1.一级缓存
mybatis一级缓存的作用范围是session,单使用mybatis时默认是开启的;
当第一次查询时,mybatis会把查询结果已Map<cacheKey,value>的形式保存到Local cache中;当再次查询时,会先去Local cache中查询,当cacheKey存在时,返回value。
cacheKey判断是否相同
1.statementId(命名空间+方法名) 一致
2.参数一致
@Test
void getUser() {
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
final UserMapper mapper = sqlSession.getMapper(UserMapper.class);
long time = new Date().getTime();
mapper.getsss();
long time2 = new Date().getTime();
System.out.println("第一次:"+ (time2 - time));//6s
long time3 = new Date().getTime();
mapper.getsss();
long time4 = new Date().getTime();
System.out.println("第二次:"+ (time4 - time3)); //0s
mapper.update(1);
System.out.println("更新了数据--------------------------------------------------------------------");
long time5 = new Date().getTime();
mapper.getsss(); //6s
long time6 = new Date().getTime();
System.out.println("第三次:"+ (time6 - time5));
}
}
在spring中mybatis一级缓存为啥没作用(没有事务会失效,有事务不会失效):
单独使用mybatis时:使用sqlsessionFactory创建一个Sqlsession,在不需要使用时在关闭。
使用mybatis-spring,您不需要直接使用sqlsessionFactory,spring将原本的DefaultSqlSession替换成了SqlSessionTemplate,并且在SqlSessionTemplate将sqlSession替换成了代理对象,它根据spring的事务配置自动提交、回滚和关闭会话。
spring通过mybatis调用数据库的过程如下:
1.当请求过来时,spring检测到后 会自动申请一个mybatis的sqlsession,并与当前线程绑定,放入threadLocal中,
2.SqlSessionTemplate()从threadLocal中获取sqlsession,去执行查询
3.查询结束,清除threadLocal与当前线程绑定的session,并释放支援
4.需要再次访问时,重新执行1.2.3步骤
Spring使用mybatis一级缓存:
使用事务:不使用事务,session会直接关闭;在开启事物的情况之下,spring使用threadLocal获取当前资源绑定同一个sqlSession,因此此时一级缓存是有效的。
mybatis一级缓存是使用hashmap简单实现的,所以多线程情况下会出现脏数据,所以一般不使用。