Mayatis初学者对ThreadLocal+OppenSession的学习和认识——Util工具的编写
1
ThreadLocal,很多地方叫做线程本地变量,也有些地方叫做线程本地存储,其实意思差不多。主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用,特别适用于各个线程依赖不通的变量值完成操作的场景。
在数据结构图中我们可以看到:
其中他的核心机制是:对于不同的线程,每次获取副本值时,别的线程并不能获取到当前线程的副本值,形成了副本的隔离,互不干扰。
2
那么。在Mybatis中如如何应用他的呢。我们继续往下走。
在mybatis中回大量的使用到factory创建sqlsession,在创建session的过程中回耗费很大的性能。所以必须要正确的编写一个Util工具类。那么问题来了,在创建工具类的时候怎样才能确保每个方法都使用的一个session。这个时候就该发挥TheardLocal的作用了。
public class MybatisUtil {
private static SqlSessionFactory factory;
private static ThreadLocal<SqlSession> tl = new ThreadLocal<>();
static {
try {
InputStream is = Resources.getResourceAsStream("mybatis.xml");
factory = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*获取sqlsession的方法*/
public static SqlSession getSession() {
SqlSession session = tl.get();
if(session==null) {
tl.set(factory.openSession());
}
return tl.get();
}
public static void closeSession() {
SqlSession session = tl.get();
if(session!=null) {
session.close();
}
tl.set(null);
}
}
实例化工具类的时候每次都会用到TheardLocal用于存储每一个线程的变量的副本【tl.set(factory.openSession());】。是的正确的区分session对象!tl.set(factory.openSession());
3
然后在web学习的过程中使用过滤器来调用Util类来创建session。
SqlSession session = MybatisUtil.getSession();
try {
filterchain.doFilter(servletrequest, servletresponse);
session.commit();
} catch (Exception e) {
// TODO: handle exception
session.rollback();
finally {
MybatisUtil.closeSession();
}
最后在servlet中调用!
在这个使用场景中最重要的就是private static ThreadLocal<SqlSession> tl = new ThreadLocal<>();
的使用,大家可以去找找其他关于ThreadLoca的知识点!