mybatis源码学习笔记

Mapper(经过动态代理,第一层是mybatis的动态代理,还在mybatis的体系中)-->sqlSessionTemplate(由Mapper代理对象的sqlSession对象指向),虽然包含了SqlSessonFactory属性,但不能直接使用,必须经过sqlSessionTemplate的另一个属性SqlSessionProxy,即SqlSessionIntercepter的处理,通过该处理调用sqlSessionTemplate的属性对象SqlSessonFactory创建会话,通过会话发起查询-->SqlSessionIntercepter(代理对象,spring的动态代理)-->SqlSessonFactory(每一次查询都会创建一个sqlSession对象,除非与其他事务在同一个事务中,会利用前一个查询语句保存在ThreadLocal中的sqlSession对象,但这个ThreadLocal对象只有在开启了事务的前提下才会存储sqlSession对象)。

为什么在sqlSessionTemplate调用select(方法里调用的是SqlSessionIntercepter的方法)语句时还要经过一层动态代理:

进行拦截,处理spring动态代理的逻辑,实现事务-->同一个事务获得的是同一个sqlSession对象(原生mybatis真正发起查询的对象),如果不进行动态代理,就需要在该类中的许多方法都实现构造DefaultSqlsession对象,代码冗余,所以就进行了动态代理,相对于抽取了公共的切面。

一级缓存是sqlSession级别的,二级缓存是应用级别的,可以跨线程使用,流程-->会话->二级缓存->一级缓存,所以二级缓存的命中率更高,适合缓存一些修改较少的数据。

二级缓存需要关注数据的生命周期,而一级缓存不需要,为什么:

一级缓存的生命周期非常短暂,而二级缓存的生命周期很长。

二级缓存使用的是装饰器模式+责任链模式。

二级缓存设计为事务提交后才存储,是为了避免脏数据的产生,一个线程执行了两个语句,如果为提交就缓存了第一条语句,但第二条语句出现错误需要回滚,缓存的第一条语句就成了脏数据。

你可能感兴趣的:(mybatis,java,缓存)