Mybatis二级缓存实现原理

二级缓存与一级缓存机制相同,不同的是它的作用域是在Mapper层, 即不同会话之间共享缓存内容,二级缓存不是默认开启的,如果配置了cache功能在创建Executor后会装饰一层CachingExecutor,存取二级缓存都在CachingExecutor中封装,总体缓存架构图见https://my.oschina.net/chengxiaoyuan/blog/792878

一、二级缓存使用

全局配置

<settings>
<setting name="cacheEnabled" value="true"/>
</settings>

Mapper里面配置cache

<mapper namespace="com.domain.CachedAuthorMapper">
	<cache />
</mapper>

如果想mapper中某个查询不用二级缓存则配置useCache=“false”

<select id="selectAllAuthors" resultType="domain.blog.Author" useCache="false">

如果希望每次执行sql前都刷新缓存则配置flushCache="true",该值select类型默认为false, 其他为true

二、二级缓存构造

上面cache里面有几个参数配置:

public class XMLMapperBuilder extends BaseBuilder {
	private void cacheElement(XNode context) throws Exception {
		if (context != null) {
			//获取缓存类型, 默认内存map, PERPETUAL在configuration初始化的时候会注册对应PerpetualCache
			String type = context.getStringAttribute("type", "PERPETUAL");
			//获取class,如果该类型不是自带的会使用classLoader加载
			Class<? extends Cache> typeClass = typeAliasRegistry.resolveAlias(type);
			//回收策略,装饰上面的缓存, 默认LRU
			String eviction = context.getStringAttribute("eviction", "LRU");
			Class<? extends Cache> evictionClass = typeAliasRegistry.resolveAlias(eviction);
			Long flushInterval = context.getLongAttribute("flushInterval");
			Integer size = context.getIntAttribute("size");
			boolean readWrite = !context.getBooleanAttribute("readOnly", false);
             //标签下面的参数
			Properties props = context.getChildrenAsProperties();
			//通过上面的参数构造cache
			builderAssistant.useNewCache(typeClass, evictionClass, flushInterval, size, readWrite, props);
		}
	}
}

PERPETUAL、LRU这些简称在初始化的时候会注册:

public Configuration() {
	.......

	typeAliasRegistry.registerAlias("PERPETUAL", PerpetualCache.class);
	typeAliasRegistry.registerAlias("FIFO", FifoCache.class);
	typeAliasRegistry.registerAlias("LRU", LruCache.class);
	typeAliasRegistry.registerAlias("SOFT", SoftCache.class);
	typeAliasRegistry.registerAlias("WEAK", WeakCache.class);

	......
}

上面去的各种参数后通过builderAssistant构造缓存并放到configuration配置的map中,看builderAssistant.useNewCache代码:

public Cache useNewCache(Class<? extends Cache> typeClass, Class<? extends Cache> evictionClass, Long flushInterval,
		Integer size, boolean readWrite, Properties props) {
	//判断为空则取默认
	typeClass = valueOrDefault(typeClass, PerpetualCache.class);
	evictionClass = valueOrDefault(evictionClass, LruCache.class);
	//创建cache, 这里是builder模式, currentNamespace为id
	Cache cache = new CacheBuilder(currentNamespace).implementation(typeClass).addDecorator(evictionClass)
			.clearInterval(flushInterval).size(size).readWrite(readWrite).properties(props).build();
	//放到configuration里的map中, key为cache的id
	configuration.addCache(cache);
	currentCache = cache;
	return cache;
}

最终通过缓存的构造模式构造一个缓存,并把缓存放入到configuration的map中,看CacheBuilder

public Cache build() {
	//判断缓存内部实现和装饰是否为空,如果为空则再给默认值
	setDefaultImplementations();
	//创建缓存实现
	Cache cache = newBaseCacheInstance(implementation, id);
	//properties配置
	setCacheProperties(cache);
	//如果是内部map缓存则用内部装饰
	if (PerpetualCache.class.equals(cache.getClass())) { 
		for (Class<? extends Cache> decorator : decorators) {
			cache = newCacheDecoratorInstance(decorator, cache);
			setCacheProperties(cache);
		}
		cache = setStandardDecorators(cache);
	} else if (!LoggingCache.class.isAssignableFrom(cache.getClass())) {
		//如果是LoggingCache子类则用LoggingCache装饰
		cache = new LoggingCache(cache);
	}
	return cache;
}

三、接入第三方缓存

导入依赖包

<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache-core</artifactId>
    <version>2.6.5</version>
</dependency>
<dependency>
    <groupId>org.mybatis.caches</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.0.2</version>
</dependency>

ehcache自带配置

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">

    <diskStore path="F:\develop\ehcache"/>

    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            maxElementsOnDisk="10000000"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
    </defaultCache>
</ehcache>

mybatis中mapper配置

114408_YO2v_1445156.png

转载于:https://my.oschina.net/chengxiaoyuan/blog/794137

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值