Mybatis-06【MyBatis基于XML的详细使用——缓存】

           MyBatis基于XML的详细使用——缓存
                    1.介绍
                    2.一级缓存的使用
                    3.二级缓存
                        1. 缓存的使用
                        2. 缓存的属性
                        3. 二级缓存的作用范围
                        4. 整合第三方缓存

1、介绍

MyBatis 内置了一个强大的事务性查询缓存机制,它可以非常方便地 配置和定制。 为了使它更加强大而且易于配置,我们对 MyBatis 3 中的缓存实 现进行了许多改进。
默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据 进行缓存。 要启用全局的二级缓存,只需要在你的 SQL 映射文件中添加一行:

1 <cache/>

当添加上该标签之后,会有如下效果:

  1. 映射语句文件中的所有 select 语句的结果将会被缓存。
  2. 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
  3. 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来 清除不需要的缓存。
  4. 缓存不会定时进行刷新(也就是说,没有刷新间隔)。
  5. 缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。
  6. 缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以 安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

在进行配置的时候还会分为一级缓存和二级缓存:
一级缓存:线程级别的缓存,是本地缓存,sqlSession级别的缓存
二级缓存:全局范围的缓存,不止局限于当前会话

2、一级缓存的使用

一级缓存是sqlsession级别的缓存,默认是存在的。在下面的案例 中,大家发现我发送了两个相同的请求,但是sql语句仅仅执行了一次,那么就 意味着第一次查询的时候已经将结果进行了缓存。

1 @Test 
2 public void test01() { 
3
4 SqlSession sqlSession = sqlSessionFactory.openSession(); 
5 try { 
6 EmpDao mapper = sqlSession.getMapper(EmpDao.class); 
7 List<Emp> list = mapper.selectAllEmp(); 
8 for (Emp emp : list) { 
9 System.out.println(emp); 
10 } 
11 System.out.println("‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐"); 
12 List<Emp> list2 = mapper.selectAllEmp(); 
13 for (Emp emp : list2) { 
14 System.out.println(emp); 
15 } 
16 } catch (Exception e) { 
17 e.printStackTrace(); 
18 } finally { 
19 sqlSession.close(); 
20 } 
21 }

在大部分的情况下一级缓存是可以的,但是有几种特殊的情况会造成 一级缓存失效:

  1. 一级缓存是sqlSession级别的缓存,如果在应用程序中只有开启了多个 sqlsession,那么会造成缓存失效
1 @Test 
2 public void test02(){ 
3 SqlSession sqlSession = sqlSessionFactory.openSession(); 
4 EmpDao mapper = sqlSession.getMapper(EmpDao.class); 
5 List<Emp> list = mapper.selectAllEmp(); 
6 for (Emp emp : list) {7 System.out.println(emp); 
8 } 
9 System.out.println("================================"); 
10 SqlSession sqlSession2 = sqlSessionFactory.openSession(); 
11 EmpDao mapper2 = sqlSession2.getMapper(EmpDao.class); 
12 List<Emp> list2 = mapper2.selectAllEmp(); 
13 for (Emp emp : list2) { 
14 System.out.println(emp); 
15 } 
16 sqlSession.close(); 
17 sqlSession2.close(); 
18 } 
  1. 在编写查询的sql语句的时候,一定要注意传递的参数,如果参数不一致,那 么也不会缓存结果
  2. 如果在发送过程中发生了数据的修改,那么结果就不会缓存
1 @Test 
2 public void test03(){ 
3 SqlSession sqlSession = sqlSessionFactory.openSession(); 
4 EmpDao mapper = sqlSession.getMapper(EmpDao.class); 
5 Emp empByEmpno = mapper.findEmpByEmpno(1111); 
6 System.out.println(empByEmpno); 
7 System.out.println("================================"); 
8 empByEmpno.setEname("zhangsan"); 
9 int i = mapper.updateEmp(empByEmpno); 
10 System.out.println(i); 
11 System.out.println("================================"); 
12 Emp empByEmpno1 = mapper.findEmpByEmpno(1111); 
13 System.out.println(empByEmpno1); 
14 sqlSession.close(); 
15 } 
  1. 在两次查询期间,手动去清空缓存,也会让缓存失效
1 @Test 
2 public void test03(){ 
3 SqlSession sqlSession = sqlSessionFactory.openSession(); 
4 EmpDao mapper = sqlSession.getMapper(EmpDao.class); 
5 Emp empByEmpno = mapper.findEmpByEmpno(1111); 
6 System.out.println(empByEmpno); 
7 System.out.println("================================"); 
8 System.out.println("手动清空缓存");9 sqlSession.clearCache(); 
10 System.out.println("================================"); 
11 Emp empByEmpno1 = mapper.findEmpByEmpno(1111); 
12 System.out.println(empByEmpno1); 
13 sqlSession.close(); 
14 } 

今天就分享到这里了,文章后续及更多java学习资料,关注我,免费领取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值