Mybatis一级缓存实现原理

Mybatis将缓存设计成两级结构,一级缓存是sqlSession级别的,同一个会话中查询多次相同sql不需要都去查数据库,二级缓存是Mapper级别的,多个会话去执行同一个Mapper的sql数据缓存在同一个地方,本文讲解一级缓存(本地缓存)内部机制,下图是整个缓存总体结构图:

144251_GV1A_1445156.png

一、一级缓存存在的意义

每当开启一次和数据库的会话,Mybatis会创建一个sqlSession表示会话,在一次会话中可能会重复查询多次数据库,每一次查询都会发起一次网络请求,这个代价很大,所以可以把第一次查询的结果缓存起来,同一个会话如果是完全一样的查询直接把缓存结果返回,这也是mybatis默认开启的。

二、一级缓存的生命周期

sqlSession查询数据库时把工作交给Executor,每次创建Executor时会创建本地缓存PerpetualCache对象,会话结束会销毁本地缓存对象,会话中执行任何增删改操作都会把缓存清空。

上面PerpetualCache里面实际上就是一个HashMap, 这里的HashMap没有做大小限制,原因是本地缓存生命周期很短,同一个会话中不会连续调用太多次查询。

三、缓存key的定义

如果缓存中有查询保留的记录则直接返回,怎样确定是完全一样的查询,这是通过相关条件构造CacheKey唯一确定一次查询,通过createCacheKey方法看到有四种参数确定唯一查询:
1. statementId
2. RowBounds的offset和limit
3. sql语句
4. 查询参数

public CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql) {
	if (closed)
		throw new ExecutorException("Executor was closed.");
	CacheKey cacheKey = new CacheKey();
	//statementId
	cacheKey.update(ms.getId());
	//分页数据
	cacheKey.update(rowBounds.getOffset());
	cacheKey.update(rowBounds.getLimit());
	//sql
	cacheKey.update(boundSql.getSql());
	List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
	TypeHandlerRegistry typeHandlerRegistry = ms.getConfiguration().getTypeHandlerRegistry();
	//sql参数
	for (int i = 0; i < parameterMappings.size(); i++) { 
		ParameterMapping parameterMapping = parameterMappings.get(i);
		if (parameterMapping.getMode() != ParameterMode.OUT) {
			Object value;
			String propertyName = parameterMapping.getProperty();
			if (boundSql.hasAdditionalParameter(propertyName)) {
				value = boundSql.getAdditionalParameter(propertyName);
			} else if (parameterObject == null) {
				value = null;
			} else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
				value = parameterObject;
			} else {
				MetaObject metaObject = configuration.newMetaObject(parameterObject);
				value = metaObject.getValue(propertyName);
			}
			cacheKey.update(value);
		}
	}
	return cacheKey;
}

 

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值