0%

8.2 MyBatis入门

8.2 MyBatis入门

MyBatis的用法非常简单,我们只要在Java项目中引入 MyBatis框架,就能以面向对象的方式操作关系数据库

8.2.1 MyBatis下载和安装

下载mybatis

进入mybatis在github上的仓库,点击releases,找到最近发布版本,展开Assets下拉列表,然后点击mybatis-3.5.2.zip超链接,下载连接即可

提示

由于MyBatis的底层依然是基于JDBC的,因此在应用程序中使用MyBatis执行持久化时同样少不了JDBC驱动。本示例程序底层采用了MySQL数据库,因此还需要将MySQL数据库驱动添加到应用程序的类加载路径中

下载MySQL驱动

进入这个站点即可下载mysql驱动。在写这篇文章的时候,最新的驱动版本是8.0版本的驱动。8.0版本的驱动支持MySQL5.5开始的后续MySQL版本。下载最新版本即可.

下载log4j

使用log4j来输出日志,如打印运行的SQL命令等.
进入log4j下载站点,然后选择镜像,在镜像的HTTP几个大字下,点击log4j对应的链接,即可下载.

MyBatis的数据库操作入门

项目结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
G:\Desktop\随书源码\Spring+Mybatis企业应用实战(第2版)\codes\08\MyBatisQs
├─src\
│ ├─log4j.properties
│ ├─mybatis-config.xml
│ └─org\
│ └─fkit\
│ ├─domain\
│ │ ├─crateDatabase.sql
│ │ ├─createTable.sql
│ │ ├─test.sql
│ │ ├─User.java
│ │ └─user_inf.sql
│ ├─mapper\
│ │ └─UserMapper.xml
│ └─test\
│ └─MyBatisTest.java
└─WebContent\
├─META-INF\
│ └─MANIFEST.MF
└─WEB-INF\
├─lib\
│ ├─commons-logging-1.2.jar
│ ├─log4j-1.2.17.jar
│ ├─log4j-api-2.3.jar
│ ├─log4j-core-2.3.jar
│ ├─mybatis-3.4.5.jar
│ ├─mysql-connector-java-5.1.44-bin.jar
└─web.xml

引入jar文件到lib目录

引入mybatis的jar文件

下载,解压mybatis的压缩包,然后进入该压缩包,使用如下copy命令把mybatisjar包复制到web项目的lib目录中.

1
copy *.jar E:\workspacne_JDK8Tomcat8.5\MyHrmApp\WebContent\WEB-INF\lib

复制效果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
G:\Desktop\随书源码\库文件\mybatis-3.4.5>dir
驱动器 G 中的卷是 原来的C
卷的序列号是 0C02-061D

G:\Desktop\随书源码\库文件\mybatis-3.4.5 的目录

2019/08/24 10:03 <DIR> .
2019/08/24 10:03 <DIR> ..
2019/08/24 10:03 <DIR> lib
2017/07/10 13:16 11,358 LICENSE
2017/08/20 18:57 1,623,052 mybatis-3.4.5.jar
2017/08/20 18:57 255,134 mybatis-3.4.5.pdf
2017/07/10 13:16 3,194 NOTICE
4 个文件 1,892,738 字节
3 个目录 215,845,244,928 可用字节

G:\Desktop\随书源码\库文件\mybatis-3.4.5>copy *.jar E:\workspacne_JDK8Tomcat8.5\MyHrmApp\WebContent\WEB-INF\lib
mybatis-3.4.5.jar
已复制 1 个文件。

引入mysql驱动

进入解压后的mysql驱动目录,打开cmd,输入如下命令进行复制:

1
copy *.jar E:\workspacne_JDK8Tomcat8.5\MyHrmApp\WebContent\WEB-INF\lib

复制效果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
G:\Desktop\随书源码\库文件\mysql-connector-java-8.0.17>dir
驱动器 G 中的卷是 原来的C
卷的序列号是 0C02-061D

G:\Desktop\随书源码\库文件\mysql-connector-java-8.0.17 的目录

