第一篇文章

MyBatis 知识整理

🗄️ 缓存机制

一级缓存(默认开启,本地缓存)

  • 作用范围sqlSession 级别,会话内部的缓存

  • 失效情况

    • sqlSession 不同(会话不同)
    • sqlSession 相同,但查询条件不同(缓存中没有该数据)
    • sqlSession 相同,两次查询之间执行了 增删改操作(因为每次增删改都会清除一级、二级缓存)
    • sqlSession 相同,但手动清除了一级缓存

二级缓存(需手动开启和配置)

  • 作用范围namespace 级别,不同会话之间可共享

  • 扩展性:MyBatis 提供了 cache 缓存接口,可实现自定义缓存

  • 机制

    • 一个会话查询的数据会先放入一级缓存
    • 当会话关闭或提交时,一级缓存的数据会写入二级缓存
    • 新的会话查询时会优先从二级缓存中获取
    • 不同 namespace 的数据存放在各自的缓存中
    • 从二级缓存取出的数据会先放到一级缓存,再在会话关闭或提交时写回二级缓存
  • 配置方法

    • 开启全局二级缓存:在 mybatis.xml 中添加
      1
      <setting name="cacheEnabled" value="true"/>
    • 在具体的 mapper.xml 中配置:
      1
      <cache></cache>
    • 实体类需实现 序列化接口
  • 常用属性(在 <cache> 标签中配置):

    • eviction:缓存回收机制
    • flushInterval:缓存刷新间隔
    • readOnly:是否只读
      • 只读:速度快,但不安全(返回的是引用,可能被修改)
      • 非只读:从缓存中复制对象,速度慢,但安全
    • size:缓存存放的元素数量
    • type:指定自定义缓存的全类名

📝 注解配置

常用注解

  • @Select@Insert@Delete@Update("sql")

    • 解耦误区:大部分数据库 SQL 相同,仅少部分有特性差异
    • 支持简单 SQL 查询
    • 不能直接加标签,但可通过 <script> 包裹
    • 注解 SQL 与 XML SQL 不能共存

结果映射相关

  • @ResultMap(""):引用已有的 resultMap

  • @Results(id="", value={@Result(), @Result(), ...}):定义新的 resultMap

  • @Result(column="", property="", one=@One(...)):替代 <result>

    • @One():替代 <association>
    • @Many():替代 <collection>

🚀 MyBatis-Plus

代码生成器

  • 可通过数据库生成结构化的 XMLJava 文件及方法

  • 适合快速开发,减少重复劳动


❓ 疑问解答

为什么只读不安全?

  • 只读缓存返回的是对象引用,如果调用方修改了该对象,缓存中的数据也会被修改,从而导致数据不一致。

  • 非只读模式会返回对象的副本,虽然性能稍慢,但能保证缓存数据的安全性和一致性。