一步步学习 MyBatis:缓存的使用及源码分析

作者/分享人:凯伦
向 Ta 提问
美团点评后端Java工程师,技术爱好者,个人公众号:凯伦说(KailunTalk)。个人博客:kailuncen.me

MyBatis 是基于 Java 的一款 ORM 框架,在互联网公司的后端开发中占了非常大的比例,也是大众点评数据访问层框架的底层框架。

我基于个人兴趣对 MyBatis 进行了一番学习,这场 Chat 的主题主要是集中在 MyBatis 的一级缓存和二级缓存具体的使用以及源码的分析,之后产出的文章中会提供作为 demo 的数据库表和示例代码。我会尽可能帮助大家了解 MyBatis 在缓存这一块的工作原理,谢谢。

实录提要:

  • MyBatis 针对 MySQL 和 Oracle 分页的解决方案有什么?
  • MyBatis 查询如 30 万、100 万的数据,如何优化?
  • MySQL 过千万数据删除需要注意什么问题?
  • MyBatis 主要缺点是什么?何时应该选用 Hibernate 而非MyBatis?
  • MySQL 使用中间件做读写分离和程序代码层面做读写分离,哪个更好?
  • 如何着手分析 MyBatis 源码?
  • 请问有哪些常用的对性能有改善的配置建议?
已有265人预订
预订达标
文章出炉
交流日期
     
06月23日
07月03日
07月10日 20:30
查看文章评论/提问
凯伦
建议使用网页浏览本次chat的文章
倾城志
多表查询的时候,会出现一个映射文件一堆association 或者collection 或者 left/inner join ,这在后期维护时很麻烦。请问老师,如何去解决这种问题呢?如何高效的利用resultMap呢?谢谢
凯伦: 已微信交流哈~
寒韩
关于一级缓存想请教下您:每一次mapper里查询调用都会创建一个SqlSession,所以对应的如文中示例StudentMapper永远不会有一级缓存命中啊?是否只有在手动通过sqlSession多次查询同一SQL才会命中?
凯伦: 只要是一个sqlsession中拿到的mapper,都会共享一个一级缓存哦,至于是否命中取决于查询语句是否相同,有无清空缓存的操作
凯伦: 前几个实验都有同一个mapper多次查询,验证缓存效果哦
寒韩: 嗯。跟随文章我debug跟踪了下源码,在如文中示例sqlSessionFactory.openSession(true);来进行测试时,因这时创建的是DefalutSqlSession实例,获取的mapper时创建mapper代理时传递的也就是DefalutSqlSession,这个时候多次查询loclcache都是同一个实例。但是我在项目中mapper的的获取是依赖Spring来创建的(项目使用Spring-boot),也就是在业务层我是通过Autowire来获取mapper实例的,这个时候mapper代理的创建Sqlseesion传递的是SqlSessionTemplate实例,我发现我mapper方法调用每次都会创建新的DefalutSqlSession,也就是每次localcache实例都是新的,也就出现了无论如何都不可能命中一级缓存。我很疑惑为什么这么设计,每一次调用都创建新sqlsession实例 ?是不是哪里需要设置什么... 我的测试用例: @Autowired UserMapper userMapper; @Test public void testFindById() { this.userMapper.findUserById(1L); this.userMapper.findUserById(1L); }
凯伦: 这个是和使用的spring有关系的,在线交流回复下
凯伦: 你可以看下SqlSessionTemplate中的SqlSessionInterceptor,这是具体执行的时候SqlSession的代理类,invoke方法里有一个getSqlSession方法,会去判断是否和事务绑定,如果绑定的话,取的是同一个SqlSession,如果没有事务的话,就每次会新建一个,在你的场景中,没有用事务,因此,每次都新建了一个SqlSession,因此才会出现你所说的情况。回答完毕,欢迎进入我的读者圈或者公众号,一起多多交流。
寒韩: 嗯。谢谢!
阿杜
“在分布式环境下,由于默认的Mybatis Cache实现都是基于本地的,分布式环境下必然会出现读取到脏数据,需要使用集中式缓存将Mybatis的Cache接口实现,有一定的开发成本,不如直接用Redis,Memcache实现业务上的缓存就好了”看到这句话,也就理解了为啥大家在日常开发中不常用mybatis的缓存了😂
阿杜: 不过在阅读源码的过程中,顺便将mybatis的原理和黑盒子给拆开了,有收获有收获
凯伦: 对您有收获就好~
橙子
分析的很透彻
凯伦: 谢谢,希望对您有帮助
hong
mybatis中#和$符号的主要区别在哪,除了说 #{} 使用了jdbc的preparedStatement进行预编译, 防止sql 注入,还有其他的吗?
凯伦: 这个回答比较长一些,在线交流解答哦
你将相思赋予谁
mybatis 查询 例如 30万 100万的 数据 如何优化
凯伦: 已chat交流
冰锋
现在我们是使用spring mybatis的搭配下使用,使用过程中对mybatis的某个查询在一个方法中进行了多次调用,由于方法查询出来后就会解密,然后mybatis缓存了解密后的数据,导致程序出现了解密报错的信息,mybatis是怎么样进行隔离查询是不是要去读取缓存的?在我看来两次查询应该不算是同一个sqlsession吧?
凯伦: 已chat交流
你可能还喜欢
Service Mesh 在华为公有云的实践
田晓亮
从零开始,搭建 AI 音箱 Alexa 语音服务
Mike
Web 安全恩仇录:再谈逻辑漏洞
肖志华
如何用 Vue 实现前端权限控制(路由权限 + 视图权限 + 请求权限)
雅X共赏
智能增长:如何用大数据和人工智能实现业务体量的增长
蒋凡
有关 Mock 的是是非非
思考的犀牛
微信扫描登录