2019/08/24 10:52 <DIR> .
2019/08/24 10:52 <DIR> ..
2019/06/07 09:49 89,517 build.xml
2019/06/07 09:49 262,785 CHANGES
2019/06/07 09:49 183 INFO_BIN
2019/06/07 09:49 135 INFO_SRC
2019/06/07 09:49 97,187 LICENSE
2019/06/07 09:49 2,321,813 mysql-connector-java-8.0.17.jar
2019/06/07 09:49 1,265 README
2019/08/24 10:52 <DIR> src
7 个文件 2,772,885 字节
3 个目录 215,819,534,336 可用字节

G:\Desktop\随书源码\库文件\mysql-connector-java-8.0.17>copy *.jar E:\workspacne_JDK8Tomcat8.5\MyHrmApp\WebContent\WEB-INF\lib
mysql-connector-java-8.0.17.jar
已复制 1 个文件。

引入log4j的jar包

解压下载好的log4j压缩包,我发现有好多jar包啊,官网上给出的消息如下:

Using Log4j on your classpath
To use Log4j 2 in your application make sure that both the API and Core jars are in the application’s classpath. Add the dependencies listed below to your classpath.

1
2
log4j-api-2.12.1.jar
log4j-core-2.12.1.jar

所以,复制log4j-api-版本号.jar,和log4j-core-版本号.jar这两个文件到web项目的lib目录下即可.

持久化对象 PO

在所有的ORM框架中都有一个非常重要的媒介:PO(持久化对象)。持久化对象的作用就是完成持久化操作,简单地说,就是通过持久化对象来对数据库执行增、删、改的操作,以面向对象的方式操作数据库
应用程序无须直接访问数据库,甚至无须理会底层数据库采用何种数据库,应用程序只需创建、修改、删除持久化对象即可;与此同时MyBatis则负责把这种操作转换为对指定数据库表的操作

创建数据库

1
2
# 创建一个数据库,指定数据库的字符为真正的utf-8编码
create database `mybatis` default character set utf8mb4;

创建数据表

1
2
3
4
5
6
7
8
9
use mybatis;
drop table if exists tb_user;
create table tb_user(
id int(11) not null auto_increment,
name varchar(18) default null,
sex char(2) default null,
age int(11) default null,
primary key (id)
);

创建成功效果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mysql> # 创建一个数据库,指定数据库的字符为真正的utf-8编码
create database `mybatis` default character set utf8mb4;
Query OK, 1 row affected
mysql> # 使用刚才创建的数据库
use mybatis;
# 如果有同名表,则删掉
drop table if exists tb_user;
# 创建表
create table tb_user(
id int(11) not null primary key auto_increment,
name varchar(18) default null,
sex char(2) default null,
age int(11) default null
);
Database changed
Database changed
Database changed

好了,有了数据表,现在来创建对应的持久化类.

持久化类

MyBatis完全采用普通的Java对象作为持久化对象使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class User
implements Serializable
{
private static final long serialVersionUID = 1L;
// 用户标识
private Integer id;
// 用户姓名
private String name;
// 用户性别
private String sex;
// 用户年龄
private Integer age;
// 无参数构造器
public User()
{
super();
}
// 有参数构造器
public User(String name, String sex, Integer age)
{
super();
this.name = name;
this.sex = sex;
this.age = age;
}
// 此处省略getter和setter方法,请自己补上
@Override
public String toString()
{
return "User [id=" + id + ", name=" + name + ", sex=" + sex + ", age=" + age + "]";
}
}

仔细看上面这个类的代码,会发现这个类与普通的JavaBean没有任何区别。实际上,MyBatis直接采用了POJO(普通的、传统的Java对象)作为持久化类,这就是MyBatis被称非低侵入式设计的原因。MyBatis不要求持久化类继承任何父类,或者实现任何接口,这样可保证代码不被污染。

映射持久化类和数据表

