代码详解:
/**
* 框架工具代码. 实现创建会话对象的功能.
* 代码中封装一个会话工厂对象. 提供一个静态访问方法.获取会话 对象.
*
* 分析:
* 会话工厂创建的个数,次数.
* 工厂创建一个. 创建一次.
*
* java中,什么代码可以保证,一次虚拟机生命周期,运行唯一一次.
*
* @author Administrator
*
*/
public class MyBatisUtils{
private static SqlSessionFactory sqlSessionFactory;
private static Map<Thread, SqlSession> currentSessions = new HashMap<>();
/*
* 用户维护线程资源的一个控制对象.
* 可以保证,相同的线程中,只有唯一的一个资源对象,与之对应.
* 功能类似自定义的属性currentSessions
* 结构和currentSessions几乎一样.
* ThreadLocal中有属性,Map集合类型的属性.
* 集合的key是当前线程对象, 集合的value是要绑定的资源对象.
* 常用方法 :
* set(T t) -> map.put(Thread.currentThread(), t);
* get() -> map.get(Thread.currentThread());
* remove() -> map.remove(Thread.currentThread());
*/
private static ThreadLocal<SqlSession> localSessions = new ThreadLocal<>();
static{
// 创建会话工厂的代码.
try{
sqlSessionFactory = new SqlSessionFactoryBuilder().build(
Resources.getResourceAsStream("mybatis.cfg.xml")
);
}catch(Exception e){
// 静态代码块出现异常.中断JVM
// 抛出一个初始化代码异常错误.
throw new ExceptionInInitializerError(e);
}
}
/*
* 会话对象创建方法
* 功能增强. 一个线程,多次访问当前方法,只创建唯一的一个会话对象.
* 线程有对象. Thread类型的对象就是线程.
* 如何获取当前线程? Thread.currentThread();
* 使用当前线程对象作为key,SqlSession对象作为value,创建一个Map集合.管理会话对象.
*/
public static SqlSession openSession(){
// 1. 获取当前线程中对应的会话对象.
// SqlSession session = currentSessions.get(Thread.currentThread());
SqlSession session = localSessions.get();
// 2. 判断获取的会话对象是否为null
if(session == null){
// 当前线程未创建过会话对象.
session = sqlSessionFactory.openSession();
// currentSessions.put(Thread.currentThread(), session );
localSessions.set(session);
}
// 3. 返回结果
return session;
// return sqlSessionFactory.openSession();
}
/**
* 回收资源方法. 避免关闭会话对象后,在集合中仍然有会话对象的引用. 造成过时对象的应用.
*/
public static void close(){
SqlSession session = localSessions.get();
if(session != null){
session.close();
}
// 将关闭后的资源从集合中删除
localSessions.remove();
}
}
网友评论