1.为什么要有缓存?
因为有些时候查询数据的频率很高,很耗费数据库资源,所有常常把变动不大且访问率高的数据放在一个缓存容器里,从而缓解数据库压力。
2.一级缓存
- 存在时间
SqlSession类实例对象存在时,一级缓存一直存在,在这期间除非了修改,添加,删除,执行commit,close,flush ,clearCache时,缓存才会被清空。
当查询数据时,会先到一级缓存查询,如果没有相关数据,会到数据库查询,然后保存到一级缓存。 - 一级缓存开启配置
一级缓存是mybatis默认开启的
如果要关闭,在crud标签体内增加 usrCache=“true/false”
3.二级缓存
-
存在时间
二级缓存是多个SqlSession共享一个mapper缓存空间,其他清空的情况和一级缓存相同,二级缓存只不过是比一级缓存范围大了而已(这里的二级缓存解释是书上的, 《spring mvc+mybatis 开发》p106上面的解释,但我测试的时候有疑问在最后) -
二级缓存开启配置
SqlMapConfig.xml配置
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
mapper.xml
<!--开启user支持二级缓存-->
<cache/>
嗯,在二级缓存测试过程中,
我已经照着上面把二级缓存开启了,
可是没有达到从缓存中取出数据
而是两次查询了数据库
测试类
public class SecondLevelCacheTest {
private InputStream in;
private SqlSessionFactory factory;
@Before//用于在测试方法执行之前执行
public void init()throws Exception{
//1.读取配置文件,生成字节输入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.获取SqlSessionFactory
factory = new SqlSessionFactoryBuilder().build(in);
}
@After//用于在测试方法执行之后执行
public void destroy()throws Exception{
in.close();
}
/**
* 测试一级缓存
*/
@Test
public void testSecondLevelCache(){
SqlSession sqlSession1 = factory.openSession();
IUserDao dao1 = sqlSession1.getMapper(IUserDao.class);
User user1 = dao1.findById(41);
System.out.println(user1);
//同一个工厂实例创建的不同sqlsession实例
SqlSession sqlSession2 = factory.openSession();
IUserDao dao2 = sqlSession2.getMapper(IUserDao.class);
User user2 = dao2.findById(41);
System.out.println(user2);
sqlSession2.close();
System.out.println(user1 == user2);
//输出false,user1和user2不是同一个对象
}
}
多个sqlsession实例 共享一个mapper 不是嘛?为什么 这里输出的user 不是同一个对象? 有点以为,如果有朋友看见搞明白了,愿告评论告知一下
四处跪求原因终于找到,二级缓存只有当,关闭sqlsession的时候才会存入二级缓存空间
测试代码修改如下,可以更加深入了解二级缓存
//进修改这里
@Test
public void testSecondLevelCache(){
SqlSession sqlSession1 = factory.openSession();
SqlSession sqlSession2 = factory.openSession();
IUserDao dao2 = sqlSession2.getMapper(IUserDao.class);
User user2 = dao2.findById(41);
System.out.println(user2);
sqlSession2.close();
IUserDao dao1 = sqlSession1.getMapper(IUserDao.class);
User user1 = dao1.findById(41);
System.out.println(user1);
System.out.println(user1 == user2);
}