您好!
欢迎来到京东云开发者社区
登录
首页
博文
课程
大赛
工具
用户中心
开源
首页
博文
课程
大赛
工具
开源
更多
用户中心
开发者社区
>
博文
>
一个宁静祥和没有bug的下午和SqlSession的故事
分享
打开微信扫码分享
点击前往QQ分享
点击前往微博分享
点击复制链接
一个宁静祥和没有bug的下午和SqlSession的故事
自猿其说Tech
2022-04-07
IP归属:未知
593320浏览
计算机编程
### 1 背景 这是一个安静祥和没有bug的下午。 作为一只菜鸡,时刻巩固一下基础还是很有必要的,如此的大好时机,就让我来学习学习mybatis如何使用。 ![](//img1.jcloudcs.com/developer.jdcloud.com/8870f2b1-f523-4f77-9729-f6c4620bfc0020220407135153.png) 这可和我看到的不一样啊,让我来看看项目里怎么写的。 ![](//img1.jcloudcs.com/developer.jdcloud.com/1999d5da-a31a-4e06-baf9-7d20f9a5ab5820220407135204.png) 我们项目中的Dao都继承于BaseDao,而BaseDao继承于SqlSessionDaoSupport,每次执行sql的时候都是直接将这个sqlSession返回,然后执行sql,这难道不是一个实例变量嘛?这和你说的可不一样诶。于是带着这样的疑问,我开始了探索。 ### 2 探索之旅 1)我们都知道,在使用mybatis时,sqlSession都来自于sqlSessionFactory,而sqlSessionFactory可以通过sqlSessionFactoryBuilder创建,也可以通过spring初始化,而项目中很显然采取了后一种方式。 ![](//img1.jcloudcs.com/developer.jdcloud.com/4c3b639a-9212-44b4-9bce-e7565920f73a20220407135314.png) 2)那么我们已经得到了sqlSessionFactory,应该如何去进一步探索sqlSession的来源呢,我想到可以通过项目中已经实现的dao进行探索。我们随便选取一个dao为例。 ![](//img1.jcloudcs.com/developer.jdcloud.com/0fed4ff0-adfa-4347-9f20-380a6f83966c20220407135330.png) 它继承了BaseDao。 ![](//img1.jcloudcs.com/developer.jdcloud.com/82cc7511-1613-42d7-aeef-e0ecb82ca93920220407135344.png) 而BaseDao又继承了SqlSessionDaoSupport,在BaseDao中调用了getSqlSession方法,实际上也就是SqlSessionDaoSupport的getSqlSession方法。 ![](//img1.jcloudcs.com/developer.jdcloud.com/2b61bb78-e795-461c-8717-aab73817b0f520220407135357.png) 而SqlSessionDaoSupport的getSqlSession方法是直接将自己的成员变量返回去的,截至目前为止,和我的怀疑点是相符合的,即目前的写法和mybatis官网的说明是冲突的。 3)反复阅读SqlSessionDaoSupport这个类后,终于被我发现了线索,细心的小伙伴应该也早已发现了,就在上图之中的注释中,“用户应该使用这个方法来获得一个SqlSession来执行sql语句,这个SqlSession被spring管理,用户不应该提交、回滚或关闭它。因为这些已经被自动执行了。” 同时,这个方法会返回一个线程安全的SqlSession。 ![](//img1.jcloudcs.com/developer.jdcloud.com/6b698b48-a469-447a-8a8f-b3f5f772234620220407135426.png) 那么这个SqlSession是从何而来的呢,从上图可以看出,它有两种赋值方式,一种是给他传一个SqlSessionFactory,生成SqlSessionTemplate,SqlSessionTemplate即为sqlSession。另一种是直接给他传一个SqlSessionTemplate作为SqlSession。根据本类的注释,如果SqlSessionFactory和SqlSessionTemplate都被定义了,那么SqlSessionFactory的方式会失效。至此,我的上述疑问已经解决了,也就是说这个SqlSession并不是一个mybatis初始的SqlSession,而是spring实现的SqlSessionTemplate。 4)但是,我又诞生了新的疑问,SqlSessionTemplate是怎么完成线程安全的呢? ![](//img1.jcloudcs.com/developer.jdcloud.com/59aef18c-da90-4ce6-a879-c495265d755920220407135446.png) 于是我进入了SqlSessionTemplate的方法执行,发现实际执行语句的都是这个代理类sqlSessionProxy。 ![](//img1.jcloudcs.com/developer.jdcloud.com/297b5522-2f52-4f39-a2ea-5911246dedb520220407135502.png) 而代理工作内容就在SqlSessionInterceptor这个handler里。 ![](//img1.jcloudcs.com/developer.jdcloud.com/43323d1a-94c7-40a2-a4e7-8471e46421d520220407135515.png) 进入其中,我们终于发现了它的获取和关闭操作。 ![](//img1.jcloudcs.com/developer.jdcloud.com/9ad99785-bb7a-43e3-8525-e17446a03d6120220407135529.png) ![](//img1.jcloudcs.com/developer.jdcloud.com/db6aee0a-3d28-4c76-9185-51c32427e07d20220407135543.png) 也就是说,每次执行,代理都会调用sessionFactory的openSession方法获得一个新的session。 ### 3 总结 终于的终于,mybatis,spring,项目以及我的疑问得到了统一,真是一个宁静祥和而又没有bug的下午呀。 ------------ ###### 自猿其说Tech-JDL京东物流技术与数据智能部 ###### 作者:马跃
原创文章,需联系作者,授权转载
上一篇:repromise系统资源收敛与核心服务优化实践
下一篇:web自动化工具selenium介绍与使用
相关文章
Taro小程序跨端开发入门实战
Flutter For Web实践
配运基础数据缓存瘦身实践
自猿其说Tech
文章数
426
阅读量
2149964
作者其他文章
01
深入JDK中的Optional
本文将从Optional所解决的问题开始,逐层解剖,由浅入深,文中会出现Optioanl方法之间的对比,实践,误用情况分析,优缺点等。与大家一起,对这项Java8中的新特性,进行理解和深入。
01
Taro小程序跨端开发入门实战
为了让小程序开发更简单,更高效,我们采用 Taro 作为首选框架,我们将使用 Taro 的实践经验整理了出来,主要内容围绕着什么是 Taro,为什么用 Taro,以及 Taro 如何使用(正确使用的姿势),还有 Taro 背后的一些设计思想来进行展开,让大家能够对 Taro 有个完整的认识。
01
Flutter For Web实践
Flutter For Web 已经发布一年多时间,它的发布意味着我们可以真正地使用一套代码、一套资源部署整个大前端系统(包括:iOS、Android、Web)。渠道研发组经过一段时间的探索,使用Flutter For Web技术开发了移动端可视化编程平台—Flutter乐高,在这里希望和大家分享下使用Flutter For Web实践过程和踩坑实践
01
配运基础数据缓存瘦身实践
在基础数据的常规能力当中,数据的存取是最基础也是最重要的能力,为了整体提高数据的读取能力,缓存技术在基础数据的场景中得到了广泛的使用,下面会重点展示一下配运组近期针对数据缓存做的瘦身实践。
自猿其说Tech
文章数
426
阅读量
2149964
作者其他文章
01
深入JDK中的Optional
01
Taro小程序跨端开发入门实战
01
Flutter For Web实践
01
配运基础数据缓存瘦身实践
添加企业微信
获取1V1专业服务
扫码关注
京东云开发者公众号