一、缓存介绍
1.1为什么使用缓存?
遇到618 、双11等访问量大的时候,数据库的压力就会增大。
于是就可以在首次访问时,查询数据库,并将数据存储到内存中;当再次访问时直接访问缓存,不需要重新查数据库,减少IO、硬盘读写次数、同时减少数据库的压力,提高效率。
1.2Mybatis中的一级缓存和二级缓存是什么?
-
一级缓存:
它指的是mybatis中的SqlSession级别的缓存。当我们执行完查询之后,查询的结果会同时存在SqlSession为我们提供的一块区域中。当我们再次查询同样的数据,mybatis会先去SqlSession中查询是否有,有的话直接拿出来使用。当SqlSession对象消失时,Mybatis的一级缓存也就消失了。
-
二级缓存:
它指的是Mybatis中SqlSessionFactory级别的缓存,由同一个SqlSessioFactory对象创建的多个SqlSession共享其缓存。多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
二、一级缓存代码实现
2.1 正常走缓存
@Test public void testFindUserById() throws Exception{ SqlSession sqlSession1 = sqlSessionFactory.openSession(); UserDao userDao = sqlSession1.getMapper(UserDao.class); User user1 = userDao.findUserById(41); //执行查询 System.out.println("第一次查询:" + user1); User user2 = userDao.findUserById(41); //不执行查询 System.out.println("第二次查询:" + user2);
2.2 不走缓存①:同一个sqlSession,但在两次相同条件的查询语句执行期间,进行了增删改
@Test // public void testNoCache2() { // 不走缓存1: 相同的sqlsession,在两次同一个查询操作期间进行了增删改 // // SqlSession sqlSession1 = sqlSessionFactory.openSession(); // UserMapper mapper1 =sqlSession1.getMapper(UserMapper.class); // // // System.out.println("!!!!!!!第一次查询!!!!"); // User user1=mapper1.findUserById(41); // System.out.println(user1); // // System.out.println("两次之间进行删除操作"); // mapper1.deleteUserById(66); // // System.out.println("!!!! !第二次查询!!!"); // User user2=mapper1.findUserById(41); // System.out.println(user2);
2.3不走缓存②:相同的sqlsession,但连续两次查询的语句条件不同
@Test // public void testGoCache() { // //不走缓存2: 相同的sqlsession,但连续两次查询的语句条件不同 // // UserMapper mapper = sqlSession1.getMapper(UserMapper.class); // System.out.println("!!!!!!!第一次查询!!!!!!!1"); // User user1=mapper.findUserById(41); //查询Id为41 // System.out.println(user1); // // System.out.println("!!!!!!!第二次查询!!!!!!!!"); // User user2=mapper.findUserById(42); //查询Id为42 // System.out.println(user2);
2.4不走缓存③:在两次相同条件的查询语句执行期间,手动清楚了缓存
@Test // public void testGoCache() { // //不走缓存3: 在两次相同条件的查询语句执行期间,手动清楚了缓存 // // UserMapper mapper = sqlSession1.getMapper(UserMapper.class); // System.out.println("!!!!!!!第一次查询!!!!!!!!"); // User user1=mapper.findUserById(41); // System.out.println(user1); // // sqlSession1.clearCache(); //手动清楚了缓存 // // System.out.println("!!!!!!!!第二次查询!!!!!!!!"); // User user2=mapper.findUserById(41); // System.out.println(user2); // // // sqlSession1.close(); // // }
2.5不走缓存④:不同的sqlsession,对应的不同的一级缓存
@Test // public void testNoCache() { // //不走缓存4: 不同的sqlsession,对应的不同的一级缓存 // SqlSession sqlSession1 = sqlSessionFactory.openSession(); // SqlSession sqlSession2 = sqlSessionFactory.openSession(); // UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class); // UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class); // // System.out.println("!!!!第一次查询!!!!!!!!"); // User user1 = mapper1.findUserById(41); // System.out.println(user1); // // // System.out.println("!!!!!!第二次查询!!!!!!!!!!"); // User user2 = mapper2.findUserById(41); // System.out.println(user2); // // // sqlSession1.close(); // sqlSession2.close(); // }
三、二级缓存代码实现
3.1 正常走缓存
@Test public void testGoCache() { //走缓存 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 获得数据库会话实例 sqlSession = sqlSessionFactory.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); System.out.println("!!!!!!!!!!!!!!第一次查询!!!!!!!!!!!!!!!!1"); User user1 = mapper.findUserById(41); System.out.println(user1); sqlSession.commit(); System.out.println("!!!!!!!!!!!!!!第二次查询!!!!!!!!!!!!!!!!1"); User user2 = mapper.findUserById(41); System.out.println(user2); }
3.2 不走缓存①:同一个SqlSessionFactory,但在两次相同条件的查询语句执行期间,进行了增删改
@Test public void testNoCache1() { //不走缓存① 同一个工厂之间进行了增删改 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 获得数据库会话实例 sqlSession1 = sqlSessionFactory.openSession(); UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class); sqlSession2 = sqlSessionFactory.openSession(); UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class); System.out.println("!!!!!!!!!!!!!!第一次查询!!!!!!!!!!!!!!!!1"); User user1 = mapper1.findUserById(41); System.out.println(user1); sqlSession1.commit(); System.out.println("两次之间进行删除操作"); // mapper1.deleteUserById(66); 这个走缓存 mapper2.deleteUserById(66); 这个不走缓存 System.out.println("!!!!!!!!!!!!!!第二次查询!!!!!!!!!!!!!!!!1"); User user2 = mapper2.findUserById(41); System.out.println(user2); }
3.3 不走缓存②:相同的SqlSessionFactory,但连续两次查询的语句条件不同
@Test
public void testNoCache2() {
//不走缓存 同一个工厂两次查询语句不同
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 获得数据库会话实例
sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
System.out.println("!!!!!!!!!!!!!!第一次查 询!!!!!!!!!!!!!!!!1");
User user1 = mapper.findUserById(41);
System.out.println(user1);
sqlSession.commit();
System.out.println("!!!!!!!!!!!!!!第二次查询!!!!!!!!!!!!!!!!1");
User user2 = mapper.findUserById(42);
System.out.println(user2);
}
3. 4 不走缓存③:不同的SqlSessionFactory,对应的不同的二级缓存
@Test
public void testNoCache3() throws IOException {
//不走缓存③ 两次同样的操作 但是不是同一个工厂
InputStream inputStream1 = Resources.getResourceAsStream("mybatis-config.xml");
InputStream inputStream2 = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory1 = new
SqlSessionFactoryBuilder().build(inputStream1);
SqlSessionFactory sqlSessionFactory2 = new
SqlSessionFactoryBuilder().build(inputStream2);
SqlSession sqlSession1 = sqlSessionFactory1.openSession();
SqlSession sqlSession2 = sqlSessionFactory2.openSession();
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
System.out.println("!!!!!!!!!!!!!!第一次查询!!!!!!!!!!!!!!!!1");
User user1 = mapper1.findUserById(41);
System.out.println(user1);
sqlSession1.commit();
System.out.println("!!!!!!!!!!!!!!第二次查询!!!!!!!!!!!!!!!!1");
User user2 = mapper2.findUserById(41);
System.out.println(user2);
}
```
四、总结
3.1 不走一级缓存的情况
1)同一个sqlSession,但在两次相同条件的查询语句执行期间,进行了增删改
2)同一个sqlSession,但连续两次查询的语句条件不同
3)同一个sqlSession,但在两次相同条件的查询语句执行期间,手动清楚了缓存
4)不同的sqlsession,对应的不同的一级缓存
3.1 不走二级缓存的情况
1)同一个SqlSessionFactory,但在两次相同条件的查询语句执行期间,进行了增删改
2)同一个SqlSessionFactory,但连续两次查询的语句条件不同
3)不同的SqlSessionFactory,对应的不同的二级缓存
<cache></cache>