使用MyBatis框架在持久层操作中,如果多个DML操作都属于一个事务,因为commit()和rollback()都是SqlSession完成的,所以必须保证只使用一个SqlSession,但是不同的DML操作可能在不同类的不同方法中,每个方法都需要获取SqlSession,所以应该如何在多个DML操作中保证使用同一个SqlSession呢?
下面给大家带来了一个工具类:ThreadLocal,它可以储存SqlSession对象,并且保证一个线程只使用一个SqlSession。现在来学习一下如何创建MyBatis这个工具类
首先需要new一个ThreadLocal对象,以便存储SqlSession:
private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<>();
再在一个静态代码块中初始化SqlSessionFactory:
static { //创建SqlSessionFactory InputStream is = null; try { is = Resources.getResourceAsStream("mybatis-cfg.xml"); } catch (IOException e) { e.printStackTrace(); } sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); }
接下来就是从ThreadLocal中获取sqlSession对象并且使用ThreadLocal存储:
要注意:存储SqlSession的时候要判断该对象是否为空,要是为空就要获取一个,然后再存到ThreadLocal,返回一个SqlSession。
//获取SqlSession public static SqlSession getSqlSession(){ SqlSession sqlSession = threadLocal.get(); if(sqlSession == null){ sqlSession = sqlSessionFactory.openSession(); threadLocal.set(sqlSession); } return sqlSession; }
接下来也可以在该工具类关闭sqlSession
//关闭sqlSession public static void closeSqlSession(){ SqlSession sqlSession = threadLocal.get(); if (sqlSession != null){ sqlSession.close(); threadLocal.set(null); } }
总代码:
public class MyBatisUtils { private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<>(); private static SqlSessionFactory sqlSessionFactory = null; static { //创建SqlSessionFactory InputStream is = null; try { is = Resources.getResourceAsStream("mybatis-cfg.xml"); } catch (IOException e) { e.printStackTrace(); } sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); } //获取SqlSession public static SqlSession getSqlSession(){ SqlSession sqlSession = threadLocal.get(); if(sqlSession == null){ sqlSession = sqlSessionFactory.openSession(); threadLocal.set(sqlSession); } return sqlSession; } //关闭sqlSession public static void closeSqlSession(){ SqlSession sqlSession = threadLocal.get(); if (sqlSession != null){ sqlSession.close(); threadLocal.set(null); } } }