关于Mybatis与Spring整合之后SqlSession与mapper对象之间数量的问题。
1,sqlsession的真实类型和数量
由于使用spring管理bean,当我们在代码中需要使用这个bean的时候,会首先去容器中找,第一次需要调用MapperFactoryBean的getObject方法获取一个bean,并保存到容器中。
MapperFactoryBean的getObject方法如下:
由于每个MapperFactoryBean对象初始化的时候,都会创建一个sqlSession,代码在MapperFactoryBean类的父类SqlSessionDaoSupport中,当spring向MapperFactoryBean对象中注入SqlSessionFactory时就创建了SqlSession:
【结论1】:一个MapperFactoryBean对象拥有一个sqlSession对象。类型是org.mybatis.spring.SqlSessionTemplate
重要:spring整合mybatis使用的sqlSession类型是org.mybatis.spring.SqlSessionTemplate,
那么整合后的mybatis是怎么执行的呢?
首先查看SqlSessionTemplate类可以看到,所有的数据库执行都被一个动态代理的sqlsession对象代理了。
在构造方法中查看该代理对象的构造
使用JDK动态代理,实现InvocationHandler的类是SqlSessionIntercepteor,查看它的invoke方法如下:
可以看到,方法开始就直接创建了一个新的sqlsession对象,这个对象就是被代理的对象。
再看getSqlSession方法,它是SqlSessionUtils中的一个静态方法,如下:
第一句话和事务有关,如果它返回空,则直接使用sessionFactory创建一个新的session
【结论】spring整合mybatis后,非事务环境下,每次操作数据库都使用新的sqlSession对象。因此mybatis的一级缓存无法使用(一级缓存针对同一个sqlsession有效)
下面两段代码:
(1)不整合spring,如下代码的输出可以看出,使用了一级缓存
结果:查询过程只执行了一次。
(2)整合spring,
输出结果如下:
两次的输出表示没有使用一级缓存。
2,Mapper接口对应的bean在容器中的数量
通过getObject返回的对象是单利的,从MapperFactoryBean的isSingleton()可以得出
【结论二】因此,同一个IOC容器中同一个Mapper接口对应的代理类只有一个
例如系统有一个UserMapper接口对应UserMapper.xml
则如下代码返回true
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 【非技术】说说2024年我都干了些啥