一级缓存
1、默认开启,未找到关闭办法
2、缓存级别:SqlSession级别
3、缓存位置:SqlSession.BaseExecutor.PerpetualCache localCache
4、跨SqlSession无法访问
二级缓存
1、开启办法:cache-enabled: true,xml文件需要增加cache标签
2、cache标签readOnly属性设置为false时,实体类必须实现序列化接口;
3、缓存级别:个人认为是mapper级别,也就是namespace级别;
4、缓存位置:SqlSessionFactory会扫描mapper放在Map<String, MappedStatement> mappedStatements,MappedStatement的成员变量Cache cache就是缓存
5、SqlSession.commit()方法之后,数据才会写入缓存
线程安全问题:
1、DefaultSqlSessionFactory是单例,但是成员变量configuration是final类型,可以保证线程安全,也不会有线程进行修改;
2、SqlSession有三个实现:DefaultSqlSession、SqlSessionTemplate、SqlSessionManager
DefaultSqlSession线程不安全,不能多线程使用一个实例;
SqlSessionTemplate和SqlSessionManager通过ThreadLocal来保证sqlsession之间的线程隔离:
SqlSessionTemplate:
private static final ThreadLocal<Map<Object, Object>> resources = new NamedThreadLocal("Transactional resources");
SqlSessionManager:
private final ThreadLocal<SqlSession> localSqlSession = new ThreadLocal<>();
3、使用@Autowired注入mapper时,底层使用的是SqlSessionTemplate来保证线程安全。
动态代理:
SqlSessionTemplate、mapper通过动态代理织入拦截器,保证每次执行前获取新的SqlSession
动态代理可以再深入研究