Mybatis一级缓存实现原理
2016-11-23 00:00
260 查看
Mybatis将缓存设计成两级结构,一级缓存是sqlSession级别的,同一个会话中查询多次相同sql不需要都去查数据库,二级缓存是Mapper级别的,多个会话去执行同一个Mapper的sql数据缓存在同一个地方,本文讲解一级缓存(本地缓存)内部机制,下图是整个缓存总体结构图:
上面PerpetualCache里面实际上就是一个HashMap, 这里的HashMap没有做大小限制,原因是本地缓存生命周期很短,同一个会话中不会连续调用太多次查询。
1. statementId
2. RowBounds的offset和limit
3. sql语句
4. 查询参数
一、一级缓存存在的意义
每当开启一次和数据库的会话,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; }
相关文章推荐
- 浅谈Mybatis中session的一级缓存的实现原理
- mybatis的一级缓存实现原理
- 深入理解mybatis原理(三) MyBatis的一级缓存实现详解
- 《深入理解mybatis原理(三)》 MyBatis的一级缓存实现详解 及使用注意事项
- 《深入理解mybatis原理》 MyBatis的一级缓存实现详解 及使用注意事项
- Mybatis实现原理深入解析 (转载)
- 【MyBatis框架】查询缓存-一级缓存原理
- 《深入理解mybatis原理》 MyBatis的一级缓存实现详解 及使用注意事项
- 整合Spring3及MyBatis3 DAO空实现的原理分析
- 《深入理解mybatis原理(五)》 MyBatis缓存机制的设计与实现
- 由浅入深分析mybatis通过动态代理实现拦截器(插件)的原理
- MyBatis原理第四篇——statementHandler对象(sqlSession内部核心实现,插件的基础)
- Mybatis 代码流程及实现原理解析(三)
- Mybatis 代码流程及实现原理解析(一)
- Mybatis最入门---分页查询(拦截器分页原理及实现)
- MyBatis 一级缓存实现
- MyBatis的一级缓存实现详解 及使用注意事项
- 《深入理解mybatis原理》 MyBatis的一级缓存实现详解 及使用注意事项
- Mybatis实现【7】 --基于接口编程的原理
- mybatis拦截器实现原理解析