Mybatis 缓存机制

为什么使用缓存?

缓存的作用是为了减去数据库的压力,提高数据库的性能。缓存实现的原理是从数据库中查询出来的对象在使用完后不销毁,而是存储在内存(缓存)中,当再次需要获取该对象时,直接从内存中获取,不再向数据库执行select语句,减少对数据库的查询次数,提高了数据库的性能。缓存是使用Map集合存储数据。缓存是使用Map集合存储数据。

MyBtais内部缓存使用HashMap,key为hashCode+sqlid+sql语句,value为从查询出来映射生成的java对象。

一级缓存
  • 一级缓存是与 SqlSession 相关联的本地缓存,它的作用范围限定在当前 SqlSession 内部。

  • 同一个id,可以走缓存;不同id,即使查询的内容相同

查询顺序

  • 每当执行相同的查询语句时,MyBatis 会先从当前 SqlSession 的一级缓存中查找是否有对应的缓存数据。

  • 如果一级缓存中有命中,则直接返回缓存数据,不会再发送查询请求到数据库。

生命周期

  • 一级缓存的生命周期与 SqlSession 的生命周期一致,即在同一个 SqlSession 中,多次查询相同的数据时,只有第一次会从数据库中查询,后续查询会直接从一级缓存中获取数据。

  • 当 SqlSession 关闭或者提交事务时,一级缓存会被清空,所有缓存数据都会失效。

 // MyBatis 的配置文件(例如:mybatis-config.xml)中不配置二级缓存
 ​
 // Mapper 接口
 public interface UserMapper {
     User selectUserById(int id);
 }
 ​
 // Mapper XML 文件
 <mapper namespace="com.example.mapper.UserMapper">
     <select id="selectUserById" parameterType="int" resultType="User">
         select * from users where id = #{id}
     </select>
 </mapper>
 ​
 // 使用 Mapper 接口的代码示例
 public class MyBatisExample {
     public static void main(String[] args) {
         SqlSession sqlSession = null;
         try {
             sqlSession = MyBatisUtil.getSqlSessionFactory().openSession();
             UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
 ​
             // 第一次查询,命中一级缓存
             User user1 = userMapper.selectUserById(1);
             System.out.println(user1);
 ​
             // 第二次查询,命中一级缓存,不会发送到数据库
             User user2 = userMapper.selectUserById(1);
             System.out.println(user2);
 ​
             sqlSession.commit(); // 提交事务
         } finally {
             if (sqlSession != null) {
                 sqlSession.close();
             }
         }
     }
 }
 ​
二级缓存

二级缓存是跨 SqlSession 的缓存机制,它存储在整个应用程序的内存中,由 SqlSessionFactory 管理。

查询顺序

  • 如果在当前 SqlSession 的一级缓存中未命中,MyBatis 会继续检查是否开启了二级缓存。

  • 如果开启了二级缓存,并且查询的数据在二级缓存中存在,则会从二级缓存中获取数据。

  • 如果二级缓存中也未命中,则 MyBatis 会发送查询请求到数据库,获取数据并同时更新一级缓存和二级缓存。

生命周期

  • 二级缓存的生命周期与整个应用程序的生命周期一致,即在应用程序关闭时才会清空。

  • 当某个 SqlSession 对象对数据进行了更新(增、删、改)操作时,MyBatis 会自动刷新或者清空相关的二级缓存,保证数据的一致性和可靠性。

如何开启二级缓存
  • 配置文件

  • POJO序列化,将所有的POJO类(bean)实现序列化接口java.io.Serializable。

 <!-- MyBatis 的配置文件(例如:mybatis-config.xml)中配置二级缓存 -->
 <configuration>
     <settings>
         <setting name="cacheEnabled" value="true"/> <!-- 开启二级缓存 -->
     </settings>
     <!-- 其他配置 -->
 </configuration>
 ​
  • 配置映射文件

在Mapper.xml映射文件中添加cache标签,表示次mapper开启二级缓存。

 <!--
     表示此namespace使用二级缓存
     cache标签的属性:
         eviction="LRU" :清除策略,默认为LRU,移除最长时间不被使用的对象。
         flushInterval="60000" :刷新间隔,以毫秒为单位的合理时间量
         size="512" :引用数目
         readOnly="true" :只读的缓存会给所有调用者返回缓存对象的相同实例
         更新操作影响:
 如果将缓存设置为只读模式,在应用程序中执行的更新操作(insert、update、delete)不会更新缓存中的数据。
 MyBatis 会根据更新操作自动刷新或者清空相关的缓存数据,以保证数据的一致性。
 -->
 <!-- MyBatis 的配置文件(例如:mybatis-config.xml)中配置二级缓存 -->
 <configuration>
     <settings>
         <!-- 其他配置 -->
     </settings>
     <cache
         eviction="LRU"
         flushInterval="60000"
         readOnly="true"
         size="1024"
         type="org.mybatis.caches.ehcache.EhcacheCache"/>
     <!-- 其他配置 -->
 </configuration>
 ​
 <!--按照学号迭代查询-->
 <!--
     二级缓存
         属性useCache="false",sql语句自己可以决定是否使用二级缓存
         属性flushCache="false",sql语句自己可以决定是否刷新缓存,多用与新增,修改,删除语句
 -->
 <select id="findUser" resultType="User">
     SELECT * FROM t_user WHERE id in
         <foreach collection="list" item="id" open="(" separator="," close=")">
             #{id}
         </foreach>
 </select>
 ​
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值