栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

1、一级缓存的使用 2、二级缓存 1、缓存的使用 2、缓存的属性 3、二级缓存的作用范围 4、整合第三方缓存

1、介绍

MyBatis 内置了一个强大的事务性查询缓存机制,它可以非常方便地

配置和定制。 为了使它更加强大而且易于配置,我们对 MyBatis 3 中的缓存实现进行了许多改进。

默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存。 要启用全局的二级缓存,只需要在你的 SQL 映射文件中添加一行:

1

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

映射语句文件中的所有 select 语句的结果将会被缓存。

映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。

缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来

清除不需要的缓存。

缓存不会定时进行刷新(也就是说,没有刷新间隔)。

缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。

缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以

安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

在进行配置的时候还会分为一级缓存和二级缓存:

一级缓存:线程级别的缓存,是本地缓存,sqlSession级别的缓存

二级缓存:全局范围的缓存,不止局限于当前会话

2、一级缓存的使用

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

 

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

  1. 一级缓存是sqlSession级别的缓存,如果在应用程序中只有开启了多个sqlsession,那么会造成缓存失效

1 @Test

2 public void test02(){

3 SqlSession sqlSession = sqlSessionFactory.openSession();

4 EmpDao mapper = sqlSession.getMapper(EmpDao.class);

5 List 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 list2 = mapper2.selectAllEmp();

13 for (Emp emp : list2) {

14 System.out.println(emp);

15 }

16 sqlSession.close();

17 sqlSession2.close();

18 }

2、在编写查询的sql语句的时候,一定要注意传递的参数,如果参数不一致,那么也不会缓存结果

3、如果在发送过程中发生了数据的修改,那么结果就不会缓存

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 }

2、二级缓存

二级缓存是全局作用域缓存,默认是不开启的,需要手动进行配置。

Mybatis提供二级缓存的接口以及实现,缓存实现的时候要求实体类实

现Serializable接口,二级缓存在sqlSession关闭或提交之后才会生效。

1、缓存的使用

步骤:

  1. 全局配置文件中添加如下配置:

1

2、需要在使用二级缓存的映射文件出使用标签标注

3、实体类必须要实现Serializable接口

1 @Test

2 public void test04(){

3 SqlSession sqlSession = sqlSessionFactory.openSession();

4 SqlSession sqlSession2 = sqlSessionFactory.openSession();

5 EmpDao mapper = sqlSession.getMapper(EmpDao.class);

6 EmpDao mapper2 = sqlSession2.getMapper(EmpDao.class);

7 Emp empByEmpno = mapper.findEmpByEmpno(1111);

8 System.out.println(empByEmpno);

9 sqlSession.close();

10

11 Emp empByEmpno1 = mapper2.findEmpByEmpno(1111);

12 System.out.println(empByEmpno1);

13 sqlSession2.close();

14 }

2、缓存的属性

eviction:表示缓存回收策略,默认是LRU

LRU:最近最少使用的,移除最长时间不被使用的对象

FIFO:先进先出,按照对象进入缓存的顺序来移除

SOFT:软引用,移除基于垃圾回收器状态和软引用规则的对象

WEAK:弱引用,更积极地移除基于垃圾收集器状态和弱引用规则的对象

flushInternal:刷新间隔,单位毫秒默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新

size:引用数目,正整数代表缓存最多可以存储多少个对象,太大容易导致内存溢出

readonly:只读,true/false

true:只读缓存,会给所有调用这返回缓存对象的相同实例,因此这些对象不能被修改。

false:读写缓存,会返回缓存对象的拷贝(序列化实现),这种方式比较安全,默认值

 

// 缓存查询的顺序是先查询二级缓存再查询一级缓存

1 @Test

2 public void test05(){

3 SqlSession sqlSession = sqlSessionFactory.openSession();

4 EmpDao mapper = sqlSession.getMapper(EmpDao.class);5 Emp empByEmpno = mapper.findEmpByEmpno(1111);

6 System.out.println(empByEmpno);

7 sqlSession.close();

8

9 SqlSession sqlSession2 = sqlSessionFactory.openSession();

10 EmpDao mapper2 = sqlSession2.getMapper(EmpDao.class);

11 Emp empByEmpno2 = mapper2.findEmpByEmpno(1111);

12 System.out.println(empByEmpno2);

13 Emp empByEmpno3 = mapper2.findEmpByEmpno(1111);

14 System.out.println(empByEmpno3);

15

16 Emp empByEmpno4 = mapper2.findEmpByEmpno(7369);

17 System.out.println(empByEmpno4);

18 Emp empByEmpno5 = mapper2.findEmpByEmpno(7369);

19 System.out.println(empByEmpno5);

20 sqlSession2.close();

21 }

需要本文章相关资料+代码,请关注并私信【想要】,免费获取
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/874482.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号