MyBatis 缓存

缓存

MyBatis 具有缓存功能,可以将 select 语句进行缓存,下一次调用相同的 sql 语句就可以直接返回结果,减少数据库访问。MyBatis 的缓存分为一级缓存和二级缓存

一级缓存

默认情况下 MyBatis 使用一级缓存,该缓存无法关闭

缓存生命周期

一级缓存的生命周期就是从一个 sqlSession 创建到 sqlSession.close() 为止,事实上, 一级缓存就保存在 sqlSession 实例中,具体在其 localCache 字段内,以哈希表的形式保存

在这里插入图片描述

在执行 sqlSession.close() 后,localCache 就会被设为 null

缓存刷新
  1. 当执行数据库修改操作(insert,update,delete等)后,缓存会失效

    System.out.println(mapper.selectById(1));
    System.out.println(mapper.selectById(1));
    System.out.println("==================");
    
    mapper.update(new User(1,"user","3214"));
    
    System.out.println("==================");
    
    System.out.println(mapper.selectById(1));
    

    通过日志我们可以清楚地看到

    ==>  Preparing: select id,name,password from user where id=?
    ==> Parameters: 1(Integer)
    <==    Columns: id, name, password
    <==        Row: 1, user, 134
    <==      Total: 1
    User{id=1, name='user', password='134'}
    User{id=1, name='user', password='134'}                       // 直接返回缓存
    ==================
    ==>  Preparing: update user set name=?,password=? where id=?
    ==> Parameters: user(String), 3214(String), 1(Integer)
    <==    Updates: 1
    ==================
    ==>  Preparing: select id,name,password from user where id=?  // 缓存失效,重新查询
    ==> Parameters: 1(Integer)
    <==    Columns: id, name, password
    <==        Row: 1, user, 3214
    <==      Total: 1
    User{id=1, name='user', password='3214'}
    
  2. 手动清理缓存

    通过 sqlSession 的 clearCache() 方法可以手动刷新缓存

    System.out.println(mapper.selectById(1));
    sqlSession.clearCache();
    System.out.println(mapper.selectById(1));
    
    ==>  Preparing: select id,name,password from user where id=?
    ==> Parameters: 1(Integer)
    <==    Columns: id, name, password
    <==        Row: 1, user, 134
    <==      Total: 1
    User{id=1, name='user', password='134'}
    ==>  Preparing: select id,name,password from user where id=?
    ==> Parameters: 1(Integer)
    <==    Columns: id, name, password
    <==        Row: 1, user, 134
    <==      Total: 1
    User{id=1, name='user', password='134'}
    

二级缓存

一级缓存只作用于 Session 周期内,如果想要全局缓存就需要开启 MyBatis 的二级缓存

开启二级缓存很简单,只需要在想要缓存的映射语句所在的映射文件中添加一行:

<cache/>

另外,缓存结果集对应的对象需要实现 Serializable 接口,不然可能出错

cache 标签还可以添加属性以设置缓存的行为,包括:

  • eviction:清除缓存的策略,主要有 LRU(最近最少使用)和 FIFO(先进先出)等,默认为 LRU
  • flushInterval:缓存刷新间隔,默认为不设置,即只在调用语句时刷新
  • size:缓存保存的引用个数,默认为 1024
  • readOnly:只读,为 true 时缓存会返回缓存对象的相同实例,因此不能修改。为 false 时缓存会返回缓存对象的拷贝,速度较慢但是更安全,默认为 false返回对象拷贝依赖序列化,因此此时的对象必须实现 Serializable 接口,这也是上文提到不实现 Serializable 可能出错的原因,而如果 readOnly 为 true 就不一定要实现 Serializable 接口

示例:

<cache
  eviction="FIFO"
  flushInterval="60000"
  size="512"
  readOnly="true"/>

参考

mybatis一级缓存二级缓存 - 寻找风口的猪 - 博客园 (cnblogs.com)

mybatis – MyBatis 3 | XML 映射器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值