一个宁静祥和没有bug的下午和SqlSession的故事

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个宁静祥和没有bug的下午和SqlSession的故事相关的知识,希望对你有一定的参考价值。

作者:马跃

1 背景

这是一个安静祥和没有bug的下午。
作为一只菜鸡,时刻巩固一下基础还是很有必要的,如此的大好时机,就让我来学习学习mybatis如何使用。

一个宁静祥和没有bug的下午和SqlSession的故事_spring

这可和我看到的不一样啊,让我来看看项目里怎么写的。

一个宁静祥和没有bug的下午和SqlSession的故事_sed_02

我们项目中的Dao都继承于BaseDao,而BaseDao继承于SqlSessionDaoSupport,每次执行sql的时候都是直接将这个sqlSession返回,然后执行sql,这难道不是一个实例变量嘛?这和你说的可不一样诶。于是带着这样的疑问,我开始了探索。

2 探索之旅

1)我们都知道,在使用mybatis时,sqlSession都来自于sqlSessionFactory,而sqlSessionFactory可以通过sqlSessionFactoryBuilder创建,也可以通过spring初始化,而项目中很显然采取了后一种方式。

一个宁静祥和没有bug的下午和SqlSession的故事_开源_03

2)那么我们已经得到了sqlSessionFactory,应该如何去进一步探索sqlSession的来源呢,我想到可以通过项目中已经实现的dao进行探索。我们随便选取一个dao为例。

一个宁静祥和没有bug的下午和SqlSession的故事_sql_04

它继承了BaseDao。

一个宁静祥和没有bug的下午和SqlSession的故事_mybatis_05

而BaseDao又继承了SqlSessionDaoSupport,在BaseDao中调用了getSqlSession方法,实际上也就是SqlSessionDaoSupport的getSqlSession方法。

一个宁静祥和没有bug的下午和SqlSession的故事_sed_06

而SqlSessionDaoSupport的getSqlSession方法是直接将自己的成员变量返回去的,截至目前为止,和我的怀疑点是相符合的,即目前的写法和mybatis官网的说明是冲突的。

3)反复阅读SqlSessionDaoSupport这个类后,终于被我发现了线索,细心的小伙伴应该也早已发现了,就在上图之中的注释中,“用户应该使用这个方法来获得一个SqlSession来执行sql语句,这个SqlSession被spring管理,用户不应该提交、回滚或关闭它。因为这些已经被自动执行了。”

同时,这个方法会返回一个线程安全的SqlSession。

一个宁静祥和没有bug的下午和SqlSession的故事_开源_07

那么这个SqlSession是从何而来的呢,从上图可以看出,它有两种赋值方式,一种是给他传一个SqlSessionFactory,生成SqlSessionTemplate,SqlSessionTemplate即为sqlSession。另一种是直接给他传一个SqlSessionTemplate作为SqlSession。根据本类的注释,如果SqlSessionFactory和SqlSessionTemplate都被定义了,那么SqlSessionFactory的方式会失效。至此,我的上述疑问已经解决了,也就是说这个SqlSession并不是一个mybatis初始的SqlSession,而是spring实现的SqlSessionTemplate。

4)但是,我又诞生了新的疑问,SqlSessionTemplate是怎么完成线程安全的呢?

一个宁静祥和没有bug的下午和SqlSession的故事_mybatis_08

于是我进入了SqlSessionTemplate的方法执行,发现实际执行语句的都是这个代理类sqlSessionProxy。

一个宁静祥和没有bug的下午和SqlSession的故事_mybatis_09

而代理工作内容就在SqlSessionInterceptor这个handler里。

一个宁静祥和没有bug的下午和SqlSession的故事_spring_10

进入其中,我们终于发现了它的获取和关闭操作。

一个宁静祥和没有bug的下午和SqlSession的故事_spring_11

一个宁静祥和没有bug的下午和SqlSession的故事_sql_12

也就是说,每次执行,代理都会调用sessionFactory的openSession方法获得一个新的session。

3 总结

终于的终于,mybatis,spring,项目以及我的疑问得到了统一,真是一个宁静祥和而又没有bug的下午呀。


以上是关于一个宁静祥和没有bug的下午和SqlSession的故事的主要内容,如果未能解决你的问题,请参考以下文章

canal-随记001-吐血一个下午找bug

查bug受气了,反思

The Finalless——新学期的scrum

nginx.conf 用于一个宁静的 api

项目上线前一天出了惊天大bug

发现京东客服的一个死循环bug