MyBatis快速入门
# 1 Mybatis相关概念
MyBatis是一款优秀的基于ORM的半自动轻量级持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解来配置和映射原生类型、接口和Java的POJO。
- ORM:Object Relation Mapping:表示对象-关系映射的缩写
Mybatis是一个半自动化的持久层框架,对开发人员开说,核心sql还是需要自己进行优化,sql和java编 码进行分离,功能边界清晰,一个专注业务,一个专注数据。
# 2 Mybatis快速入门
MyBatis开发套路:
- 添加MyBatis的GAV坐标
- 创建数据库表
- 创建实体类
- 编写映射配置文件(XXXMapper.xml)
- 编写核心配置文件(SqlMapConfig.xml)
- 测试功能是否正常
接下来我们就来快速完成这一套流程,
# 2.1 导入开发包
要使用 MyBatis, 只需将 mybatis-x.x.x.jar和数据库驱动文件置于 classpath 中即可。
如果使用 Maven 来构建项目,则需将下面的 dependency 代码置于 pom.xml 文件中:
<!--mybatis坐标-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!--mysql驱动坐标-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--单元测试坐标-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--日志坐标-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 2.2 创建数据库表
-- 员工表
CREATE TABLE EMP (
EMPNO INT PRIMARY KEY, -- 员工编号
ENAME VARCHAR(10), -- 员工名称
JOB VARCHAR(9), -- 工作
MGR DOUBLE, -- 直属领导编号
HIREDATE DATE, -- 入职时间
SAL DOUBLE, -- 工资
COMM DOUBLE, -- 奖金
DEPTNO INT, -- 部门号
FOREIGN KEY (DEPTNO) REFERENCES DEPT (DEPTNO)
);
INSERT INTO EMP VALUES (7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800, NULL, 20);
INSERT INTO EMP VALUES (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600, 300, 30);
INSERT INTO EMP VALUES (7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1250, 500, 30);
INSERT INTO EMP VALUES (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975, NULL, 20);
INSERT INTO EMP VALUES (7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250, 1400, 30);
INSERT INTO EMP VALUES (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2850, NULL, 30);
INSERT INTO EMP VALUES (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2450, NULL, 10);
INSERT INTO EMP VALUES (7788, 'SCOTT', 'ANALYST', 7566, '1987-07-13', 3000, NULL, 20);
INSERT INTO EMP VALUES (7839, 'KING', 'PRESIDENT', NULL, '1981-11-17', 5000, NULL, 10);
INSERT INTO EMP VALUES (7844, 'TURNER', 'SALESMAN', 7698, '1981-09-08', 1500, 0, 30);
INSERT INTO EMP VALUES (7876, 'ADAMS', 'CLERK', 7788, '1987-07-13', 1100, NULL, 20);
INSERT INTO EMP VALUES (7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950, NULL, 30);
INSERT INTO EMP VALUES (7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000, NULL, 20);
INSERT INTO EMP VALUES (7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300, NULL, 10);
-- 部门表
CREATE TABLE DEPT (
DEPTNO INT PRIMARY KEY, -- 部门编号
DNAME VARCHAR(14), -- 部门名称
LOC VARCHAR(13) -- 部门地址
);
INSERT INTO DEPT VALUES (10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO DEPT VALUES (20, 'RESEARCH', 'DALLAS');
INSERT INTO DEPT VALUES (30, 'SALES', 'CHICAGO');
INSERT INTO DEPT VALUES (40, 'OPERATIONS', 'BOSTON');
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
# 2.3 创建实体类
public class Emp {
private Integer empno;
private String ename;
private String job;
private Integer mgr;
private Date hiredate;
private Double sal;
private Double comm;
private Integer deptno;
// getter setter
}
public class Dept {
private Integer deptno;
private String dname;
private String loc;
// getter setter
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 2.4 编写映射文件
Mapper.xml映射文件的作用主要是映射实体(User)和数据库表(user)的关系。同时定义对数据库操作的sql语句信息。
<?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:命名空间,必须保持唯一-->
<!--namespace在实际开发中是需要和接口全限定类名保持一致的,这个后面解释这样的好处-->
<mapper namespace="emp">
<!--定义查询sql语句-->
<!--id:同一个mapper.xml文件中需要唯一-->
<!--resultType:返回结果对应的实体类-->
<select id="findAll" resultType="com.hukai.demo.pojo.Emp">
select * from emp
</select>
</mapper>
2
3
4
5
6
7
8
9
10
11
12
13
# 2.5 编写核心配置文件
SqlMapConfig.xml核心配置文件主要是配置数据库相关的信息,例如数据库的url路径、数据库驱动、账号、密码等。同时还有一个非常重要的任务就是关联Mapper.xml配置文件。这样MyBatis只需要解析这个配置文件就可以解读到所有需要的信息了。
<?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">
<configuration>
<!--environments:运行环境-->
<environments default="development">
<environment id="development">
<!--当前事务交由JDBC进行管理-->
<transactionManager type="JDBC"></transactionManager>
<!--当前使用mybatis提供的连接池-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--引入映射配置文件-->
<mappers>
<mapper resource="mapper/EmpMapper.xml"></mapper>
</mappers>
</configuration>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 2.6 测试功能是否正常
最后,我们编写一个测试方法测试一下功能是否正常:
@Test
public void testFindAll() throws Exception{
// 加载配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 解析配置文件并构建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
// 构建sql会话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
// 执行查询操作
List<Emp> empList = sqlSession.selectList("emp.findAll");
// 打印结果
empList.forEach(System.out::println);
// 关闭session
sqlSession.close();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 3 Mybatis的Dao层实现
# 3.1 传统的开发方式
传统方式即开发dao接口和dao实现类。首先添加Dao接口:
public interface EmpDao {
List<Emp> findAll throws IOException();
}
2
3
4
编写实现类:
public class EmpDaoImpl implements EmpDao {
@Override
public List<Emp> findAll() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
List<Emp> empList = sqlSession.selectList("emp.findAll");
sqlSession.close();
return empList;
}
}
2
3
4
5
6
7
8
9
10
11
测试传统方式:
@Test
public void testTraditionDao() throws IOException {
EmpDao empDao = new EmpDaoImpl();
List<Emp> all = empDao.findAll();
System.out.println(all);
}
2
3
4
5
6
这种方式存在大量重复代码及硬编码,实际开发中我们一般都不用,了解传统开发只是为了让我们更好的理解mybatis。
# 3.2 代理开发方式
采用 Mybatis 的代理开发方式实现 DAO 层的开发,这种方式是我们后面进入企业的主流。 Mapper 接口开发方法只需要程序员编写Mapper 接口(相当于Dao 接口),由Mybatis 框架根据接口 定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。
Mapper 接口开发需要遵循以下规范:
- Mapper.xml文件中的namespace与mapper接口的全限定名相同;
- Mapper接口方法名和Mapper.xml中定义的每个statement的id相同;
- Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同;
- Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同;

测试代理方式:
@Test
public void testFindAll() throws Exception{
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
EmpDao empDao = sqlSession.getMapper(EmpDao.class);
List<Emp> all = empDao.findAll();
all.forEach(System.out::println);
sqlSession.close();
}
2
3
4
5
6
7
8
9
10