MyBatis 中的缓存机制

文章目录

    • 一级缓存
    • 二级缓存

MyBatis 中的缓存是用于提高数据访问性能的一个重要机制。它可以将查询结果缓存在内存中,避免重复查询数据库,从而加快数据访问速度。MyBatis 中存在一级缓存和二级缓存,一级缓存和二级缓存是相互独立的,它们并不共享缓存数据。一级缓存默认开启;而二级缓存默认关闭,如果需要开启二级缓存,则需要手动配置进行开启。

在使用 MyBatis 中的缓存时,需要关注缓存的有效性和管理。由于缓存会使得数据的实时性降低,可能会造成数据不一致。因此在更新、插入或删除相关数据时,需要及时清空缓存或使缓存失效,以保持数据的一致性。另外,一级缓存与二级缓存都基于本地缓存,所以在分布式的系统中,需要关注不同节点间的缓存同步与缓存一致性问题,以避免数据不一致的情况发生。

一级缓存

一级缓存是针对同一个 SqlSession 对象的缓存,一级缓存的生命周期与 SqlSession 对象绑定(即在 SqlSession 关闭之前一直有效),当同一个 SqlSession 对象执行相同的 SQL 语句时,会先从一级缓存中查找,如果找到了缓存的结果,则直接返回缓存结果,无需再次查询数据库。一级缓存是线程私有的,不会和其他 SqlSession 对象共享缓存。

一级缓存在某些情况下会失效,常见的一级缓存失效的情况包括:

  1. 使用不同 SqlSession:一级缓存只在同一个 SqlSession 内有效,当使用不同的 SqlSession 对象执行查询时,缓存不会跨会话共享,因此缓存会失效。
  2. 执行了 DML 操作:在 SqlSession 执行更新操作(insert、update、delete)时,会触发缓存的刷新,此时一级缓存会被清空。
  3. 查询参数不同:在同一个 SqlSession 中使用不同的查询参数执行相同的查询语句会导致一级缓存会失效,因为 MyBatis 会将参数作为缓存的 key,不同参数会对应不同缓存结果。
  4. 手动关闭或提交 SqlSession:在 SqlSession 关闭或提交后,一级缓存会被清空。
  5. 手动清除缓存:通过 SqlSession 的 clearCache() 方法的调用主动清除一级缓存。

二级缓存

二级缓存是基于 SqlSessionFactory 级别的缓存,二级缓存的生命周期与 SqlSessionFactory 对象绑定(即在应用程序重启之前一直有效),多个 SqlSession 对象之间可以共享二级缓存。当执行相同的 SQL 语句时,会先从二级缓存中查找,如果找到了缓存的结果,则直接返回缓存结果,无需再次查询数据库。

配置开启二级缓存后,MyBatis 将会启用二级缓存,并根据设置进行缓存管理。通过二级缓存,同一个 namespace 下的不同 SqlSession 间也可以共享相同的二级缓存,从而提高数据访问的性能。

当需要在 MyBatis 中开启二级缓存时,可以按照以下步骤进行配置:

  1. 全局配置文件中开启二级缓存:在 MyBatis 的全局配置文件(通常是 mybatis-config.xml)中设置 标签中的 cacheEnabled 属性值为 true,该配置是开启二级缓存的总开关。因为该属性的默认值为 true,所以在默认情况下不需要专门设置这个属性。

    <configuration>
        <settings>
            <setting name="cacheEnabled" value="true"/>
        settings>
    configuration>
    
  2. 在映射文件中开启二级缓存:在对应的映射文件(.xml)里,要为需要使用二级缓存的 Mapper 开启二级缓存。可以使用 标签来开启,该标签一般位于 标签内。例如:

    <mapper namespace="com.example.UserMapper">
        <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
        
    mapper>
    
  3. 查询的数据所转换的类必须实现序列化接口。

完成以上步骤,二级缓存在 SqlSession 关闭或提交后将生效。

标签还有一些可选属性,用于更精细地配置二级缓存。以下是 标签的属性说明:

属性 说明
eviction 指定缓存的回收策略,默认是 LRU(最近最少使用),还有 FIFO(先进先出)、SOFT(软引用)、WEAK(弱引用)等策略。
flushInterval 表示刷新缓存的时间间隔,单位是毫秒。
size 指定缓存可以存储的最大元素数量。
readOnly 指定缓存是否为只读,默认是 false

你可能感兴趣的:(Mybatis,mybatis)