Mybatis的一级缓存和二级缓存的基本介绍

Mybatis的一级缓存和二级缓存
基本介绍
  1. 程序在执行的时候,它调用的对象存在于内存中,而我们为了提高性能方便快速调用,把已经被调用过的对象存在于缓存中,再次调用相同的程序或者相同的对象的时候,不必去数据库或者其他的持久化设备中查询。
  2. 而Mybatis的缓存都是为了更好的执行查询语句,一旦执行增删改语句,缓存就会被清零
一级缓存
  1. 一级缓存的作用域是我们一个SqlSession对象,同一个SqlSession中执行相同的查询语句(查询的参数也相同),第一次查询获取结果的时候,就会把它也写入缓存中,那木第二次查询的时候就会直接在缓存中获取结果,而不会在数据库中获取。

  2. 它是基于PerpetualCache的本地缓存,基于HashMap实现。

    public class PerpetualCache implements Cache {
        private final String id; // 缓存id
        private final Map<Object, Object> cache = new HashMap(); // 缓存的数据结构
    
        public PerpetualCache(String id) {
            this.id = id;
        }
    
        public String getId() {
            return this.id;
        }
    
        public int getSize() {
            return this.cache.size();
        }
    
        public void putObject(Object key, Object value) {
            this.cache.put(key, value);
        }
    
        public Object getObject(Object key) {
            return this.cache.get(key);
        }
    
        public Object removeObject(Object key) {
            return this.cache.remove(key);
        }
    
        public void clear() { //清除缓存
            this.cache.clear();
        }
    
        public boolean equals(Object o) { 
            if (this.getId() == null) {
                throw new CacheException("Cache instances require an ID.");
            } else if (this == o) {
                return true;
            } else if (!(o instanceof Cache)) {
                return false;
            } else {
                Cache otherCache = (Cache)o;
                return this.getId().equals(otherCache.getId());
            }
        }
    
        public int hashCode() { 
            if (this.getId() == null) {
                throw new CacheException("Cache instances require an ID.");
            } else {
                return this.getId().hashCode();
            }
        }
    }
    
  3. 在Mybatis中我们只要创建一个SqlSession对象,就会默认开启一个一级缓存。

  4. 缓存失效:我们执行完增删改语句之后,缓存就会失效。或者执行SqlSession的commit()和close()方法的时候也会清空一级缓存。

二级缓存
  1. 二级缓存是mapper级别的也可以说是namespace级别的。当我们多个SqlSession去执行去操作同一个mapper下的sql语句,他们是共用这个二级缓存的。

        <mappers>
            <mapper resource="mapper/VideoMapper.xml"/>
            <mapper resource="mapper/VideoOrderMapper.xml"/>
        </mappers>
    
  2. 它也是基于PerpetualCache 的 HashMap本地缓存,可自定义存储源,如 Ehcache/Redis等

  3. 二级缓存是要我们去打开的

    • 第一步 全局配置中加入cacheEnabled 并且将值设为true。

         <settings>
              <setting name="cacheEnabled" value="true" />
          </settings>
      
    • 第二步开启 namespace下的二级缓存

    • <cache eviction="LRU" flushInterval="100000" readOnly="true" size="1024"/>
      
      • eviction : 就是我们的缓存的回收策略

        常见的有两种 : LRU和FIFO

        LRU: 最近最少使用,缓存不够的时候就会清除掉最长时间没有使用的数据

        FIFO:先进先出,按数据的的进入缓存的顺序来清除它们

      • flushInterval:清空缓存的时间间隔,单位是ms

      • readOnly:只可以从缓存中读取数据。默认是false,我们要改为true

      • 用来指定缓存中最多指定key的数量。(底层是HashMap)

  4. 二级缓存是跨sqlSessionz,只要它执行的是这个mapper中的查询语句,被查询到数据就会被存储于二级缓存中。

  5. 失效策略 :执行完增删改语句之后就会清空二级缓存

  6. 一级缓存和二级缓存的使用顺序: 优先二级缓存 —> 一级缓存 ----> 数据库

  7. 二级缓存的使用原则

    • 二级缓存的中的数据是基于namespace的,不同的namespace下的缓存数据是互不干扰的,如果在多个namespace下对同一个表进行操作,那木缓存下的数据可能就会出现不一致的问题
    • 查询多于修改时使用二级缓存 。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值