12.MyBatis缓存

12.MyBatis缓存

什么是缓存?为什么要缓存?哪些数据能缓存?

  • 存在内存中的临时数据

  • 缓存是一般的ORM 框架都会提供的功能,目的就是提升查询的效率和减少数据库的压力。

  • 经常查询又不经常改变的数据适合缓存

Mybatis一级缓存:

  • 默认情况下是开启的;(SqlSession级别的缓存)
  • 本地缓存

Mybatis二级缓存:

  • 需要手动开启和配置
  • 基于namespace级别的缓存

Cache缓存

  • Mybatis支持自定义缓存 需要事先Cache接口
12.1 Mybatis一级缓存
  • 测试代码
@Test
public void testQueryById(){
    SqlSession sqlSession = MyBatisUtil.getSqlSession();

    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    User user1 = mapper.queryById(1);
    User user2 = mapper.queryById(1);

    System.out.println(user1);
    System.out.println(user2);
    System.out.println(user1==user2);

    sqlSession.close();
}
  • 测试结果

    ==>  Preparing: select * from user where id=?
    ==> Parameters: 1(Integer)
    <==    Columns: id, name, email, phone, gender, password, age, create_time, update_time
    <==        Row: 1, xuan, 1870136088@qq.com, 13927497470, 1, 123456, 111, 2020-07-11 18:15:33, 2020-07-12 13:13:07
    <==      Total: 1
    User{id=1, name='xuan', email='1870136088@qq.com', phone='13927497470', gender=1, password='123456', age=111, create_time=Sun Jul 12 02:15:33 GMT+08:00 2020, update_time=Sun Jul 12 21:13:07 GMT+08:00 2020}
    User{id=1, name='xuan', email='1870136088@qq.com', phone='13927497470', gender=1, password='123456', age=111, create_time=Sun Jul 12 02:15:33 GMT+08:00 2020, update_time=Sun Jul 12 21:13:07 GMT+08:00 2020}
    true
    

一级缓存的不足:

使用一级缓存的时候,因为缓存不能跨会话共享,不同的会话之间对于相同的数据可能有不一样的缓存。在有多个会话或者分布式环境下,会存在脏数据的问题。如果要解决这个问题,就要用到二级缓存。MyBatis 一级缓存(MyBaits 称其为 Local Cache)无法关闭,但是有两种级别可选:

  1. session 级别的缓存,在同一个 sqlSession 内,对同样的查询将不再查询数据库,直接从缓存中。
  2. statement 级别的缓存,避坑: 为了避免这个问题,可以将一级缓存的级别设为 statement 级别的,这样每次查询结束都会清掉一级缓存。
12.2 Mybatis二级缓存

为什么要开启二级缓存,有什么用?

  • 二级缓存是用来解决一级缓存不能跨会话共享的问题的,范围是namespace 级别的,可以被多个SqlSession 共享(只要是同一个接口里面的相同方法,都可以共享

开启二级缓存的方法

第一步:配置 mybatis.configuration.cache-enabled=true,只要没有显式地设置cacheEnabled=false,都会用CachingExecutor 装饰基本的执行器。

第二步:在Mapper.xml 中配置标签:

<cache
  eviction="FIFO"
  flushInterval="60000"
  size="512"
  readOnly="true"/>
#这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突。

基本上就是这样。这个简单语句的效果如下:

  • 映射语句文件中的所有 select 语句的结果将会被缓存。
  • 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
  • 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
  • 缓存不会定时进行刷新(也就是说,没有刷新间隔)。
  • 缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。
  • 缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

可用的清除策略有:

  • LRU – 最近最少使用:移除最长时间不被使用的对象。
  • FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
  • SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。
  • WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。

默认的清除策略是 LRU

12.3 自定义Ehcache缓存

什么是ehcache?

EhCache 是一个**纯Java的进程内缓存框架,**具有快速、精干等特点,是Hibernate中默认CacheProvider。**Ehcache是一种广泛使用的开源Java分布式缓存。**主要面向通用缓存,Java EE和轻量级容器。它具有内存磁盘存储,缓存加载器,缓存扩展,缓存异常处理程序,一个gzip缓存servlet过滤器,支持REST和SOAP api等特点。

集成:

可以单独使用,一般在第三方库中被用到的比较多(如mybatis、shiro等)ehcache 对分布式支持不够好,多个节点不能同步,通常和redis一块使用。

12.3.1 Mybatis集成Ehcache

​ 第一步:导入相关依赖

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-ehcache -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.0.0</version>
</dependency>

​ 第二步: 配置文件中指定二级缓存

<cache type="org.mybatis.caches.ehcache"></cache>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值