0
点赞
收藏
分享

微信扫一扫

MyBatis 缓存

黄昏孤酒 2022-02-22 阅读 103

缓存

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'}
    

二级缓存

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

<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 条评论