MyBatis是通过XML文件去完成持久化类和数据库表之间的映射关系的.

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace指用户自定义的命名空间。 -->
<mapper namespace="org.fkit.mapper.UserMapper">
<!-- id="save"是唯一的标示符 -->
<!-- parameterType属性指明插入时使用的参数类型,也就是PO类的全路径 -->
<!-- useGeneratedKeys="true"表示使用数据库的自动增长策略 -->
<insert
id="save"
parameterType="org.fkit.domain.User"
useGeneratedKeys="true"> insert into tb_user(name,sex,age) values(#{name},#{sex},#{age})
</insert>
</mapper>

namespace属性

上面的XML配置中定义了一条 insert语句,详细解释如下
<mapper namespace="org.fkit.mapper.UserMapper">:为这个 mapper指定一个唯一的 namespace, namespace的值习惯上设置成包名+SQL映射文件名,这样就能够保证namespace的值是唯一的,例如namespace="org.fkit.mapper.UserMapper"就是org.fkit.mapper(包名)+UserMapper(UserMapper.xml去除后缀后的文件名)

insert标签

1
2
3
4
5
<insert
id="save"
parameterType="org.fkit.domain.User"
useGeneratedKeys="true"> insert into tb_user(name,sex,age) values(#{name},#{sex},#{age})
</insert>

id属性

insert标签中编写了SQL插入语句,设置insert标签的id属性值为saveid属性值必须是唯一的,不能够重复

parameterType属性

使用parameterType属性指明插入时使用的参数类型,属性值设置为持久化对象的全限定名。

useGeneratedKeys属性

使用useGeneratedKeys="true"表示使用数据库的自动增长策略,这需要底层数据库的支持。

insert语句

insert标签中只有一条标准的insert语句,用来向tb_user表插入一条数据,#{name}表示取参数中的对象的name属性值。

Mybatis根配置文件

对于MyBatis来说,现在还不知道需要连接哪个数据库,以及连接数据库时所用的连接池用户名密码等详细信息。这些信息对于所有的持久化类都是通用的,MyBatis把这些通用信息称为根配置信息,根配置信息需要使用配置文件指定。
MyBatis根配置文件默认被命名为mybatis-config.xml,应用程序运行时需要先加载该文件.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- XML 配置文件包含对 MyBatis 系统的核心设置 -->
<configuration>
<!-- 指定 MyBatis 所用日志的具体实现 -->
<settings>
<setting
name="logImpl"
value="LOG4J"/>
</settings>
<environments default="mysql">
<!-- 环境配置,即连接的数据库。 -->
<environment id="mysql">
<!-- 指定事务管理类型,type="JDBC"指直接简单使用了JDBC的提交和回滚设置 -->
<transactionManager type="JDBC"/>
<!-- dataSource指数据源配置,POOLED是JDBC连接对象的数据源连接池的实现。 -->
<dataSource type="POOLED">
<property
name="driver"
value="com.mysql.jdbc.Driver"/>
<!-- 数据库的URL -->
<property
name="url"
value="jdbc:mysql://127.0.0.1:3306/mybatis"/>
<!-- 数据库的账户 -->
<property
name="username"
value="root"/>
<!-- 数据的密码 -->
<property
name="password"
value="root"/>
</dataSource>
</environment>
</environments>
<!-- mappers告诉了MyBatis去哪里找持久化类的映射文件 -->
<mappers>
<mapper resource="org/fkit/mapper/UserMapper.xml"/>
</mappers>
</configuration>

配置文件详解

MyBatis配置文件是一个XML文件,该文件第一行是XML文件声明,指定该XML文件的版本和存储该文件所用的字符集:

1
<?xml version="1.0" encoding="UTF-8" ?>

MyBatis配置文件的根元素是configuration,

  • 根元素configuration中有settings子元素,该元素有很多子元素,本示例只是配置了日志信息,之后可以在控制台看到输出的SQL语句,其在调试中非常有用。
  • 根元素configuration中还有environments子元素,用来配置MyBatis的环境,即连接的数据库,该子元素用于将SQL映射应用于多种数据库中。每个数据库对应一个SqlsessionFactory,可以配置多种环境,但只能为SqlsessionFactory实例选择一个环境,default属性表示选择的环境。
    • environments元素的environment子元素用于配置一个环境,
      • environmenttransactionManager子元素用来配置MyBatis当中的事务管理,JDBC属性表示直接简单使用JDBC的提交和回滚设置。
      • environmentdatasource子元素用来配置数据源,MyBatis并不推荐采用DriverManager来连接数据库,而是推荐使用薮据源来管理数据库连接,这样能保证最好的性能。
        • datasource元素依次有很多property子元素,这些property子元素用于配置MyBatis连接数据库的必要信息,如连接数据库的驱动、URL、用户名、密码等信息
  • 根元素configuration中还有mappers子元素,它可以支持多个mapper子元素,每个mapper子元素用于指定一个持久化配置文件

数据源介绍

数据源是一种用来提高数据库连接性能的常规手段,数据源会负责维持一个数据库连接池,当程序创建数据源实例时,系统会一次性地创建多个数据库连接,并把这些数据库连接保存在连接池中。当程序需要进行数据库访问时,无须重新获得数据库连接,而是从连接池中取出一个空闲的数据库连接,当程序使用数据库连接访问数据库结束后无须关闭数据库连接,而是将数据库连接归还给连接池即可。通过这种方式,就可避免频繁地获取数据库连接、关闭数据库连接所导致的性能下降

MyBatisTest.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class MyBatisTest {
public static void main(String[] args)
{
// 创建Session实例
SqlSession sqlSession = null;
try (
// 读取mybatis-config.xml文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");)
{
// 读取配置文件,初始化mybatis,创建SqlSessionFactory类的实例
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
sqlSession = sqlSessionFactory.openSession();
// 创建User对象
User user = new User("admin", "男", 26);
// 插入数据
sqlSession.insert("org.fkit.mapper.UserMapper.save", user);
// 提交事务
sqlSession.commit();
} catch (Exception e)
{
// 回滚事务
sqlSession.rollback();
e.printStackTrace();
} finally
{
try
{
// 关闭sqlSession
if (sqlSession != null)
sqlSession.close();
} catch (Exception e)
{
e.printStackTrace();
}
}
}
}

上面持久化操作的代码非常简单。程序先创建一个User对象,再使用SqlSessioninsert()方法来保存User对象即可,这是完全对象化的操作方式,可以说非常简单明了。当Java程序以面向对象的方式来操作持久化对象时,MyBatis负责将这种操作转换为底层SQL操作。

显示执行的SQL语句

执行持久化操作之前,为了查看控制台输出的SQL语句,需要加入日志框架log4j的相关jar包,在CLASSPATH下增加一个log4.properties文件:

1
2
3
4
5
6
7
8
# 全局的日志配置
log4j.rootLogger=ERROR, stdout
# Mybatis的日志配置
log4j.logger.org.fkit.mapper.UserMapper=DEBUG
# 控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] %m%n

运行效果

运行MyBatisTest类的main()方法,运行完成后,可以看到mybatis数据库中的TB_USER表中包含了User实例对应的记录,如下图所示:
这里有一张图片
控制台输出

1
2
3
DEBUG [main] ==>  Preparing: insert into tb_user(name,sex,age) values(?,?,?) 
DEBUG [main] ==> Parameters: admin(String), 男(String), 26(Integer)
DEBUG [main] <== Updates: 1

使用MyBatis持久化操作步骤

在执行sqlSession.insert("org.fkit.mapper.UserMapper.save", user);之前,先要获取SqlSession对象。PO只有在SqlSession的管理下才可完成数据库访问。为了使用MyBatis进行持久化操作,通常需要执行如下操作步骤

  • 1.开发持久化类PO和编写持久化操作的Mapper.xml,在其中定义要执行的SQL语句
  • 2.获取SqlSessionFactorySqlSessionFactory是数据库编译后的内存镜像,通常一个应用对应一个SqlSessionFactory对象。SqlSessionFactory对象通过加载mybatis-config.xml配置文件生成.
  • 3.获取SqlSessionSqlSessionSqlSessionFactory工厂产生,对PO的操作必须在SqlSession的管理下才能同步到数据库。
  • 4.用面向对象的方式操作数据库。
  • 5.关闭事务,关闭SqlSession

MyBatis相较JDBC的优点

MyBatis相较JDBC有如下两个显著优点

  • 只需要在Mapper.xml配置文件中编写SQL语句,在应用程序中就可以采用PO方式来访问数据库。
  • JDBC访问过程中大量的checked异常被包装成MyBatisRuntime异常,从而不再要求程序必须处理所有异常。

原文链接: 8.2 MyBatis入门