ThreaLocal介绍
Java官方文档中的描述:ThreadLocal类用来提供线程内部的局部变量。这种变量在多线程环境下访问(通过get和set方法访问)时能保证各个线程的变量相对独立于其他线程内的变量。ThreadLocal实例通常来说都是private static类型的,用于关联线程和线程上下文。
在使用Mybatis中,需要用到事务处理,而使用Mybatis使用MVC架构模式,在service处理事务时获取的SqlSession对象需要与dao层保持一致,不一致的话会处理不了事务,在java.lang.ThreadLocal中提供了一个线程工具类,用来获取当前线程的资源,它底层是一个Map集合,key存储线程,value存储资源,我们可以利用它来存储SqlSession对象,这样在service调用ThreadLocal获取当前线程的SqlSession对象,保持与dao层SqlSession对象是一致的,这样就能够处理事务。
/**
* Mybatis工具类
*
*/
public class SqlSessionUtil {
private SqlSessionUtil() {//构造方法私有化
}
public static SqlSessionFactory sqlSessionFactory;
//全局对象,服务器级别的,一般一个服务器当中定义一个即可。
public static ThreadLocal<SqlSession> local = new ThreadLocal<>();
//类加载的时候执行
static {
try {
sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取SqlSession会话
* @return SqlSession对象
*/
public static SqlSession getSession(){
SqlSession sqlSession = local.get();
if (sqlSession == null) {
sqlSession = sqlSessionFactory.openSession();
//将SqlSession对象绑定到当前线程上
local.set(sqlSession);
}
return sqlSession;
}
/**
* 关闭SqlSession对象
* @param sqlSession
*/
public static void close(SqlSession sqlSession){
if (sqlSession != null) {
sqlSession.close();
//从当前线程移除SqlSession对象和当前线程的绑定关系
local.remove();
}
}
}