## 原始的 MyBatis 开发步骤
1. 建表
2. 创建与表结构对应的实体类
3. 在 MyBatis 配置文件中创建实体类的别名,方便在映射文件中使用
4. 创建 DAO 层接口
5. 编写映射文件实现接口
6. 在 MyBatis 配置文件中注册映射文件
7. 调用接口方法
```java
@Test
public void test() {
// 获取 SqlSession
InputStream is = MyBatisTest.class.getClassLoader().getResourceAsStream("mybatis.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
SqlSession session = factory.openSession();
// 获取接口的实现类对象,这个对象是 MyBatis 通过动态代理生成的实现类的对象
UserDao mapper = session.getMapper(UserMapper.class);
// 通过实现类对象调用接口的方法
try {
List users = mapper.findAll();
for(User user : users) {
System.out.println(user);
}
} finally {
session.close();
}
}
```
可以看到,使用 MyBatis 原始的开发步骤会存在配置繁琐和代码冗余的问题,例如,需要配置大量的实体类别名,以及大量的 Mapper 文件注册,在执行接口中的方法之前需要先获取 `SqlSessionFactoryBuilder`、`SqlSessionFactory`、`SqlSession` 等对象,最后需要手动关闭 `SqlSession`
## Spring 整合 MyBatis
### 总体思路
1. 将 MyBatis 配置文件转移到 Sping 配置文件中,主要是解决连接池、实体类别名、注册 Mapper 文件的配置
2. 封装获取 `SqlSessionFactory` 的系列代码
### 环境搭建
引入一下依赖,注意 Spring 整合 MyBatis 的相关 jar 包是由 MyBatis 给出的
```xml
org.springframework
spring-jdbc
5.2.6.RELEASE
org.mybatis
mybatis-spring
2.0.4
com.alibaba
druid
1.1.12
mysql
mysql-connector-java
5.1.43
org.mybatis
mybatis
3.5.4
```
### 编码实现
#### 转移配置文件
在配置文件中主要配置一下内容:
1. 数据源信息,使用的连接池
2. 将 `SqlSessionFactory` 对象纳入 IOC 容器管理
3. 实体类所在的包、Mapper 文件的路径、DAO 接口的路径
```xml
```
#### 使用
Spring 帮我们接管了 MyBatis 的很多操作,需要我们自己编码实现的内容有
1. 数据库表
2. 实体类
```java
public class User implements Serializable {
private Integer id;
private String name;
private String password;
// getter setter
}
```
3. DAO 接口
```java
public interface UserDAO {
public void insert(User user);
}
```
4. 映射文件
```xml
insert into user (name,passwprd) values(#{name}, #{password})
```
5. 在 Service 层调用 DAO 接口,这里以单元测试代替
```java
@Test
public void test() {
// 获取工厂
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
// 获取DAO接口的代理实现类对象
UserDAO userDAO = (UserDAO) ctx.getBean("userDAO");
User user = new User();
user.setName("xiaojr");
user.setPassword("999999");
// 执行insert操作
userDAO.insert(user);
}
```
## 细节问题
### Spring 与 Myabatis 整合后,为什么 DAO 不提交事务,但是数据能够插入数据库中?
* 可以这样说,谁控制了 `Connection` 谁就控制了事务
* 在此之前,使用 MyBatis 提供的连接池获取 `Connection`,底层 `Connection.setAutoCommit(false)`,需要手动提交
* 我们选择外部的 Druid(C3P0、DBCP)作为连接池,所有的连接都是从连接池获得,也就是说连接池控制着 `Connection` 和事务,底层 `Connection.setAutoCommit(true)`,一条 SQL 完成自动提交,不需要手动提交事务
* 在实战中,对于多条增删改语句的执行,我们依然会手动控制事务的提交和回滚,而 Spring 为我们提供了事务控制的解决方案
## 参考
[孙哥说Spring5](https://www.bilibili.com/video/BV185411477k)

Spring | 整合 MyBatis