作者:马跃
1 背景
这是一个宁静祥和没有bug的下午。
作为一只菜鸡,时刻坚固一下根底还是很有必要的,如此的大好时机,就让我来学习学习mybatis如何应用。
这可和我看到的不一样啊,让我来看看我的项目里怎么写的。
咱们我的项目中的Dao都继承于BaseDao,而BaseDao继承于SqlSessionDaoSupport,每次执行sql的时候都是间接将这个sqlSession返回,而后执行sql,这难道不是一个实例变量嘛?这和你说的可不一样诶。于是带着这样的疑难,我开始了摸索。
2 探索之旅
1)咱们都晓得,在应用mybatis时,sqlSession都来自于sqlSessionFactory,而sqlSessionFactory能够通过sqlSessionFactoryBuilder创立,也能够通过spring初始化,而我的项目中很显然采取了后一种形式。
2)那么咱们曾经失去了sqlSessionFactory,应该如何去进一步摸索sqlSession的起源呢,我想到能够通过我的项目中曾经实现的dao进行摸索。咱们轻易选取一个dao为例。
它继承了BaseDao。
而BaseDao又继承了SqlSessionDaoSupport,在BaseDao中调用了getSqlSession办法,实际上也就是SqlSessionDaoSupport的getSqlSession办法。
而SqlSessionDaoSupport的getSqlSession办法是间接将本人的成员变量返回去的,截至目前为止,和我的狐疑点是相符合的,即目前的写法和mybatis官网的阐明是抵触的。
3)重复浏览SqlSessionDaoSupport这个类后,终于被我发现了线索,仔细的小伙伴应该也早已发现了,就在上图之中的正文中,“用户应该应用这个办法来取得一个SqlSession来执行sql语句,这个SqlSession被spring治理,用户不应该提交、回滚或敞开它。因为这些曾经被主动执行了。”
同时,这个办法会返回一个线程平安的SqlSession。
那么这个SqlSession是从何而来的呢,从上图能够看出,它有两种赋值形式,一种是给他传一个SqlSessionFactory,生成SqlSessionTemplate,SqlSessionTemplate即为sqlSession。另一种是间接给他传一个SqlSessionTemplate作为SqlSession。依据本类的正文,如果SqlSessionFactory和SqlSessionTemplate都被定义了,那么SqlSessionFactory的形式会生效。至此,我的上述疑难曾经解决了,也就是说这个SqlSession并不是一个mybatis初始的SqlSession,而是spring实现的SqlSessionTemplate。
4)然而,我又诞生了新的疑难,SqlSessionTemplate是怎么实现线程平安的呢?
于是我进入了SqlSessionTemplate的办法执行,发现理论执行语句的都是这个代理类sqlSessionProxy。
而代理工作内容就在SqlSessionInterceptor这个handler里。
进入其中,咱们终于发现了它的获取和敞开操作。
也就是说,每次执行,代理都会调用sessionFactory的openSession办法取得一个新的session。
3 总结
终于的终于,mybatis,spring,我的项目以及我的疑难失去了对立,真是一个平静祥和而又没有bug的下午呀。