一、查询缓存
查询缓存的使用,主要是为了提高查询访问速度。将用户对同一数据的重复查询过程简单化,不在每次均从数据库中查询获取结果数据,从而提高访问速度。
MyBatis 的查询缓存机制,根据缓存区的作用域与生命周期,可划分为两种:一级缓存和二级缓存。
MyBatis 查询缓存的作用域是根据映射文件 mapper 的 namespace 划分的,相同 namespace 的 mapper 查询数据存放在同一个缓存区域。不同的 namespace 下的数据互不干扰。无论是一级缓存还是二级缓存,都是按照 namespace 进行分别存放的。
但一、二级缓存的不同之处在于,SqlSession 一旦关闭,则 SQLSession 中的数据将不存在,即一级缓存就不存在,而二级缓存的生命周期会与整个应用同步,与 SQLSession 是否关闭无关。
简单的说,一级缓存是在同一线程(同一 SQLSession)间共享数据,而二级缓存是在不同线程间共享数据。
二、一级缓存的证明
三、从缓存中查找数据的依据
MyBatis 的查询依据是:Sql 的 id+SQL 语句。
Hibernate 的查依据是:查询结果对象的 id。
缓存的底层实现是一个 Map,Map 的 value 是查询结果。Map 的 key,即查询依据,使用的 ORM 架构不同,查询依据就不不同。
ORM:
- @Test
- public void test03() {
- Student student = dao.selectStudentById(197);
- System.out.println(student);
- //增删改操作都会清空一级缓存
- dao.insertStudent(new Student("阿古斯",26,96.5));
- Student student1 = dao.selectStudentById(197);
- System.out.println(student1);
- }
输出:
- 0 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentById - ==> Preparing: select id,name,age,score from student where id=?
- 75 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentById - ==> Parameters: 197(Integer)
- 116 [main] TRACE com.jmu.dao.IStudentDao.selectStudentById - <== Columns: id, name, age, score
- 116 [main] TRACE com.jmu.dao.IStudentDao.selectStudentById - <== Row: 197, 明明, 19, 87.9
- 120 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentById - <== Total: 1
- Student [id=197, name=明明, score=87.9, age=19]
- 121 [main] DEBUG com.jmu.dao.IStudentDao.insertStudent - ==> Preparing: insert into student(name,age,score) values(?,?,?)
- 122 [main] DEBUG com.jmu.dao.IStudentDao.insertStudent - ==> Parameters: 阿古斯(String), 26(Integer), 96.5(Double)
- 123 [main] DEBUG com.jmu.dao.IStudentDao.insertStudent - <== Updates: 1
- 124 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentById - ==> Preparing: select id,name,age,score from student where id=?
- 124 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentById - ==> Parameters: 197(Integer)
- 124 [main] TRACE com.jmu.dao.IStudentDao.selectStudentById - <== Columns: id, name, age, score
- 125 [main] TRACE com.jmu.dao.IStudentDao.selectStudentById - <== Row: 197, 明明, 19, 87.9
- 125 [main] DEBUG com.jmu.dao.IStudentDao.selectStudentById - <== Total: 1
- Student [id=197, name=明明, score=87.9, age=19]
- 结论:增删改操作都会清空一级缓存,无论是否提交
五、内置二级缓存
首先,证明二级缓存的存在。
因为 SqlSession 一旦关闭,一级缓存就不存在,而二级缓存的生命周期会与整个应用同步,与 SQLSession 是否关闭无关。
开启内置的二级缓存步骤:
缓存命中率:
- 【DEBUG】Cache Hit Ratio:0.5
(2)增删改对二级缓存的影响
上面的例子说明:
- public void test01() {
- sqlSession = MybatisUtils.getSqlSession();
- dao = sqlSession.getMapper(IStudentDao.class);
- Student student = dao.selectStudentById(197);
- System.out.println(student);
- sqlSession.close();
- sqlSession = MybatisUtils.getSqlSession();
- dao = sqlSession.getMapper(IStudentDao.class);
- dao.insertStudent(new Student("", 0, 0));
- Student student1 = dao.selectStudentById(197);
- System.out.println(student1);
- }
(3)二级缓存的配置
(4)二级缓存的关闭
(1)全局关闭
- <settings>
- <!-- 关闭二级缓存 -->
- <setting name="cacheEnabled" value="false" />
- </settings>
(2)局部关闭
(5)二级缓存的使用原则
来源: https://www.cnblogs.com/hoje/p/8117575.html