mybatis源码解析--mapper解析之cache

本文详细解析了MyBatis的二级缓存机制,包括默认的PerpetualCache实现、缓存配置及自定义缓存实现。通过XMLMapperBuilder解析mapper文件中的cache元素,并利用CacheBuilder构建缓存实例。缓存策略可以通过设置eviction属性来自定义,如LruCache等。同时,文章提供了自定义缓存的示例和测试,展示了缓存如何提高查询效率并避免重复数据库查询。
摘要由CSDN通过智能技术生成

mybatis源码解析–mapper解析之cache

cache用法

MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。MyBatis 3 中的缓存实现的很多改进都已经实现了,使得它更加强大而且易于配置。

默认情况下是没有开启缓存的,除了局部的 session 缓存,可以增强变现而且处理循环 依赖也是必须的。要开启二级缓存,需要我们在自己的maper文件中添加

<cache type="" eviction="FIFO" flushInterval="60000" size="512" readOnly="" blocking="">
      <property name="" value=""/>
</cache>
#type 
表示自定义的缓存的类,没有的情况下会存在一个默认的缓存类PerpetualCache.class。
自定义的缓存类需要有一个以String为参数的构造函数
#eviction 
表示缓存的策略(只支持默认的缓存类,自定义的缓存类不支持)
    LRU – 最近最少使用的:移除最长时间不被使用的对象。
    FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
    SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
    WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
#flushInterval 
(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒 形式的时间段。
默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新
#size 
(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的 可用内存资源数目。
默认值是 1024
#readOnly 
(只读)属性可以被设置为 truefalse。
只读的缓存会给所有调用者返回缓 存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存 会返回缓存对象的拷贝(通过序列化) 。
这会慢一些,但是安全,因此默认是 false
#blocking 
是否采用阻塞的方式(加锁)

同时还需要我们在对应的SQL上面调整缓存的使用

<!--根据ID查询-->
    <select id="selectById"
         resultType="com.liubin.study.mybatis.object.dataobject.SupplierLabelDO"
            useCache="true"
            flushCache="false">
        <include refid="selectFields"/>
        <where>
            label.id = #{id}
        </where>
    </select>
#useCache 是否使用缓存。
从缓存中读取,如果存在,那么直接返回。不存在,则查询数据库并更新缓存。
#flushCache 是否更新缓存
强制更新缓存

实现自定义的缓存

对于自定义的缓存,我们需要实现Cache接口,可以看一下Cache接口的内容

public interface Cache {
   

  /**
   * 返回缓存的唯一标识
   */
  String getId();

  /**
   * 设置缓存
   */
  void putObject(Object key, Object value);

  /**
   * 换取缓存
   */
  Object getObject(Object key);

  /**
   * As of 3.3.0 this method is only called during a rollback 
   * for any previous value that was missing in the cache.
   * This lets any blocking cache to release the lock that 
   * may have previously put on the key.
   * A blocking cache puts a lock when a value is null 
   * and releases it when the value is back again.
   * This way other threads will wait for the value to be 
   * available instead of hitting the database.
   *
   * 
   * @param key The key
   * @return Not used
   */
  Object removeObject(Object key);

  /**
   * 清空缓存
   */  
  void clear();

  /**
   * 可选的,获取缓存的数量
   */
  int getSize();

  /** 
   * 可选的,获取缓存的读写锁
   */
  ReadWriteLock getReadWriteLock();

}

我们自行实现一个用mapper存储的缓存

/**
 * 自定义实行的mybatis的缓存<br/>
 * 
 * @Type
 * @Desc
 * @date 2018/8/2
 * @Version
 */
public class SimpleCache implements Cache {
   
    private final Logger LOGGER = LoggerFactory.getLogger(SimpleCache.class);
    private String id;
    private Map<Object, Object> cache = new HashMap<Object, Object>();
    public SimpleCache(String id) {
        this.id = id;
    }
    public String getId() {
        return this.id;
    }
    public void putObject(Object key, Object value) {
        LOGGER.info("putObject:{},{}",key,value);
        cache.put(key,value);
    }
    public Object getObject(Object key) {
        Object value = cache.get(key);
        LOGGER.info("getObject:{},value:{}",key,value);
        return value;
    }
    public Object removeObject(Object key) {
        LOGGER.info("removeObject:{}",key);
        return null;
    }
    public void clear() {
        LOGGER.info("clear");
    }
    public int getSize() {
        LOGGER.info("getSize");
        return 0;
    }
    public ReadWriteLock getReadWriteLock() {
        LOGGER.info("getReadWriteLock");
        return null;
    }
}

在Mapper.xml中使用自定义的缓存

<!--
        自行实现的缓存缓存的配置
        -->
    <cache type="com.liubin.study.mybatis.cache.SimpleCache" eviction="FIFO" flushInterval="60000" size="512">
    </cache>
    <!--使用默认的缓存
    <cache eviction="FIFO" flushInterval="60000" size="512">
    </cache>-->

    <!--根据ID查询-->
    <sele
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值