欢迎关注本人公众号:
1.缓存机制
在进行源码阅读时,通常可以以包为单位进行,因为包本身就是具有一定结构、功能的类的集合,但是,也总会有一些功能相对复杂,会横跨多个包。因此以功能为主线一次阅读多个包中的源码是必要的,能帮助我们理清功能实现。
mybatis基于cache包中提供的缓存实现了两级缓存机制。
1.一级缓存
mybatis的一级缓存又叫本地缓存,与它相关的配置项有2个。
1.在配置文件XML的setting节点,可选项有session与statement,分别对应了一次会话和一条语句,一级缓存的默认范围是session。
<setting name="cache" value="SESSION">
2.是在映射文件mapper.xml中的数据库操作节点内增加flushCache属性,默认值为false。可以设置为ture或false;当设置为true时,mybatis会在改数据库操作执行前清空一,二级缓存。
<select id = "selectById" resultType="User" flushCache="true">
</select>
一级缓存功能是由BaseExecutor类实现。BaseExecutor类作为实际执行器的基类,为所有实际执行器提供一些通用的基本功能,在这里增加缓存也就意味着每个实际执行器都具有着一级缓存。
public abstract class BaseExecutor implements Executor { private static final Log log = LogFactory.getLog(BaseExecutor.class); protected Transaction transaction; protected Executor wrapper; protected ConcurrentLinkedQueue<DeferredLoad> deferredLoads; // 查询操作的结果缓存 protected PerpetualCache localCache; // Callable查询的输出参数缓存 protected PerpetualCache localOutputParameterCache; protected Configuration configuration; protected int queryStack; private boolean closed;
/** * 更新数据库数据,INSERT/UPDATE/DELETE三种操作都会调用该方法 * @param ms 映射语句 * @param parameter 参数对象 * @return 数据库操作结果 * @throws SQLException */ @Override public int update(MappedStatement ms, Object parameter) throws SQLException { ErrorContext.instance().resource(ms.getResource()) .activity("executing an update").object(ms.getId()); if (closed) { // 执行器已经关闭 throw new ExecutorException("Executor was closed."); } // 清理本地缓存 clearLocalCache(); // 返回调用子类进行操作 return doUpdate(ms, parameter); } @Override public List<BatchResult> flushStateme