当用户多次查询相同的数据的时候,如果不需要缓存,那么每次都需要访问数据库,从而增加数据库的压力,当使用缓存之后,第一次将这些数据从数据库中查询,将查询的数据保存到缓存中,当用户再次查询相同的数据时,不用直接访问数据库进行查询,直接取缓存里面查询。这样可以减少网络连接和数据库查询带来的损耗,提高代码的查询效率,减少高并发访问带来的系统性能问题。
总的来说:查询一些不经常变化的数据,使用缓存可以提高查询效率,减少并发问题的发生。
Mybatis缓存主要分为一级缓存和二级缓存
Mybatis的一级缓存主要是SqlSession级别,默认是主动开启的。
一般来说参数和sql完全一样的情况下,第一次执行SQL语句,使用SqlSession查询数据库,Mybatis会把结果集存放到缓存中并返回结果,如果第二次一直到第n次执行SQL语句进行查询,那么SqlSession就会查询当前第一次缓存的数据直接返回,而不会再次请求数据库查询。
@Test
public void test01(){
SqlSession sqlSession=sqlSessionFactory.openSession();
try{
EmpMapper mapper=sqlSession.getMapper(EmpMapper.class);
List<Emp> list=mapper.selectAllEmp();
for(Emp emp:list){
System.out.println(emp);
}
System.out.println("=============");
List<Emp> list2=mapper.selectAllEmp();
for(Emp emp:list2){
System.out.println(emp);
}
}catch(Exception e){
e.printStackTrace();
}finally{
sqlSession.close();
}
复制代码
分析:虽然在上面的代码中我们查询了两次,但最后只执行了一次数据库操作,这就是Mybatis提供的一级缓存在起作用了。因为一级缓存的存在,导致第二次查询id为1的记录时,并没有发出sql语句从数据库中查询数据,而是从一级缓存中查询。
一级缓存是sqlSession级别的缓存,如果在应用程序中只有开启了多个sqlsession,那么会造成缓存失效
@Test
public void test02() {
SqlSession sqlSession = sqlSessionFactory.openSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
List<Emp> list = mapper.selectAllEmp();
for (Emp emp : list) {
System.out.println(emp);
}
System.out.println("================================");
SqlSession sqlSession2 = sqlSessionFactory.openSession();
EmpMapper mapper2 = sqlSession2.getMapper(EmpMapper.class);
List<Emp> list2 = mapper2.selectAllEmp();
for (Emp emp : list2) {
System.out.println(emp);
}
sqlSession.close();
sqlSession2.close();
}
复制代码
@Test
public void test03() {
SqlSession sqlSession = sqlSessionFactory.openSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Emp empByEmpno = mapper.findEmpByEmpno(1111);
System.out.println(empByEmpno);
System.out.println("================================");
empByEmpno.setEname("zhangsan");
int i = mapper.updateEmp(empByEmpno);
System.out.println(i);
System.out.println("================================");
Emp empByEmpno1 = mapper.findEmpByEmpno(1111);
System.out.println(empByEmpno1);
sqlSession.close();
}
复制代码
@Test
public void test03() {
SqlSession sqlSession = sqlSessionFactory.openSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Emp empByEmpno = mapper.findEmpByEmpno(1111);
System.out.println(empByEmpno);
System.out.println("================================");
System.out.println("手动清空缓存");
sqlSession.clearCache();
System.out.println("================================");
Emp empByEmpno1 = mapper.findEmpByEmpno(1111);
System.out.println(empByEmpno1);
sqlSession.close();
}
复制代码
特点:
失效情况:
二级缓存是namespace级别的缓存,他比一级缓存更加底层,一般情况下Mybatis是默认不开启二级缓存的。
如果需要开启二级缓存那么则需要实现一下两个条件
<settings>
<!--因为cacheEnabled的取值默认就为true,所以这一步可以省略不配置。为true代表开启二级缓存;为false代表不开启二级缓存。-->
<setting name="cacheEnabled" value="true"/>
</settings>
复制代码
<!--当前映射文件开启二级缓存-->
<cache></cache>
复制代码
@Test
public void test04() {
SqlSession sqlSession = sqlSessionFactory.openSession();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
EmpMapper mapper2 = sqlSession2.getMapper(EmpMapper.class);
Emp empByEmpno = mapper.findEmpByEmpno(1111);
System.out.println(empByEmpno);
sqlSession.close();
Emp empByEmpno1 = mapper2.findEmpByEmpno(1111);
System.out.println(empByEmpno1);
sqlSession2.close();
}
复制代码
@Test
public void test05() {
SqlSession sqlSession = sqlSessionFactory.openSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Emp empByEmpno = mapper.findEmpByEmpno(1111);
System.out.println(empByEmpno);
sqlSession.close();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
EmpMapper mapper2 = sqlSession2.getMapper(EmpMapper.class);
Emp empByEmpno2 = mapper2.findEmpByEmpno(1111);
System.out.println(empByEmpno2);
Emp empByEmpno3 = mapper2.findEmpByEmpno(1111);
System.out.println(empByEmpno3);
Emp empByEmpno4 = mapper2.findEmpByEmpno(7369);
System.out.println(empByEmpno4);
Emp empByEmpno5 = mapper2.findEmpByEmpno(7369);
System.out.println(empByEmpno5);
sqlSession2.close();
}
复制代码
特性:
实现:
<setting name="cacheEnabled" value="true"/>
失效:
<cache-ref namespace="com.mybatis.mapper.DeptMapper"/>
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。