首先,先清除mybatis一级缓存和二级缓存的作用域。
一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。(https://www.cnblogs.com/little-fly/p/6251451.html)
这句话怎么理解呢?也就是一级缓存是在同一个SqlSession下有效的。SqlSession关闭则缓存释放。下面代码就是一个一级缓存的例子。并没有重新获取SqlSession。第二个mapper.getPerson()就是直接查询的一级缓存。不查询数据库。
注:Mybatis默认开启一级缓存
/**
* @author cuimiao
* @version 0.0.1
* @since 0.0.1 2017-11-21
*/
public class Demo {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream, "development_test");
//SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
try {
BlogMapper mapper = session.getMapper(BlogMapper.class);
Person person = mapper.getPerson();
System.out.println();
Person person2 = mapper.getPerson();
System.out.println();
} finally {
session.close();
}
}
}
二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession去操作数据库得到数据会存在二级缓存区域,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
也就是,在不用的页面(不同的session中)查询同一个sql的缓存。下面是二级缓存的代码示例
/**
* @author cuimiao
* @version 0.0.1
* @since 0.0.1 2017-11-22
*/
public class DemoCache {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream, "development_test");
//SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
SqlSession session2 = sqlSessionFactory.openSession();
try {
BlogMapper mapper = session.getMapper(BlogMapper.class);
Person person = mapper.getPersonById(1);
session.close();//这个close必须要加,不然缓存存不进去。
System.out.println();
BlogMapper mapper2 = session2.getMapper(BlogMapper.class);
Person person2 = mapper2.getPersonById(1);
session2.close();
System.out.println();
} finally {
session.close();
}
}
}
这里我开启了两个session。但查询的同一条sql。这个时候,第二个查询条件走的二级缓存,并不查询数据库。
这里遇到了坎坷,感谢https://www.cnblogs.com/shenxiaoquan/p/5796733.html这个链接。
session.close()不执行的话,是不能把sql加入缓存的。也就是只有在session关闭后,缓存才被添加,后面的sql查询才可以用缓存。