MyBatis03
# 2. MyBatis缓存
Mybatis中的一级缓存和二级缓存:
【一级缓存】
它指的是Mybatis中SqlSession
对象的缓存
当我们执行查询之后,查询的结果会同时存入到SqlSession为我们提供一块区域中。该区域的结构是一个Map。
当我们再次查询同样的数据,Mybatis会先去SqlSession中查询是否有,有的话直接拿出来用。
当SqlSession对象消失时,Mybatis的一级缓存也就消失了。
【二级缓存】
它指的是Mybatis中SqlSessionFactory对象的缓存。
由同一个SqlSessionFactory
对象创建的SqlSession
共享其缓存
二级缓存的使用步骤:
- 让Mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)
- 让当前的映射文件支持二级缓存(在IUserDao.xml中配置)
- 让当前的操作支持二级缓存(在select标签中配置)
# 一级缓存
MyBatis提供了缓存策略,通过缓存策略来减少数据库的查询次数,从而提高性能。 Mybatis中缓存分为一级缓存,二级缓存。
Mybatis的一级缓存的作用域是session
,是SqlSession级别的缓存,只要SqlSession没有flush
或close
,它就存在。
如果执行相同的SQL(相同语句和参数), MyBatis不进行执行SQL,而是从缓存中命中返回查询;如果命中直接返回,没有命中则执行SQL,从数据库中査询
一级缓存存在测试
我们可以发现,虽然在上面的代码中我们查询了两次,但最后只执行了一次数据库操作,这就是Mybatis提供给我们的一级缓起作用了。因为一级缓存的存在,导致第二次查询id为51的记录时,并没有发出SQL语句从数据库中查询数据,而是从一级缓存中查询。
一级缓存是SqlSession范围的缓存,当调用SqlSession的修改,添加,删除,commit(),close()等方法时,就会清空一级缓存。
一级缓存清空测试
当执行sqlSession.close()
后,再次获取sqlSession并查询id=51的User对象时,又重新执行了SQL 语句,从数据库进行了查询操作。
# 二级缓存
MyBatis 的二级缓存是mapper映射
级别的缓存,作用域是同一个mapper的namespace ,同一个namespace中查询SQL可以从缓存中命中,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
二级缓存测试
主配置文件SqlMapConfig.xml
中开启缓存(默认是开启的)
映射配置文件IUserDao.xml
中开启二级缓存
<!--开启user支持二级缓存-->
<cache/>
2
@Test
public void testFirstLevelCache(){
SqlSession sqlSession1 = factory.openSession();
IUserDao dao1 = sqlSession1.getMapper(IUserDao.class);
User user1 = dao1.findById(41);
System.out.println(user1);
//一级缓存消失
sqlSession1.close();
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);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
经过上面的测试,我们发现执行了两次查询,并且在执行第一次查询后,我们关闭了一级缓存,再去执行第二次查询时,我们发现并没有对数据库发出SQL语句,所以此时的数据就只能是来自于我们所说的二级缓存。