Mayatis初学者对ThreadLocal+OppenSession的学习和认识——Util工具的编写

1

ThreadLocal,很多地方叫做线程本地变量,也有些地方叫做线程本地存储,其实意思差不多。主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用,特别适用于各个线程依赖不通的变量值完成操作的场景。
在数据结构图中我们可以看到:
Mayatis初学者对ThreadLocal+OppenSession的学习和认识——Util工具的编写
其中他的核心机制是:对于不同的线程,每次获取副本值时,别的线程并不能获取到当前线程的副本值,形成了副本的隔离,互不干扰。

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的知识点!