**
使用ThreadLocal来减低耦合,减少依赖
**
一.ThreadLocal是什么?
java.lang.ThreadLocal 该类提供了线程局部 (thread-local) 变量,用于在当前线程中共享数据。
二.ThreadLocaler有什么特点?
1 ThreadLocal工具类底层就是一个Map,key存放的当前线程,value存放需要共享的数据。
2 使用哪个线程存的,就只能使用哪个线程取
三.MySessionUtils类的改造
原代码
SqlSession属于Dao层代码,不允许出现在Service层中,但是在Service层中可能会用到Mybatis,这样就会造成高耦合
//Session工具类
public class MySessionUtils {
private static SqlSessionFactory sessionFactory;
//static 静态代码,在类加载的时候执行一次,且只执行一次
static{
// 》1 创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 》2 创建SqlSessionFactory对象
InputStream inputStream = MySessionUtils.class.getClassLoader().getResourceAsStream("SqlMapConfig.xml");
sessionFactory = sqlSessionFactoryBuilder.build(inputStream);//加载核心配置文件 参1 输入流
// 》3 加载SqlMapConfig.xml配置文件
}
public static SqlSession getSession() {
// 》4 创建SqlSession对象
SqlSession sqlSession = sessionFactory.openSession();
return sqlSession;
}
}
使用ThreadLocal进行改造
public class MySessionUtils2 {
private static SqlSessionFactory sessionFactory;
// 创建一个map来存放线程
public static ThreadLocal<SqlSession> map=new ThreadLocal<>();
//static 静态代码,在类加载的时候执行一次,且只执行一次
static{
// 》1 创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 》2 创建SqlSessionFactory对象
InputStream inputStream = MySessionUtils2.class.getClassLoader().getResourceAsStream("SqlMapConfig.xml");
sessionFactory = sqlSessionFactoryBuilder.build(inputStream);//加载核心配置文件 参1 输入流
// 》3 加载SqlMapConfig.xml配置文件
}
// 用ThreadLocal来降低耦合 定义一个集合来存储线程,Map<Thread,Object>
public static SqlSession getSession() {
//查找local中已经存在的session
SqlSession sqlSession=map.get();
if (sqlSession!=null){
return sqlSession;
}
//session不存在时,创建session,并保存在Local中
else {
sqlSession = sessionFactory.openSession();
map.set(sqlSession);
return sqlSession;
}
// 》4 创建SqlSession对象
}
//提交关闭session,用ThreadLocal集合
public static void commitAndCloseSession(){
SqlSession sqlSession=map.get();
if(sqlSession!=null){
sqlSession.commit();
sqlSession.close();
//已经关闭了的session不能留在local
//要删除
map.remove();
}
}
}
执行一次MySessionUtils2 方法就是一个线程,在同一个线程中,在不同的方法里都可以调用其中的存放的session