MyBatis工具类封装与事务管理

本文最后更新于:1 年前

Mybatis中的事务管理⽅式有两种,分别是 JDBC 和 MANAGED。

  • JDBC的事务管理机制,即使⽤JDBC事务管理机制进⾏事务管理
  • MANAGED的事务管理机制,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
29
30
31
32
33
34
public class MyBatisUtil {

private static SqlSessionFactory factory;
private static final ThreadLocal<SqlSession> local = new ThreadLocal<SqlSession>();

static{
try {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
factory = builder.build(is);
} catch (IOException e) {
e.printStackTrace();
}
}

public static SqlSessionFactory getFactory(){
return factory;
}

public static SqlSession getSqlSession(){
SqlSession sqlSession = local.get();
if(sqlSession == null ){
sqlSession = factory.openSession();
local.set(sqlSession);
}
return sqlSession;
}

public static <T extends Object> T getMapper(Class<T> c){
SqlSession sqlSession = getSqlSession();
return sqlSession.getMapper(c);
}

}
需要提交事务时,调用 getSqlSession() 方法
不需要提交事务时,调用 getMapper(...) 方法

事务管理

SqlSession 对象

  • 通过 getMapper(DAO.class) 方法获取 Mapper(DAO接口的实例)
  • 事务管理

手动提交事务

  • sqlSession.commit() 提交事务
  • sqlSession.rollback() 事务回滚
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Test
public void insertStudent() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
//1.当我们获取sqlSession对象时,就默认开启了事务
try{
//通过会话获取DAO对象
StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);
//测试StudentDAO中的方法
Student student = new Student(0, "10005", "Lily", "女", 21);
int i = studentDAO.insertStudent(student);
//2.操作完成并成功之后,需要手动提交
sqlSession.commit();
}catch (Exception e){
//3.当操作出现异常,调用rollback进行回滚
sqlSession.rollback();
}
}

业务逻辑层手动事务管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class StudentServiceImpl implements StudentService {

public boolean addStudent(Student student) {
boolean b = false;
SqlSession sqlSession = MyBatisUtil.getSqlSession();
try{
StudentDAO studentDAO = sqlSession.getMapper(StudentDAO.class);
int i = studentDAO.insertStudent(student);
b = i>0;
sqlSession.commit();
}catch (Exception e){
sqlSession.rollback();
}
return b;
}
}

通过 SqlSessionFactory 调用 openSession 方法获取 SqlSession 对象时,可以通过参数设置事务是否自动提交

  • 如果参数设置为true,表示自动提交事务factory.openSession(true);
  • 如果参数设置为 false,或者不设置参数,表示手动提交factory.openSession();factory.openSession(false);

MyBatisUtil优化

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
public class MyBatisUtil {

private static SqlSessionFactory factory;
private static final ThreadLocal<SqlSession> local = new ThreadLocal<SqlSession>();

static{
try {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
factory = builder.build(is);
} catch (IOException e) {
e.printStackTrace();
}
}

public static SqlSessionFactory getFactory(){
return factory;
}

private static SqlSession getSqlSession(boolean isAutoCommit){
SqlSession sqlSession = local.get();
if(sqlSession == null ){
sqlSession = factory.openSession(isAutoCommit);
local.set(sqlSession);
}
return sqlSession;
}

/** 手动事务管理 **/
public static SqlSession getSqlSession(){
return getSqlSession(false);
}

/** 自动事务提交 **/
public static <T extends Object>T getMapper(Class<T> c){
SqlSession sqlSession = getSqlSession(true);
return sqlSession.getMapper(c);
}

}
测试

业务逻辑层自动事务管理

1
2
3
4
5
6
7
8
9
10
public class StudentServiceImpl implements StudentService {

private StudentDAO studentDAO = MyBatisUtil.getMapper(StudentDAO.class);

public boolean addStudent(Student student) {
int i = studentDAO.insertStudent(student);
boolean b = i>0;
return b;
}
}