组团学

MyBatis缓存

阅读 (874300)

1、MyBatis缓存概述

1.1、什么是MyBatis缓存

像大多数的持久化框架一样,MyBatis 也提供了缓存策略,通过缓存策略来减少数据库的查询次数,从而提高性能。

1.2、MyBatis缓存分类

MyBatis 中缓存分为一级缓存,二级缓存。

默认情况下,只有一级缓存(SqlSession级别的缓存,也称为本地缓存)开启。

二级缓存需要手动开启和配置,他是基于namespace级别的缓存。

为了提高扩展性。MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存

image-20200330115340445

1.3、前期准备

创建一个新的项目mb004

2、MyBatis一级缓存

一级缓存是SqlSession,只要SqlSession没有flush和close,SqlSession都是存在的。

2.1、一级缓存验证

完成学生信息查询

@Test public void findById(){ Students students=studentsDao.findById(2); System.out.println("第一次查询:"+students); Students students1=studentsDao.findById(2); System.out.println("第二次查询:"+students1); }

image-20200330110457904

2.2、一级缓存业务

一级缓存是 SqlSession 范围的缓存,当调用 SqlSession 的修改,添加,删除,commit(),close()等方法时,就会清空一级缓存。

@Test public void findById(){ Students students=studentsDao.findById(2); System.out.println("第一次查询:"+students); students.setSname("你好"); students.setSage(19); studentsDao.updateStudents(students); Students students1=studentsDao.findById(2); System.out.println("第二次查询:"+students1); System.out.println(students==students1); }

image-20200330111251898

执行步骤:

第一次查询id为2的学生信息,先去缓存中找,如果没有去查询数据库

修改学生信息,执行了一次commit,一级缓存清理

第二次查询id为2的学生信息,也去缓存中找,如果没有去查询数据库

2.3、一级缓存清理

clearCache():清除一级缓存

@Test public void findById(){ Students students=studentsDao.findById(2); System.out.println("第一次查询:"+students); session.clearCache();//清除一级缓存的方法 Students students1=studentsDao.findById(2); System.out.println("第二次查询:"+students1); System.out.println(students==students1); }

image-20200330111752834

3、MyBatis二级缓存

二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的。

image-20200330115340445

3.1、二级缓存开启

3.1.1、配置SqlMapConfig.xml

<settings> <!-- 开启二级缓存的支持 --> <setting name="cacheEnabled" value="true"/> </settings>

cacheEnabled 默认值为 true。为 true 代表开启二级缓存;为false 代表不开启二级缓存。

3.1.2、配置ISudentsDao.xml

格式: <cache></cache> 格式: useCache属性:true|false useCache=”true”代表当前要使用二级缓存,如果不使用二级缓存可以设置为 false。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.tyschool.mb004.students.dao.IStudentsDao"> <cache></cache> <select id="findById" resultType="Students" parameterType="int" useCache="true"> select * from students where sid=#{sid} </select> <update id="updateStudents" parameterType="Students"> update students set sname=#{sname},ssex=#{ssex},sage=#{sage},cid=#{cid} where sid=#{sid} </update> </mapper>

注意:

配置中大部分属性都有默认配置,不用配置也可使用。

<cache eviction="LRU" flushInterval="10000" size="1024" readOnly="true"/>

的属性:

**eviction:**代表的是缓存收回策略,有一下策略:

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

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

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

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

**flushInterval:**刷新间隔时间,单位为毫秒,默认是当sql执行的时候才回去刷新。

**size:**引用数目,一个正整数,代表缓存最多可以存储多少对象,不宜设置过大,过大会造成内存溢出。

**readOnly:**只读,意味着缓存数据只能读取,不能修改,这样设置的好处是我们可以快速读取缓存,去诶但是我们没有办法修改缓存。默认值为false,不允许我们修改。

3.2、二级缓存测试

@Test public void findById(){ session=factory.openSession(); studentsDao=session.getMapper(IStudentsDao.class); Students students=studentsDao.findById(2); System.out.println("第一次查询:"+students); session.close(); session=factory.openSession(); studentsDao=session.getMapper(IStudentsDao.class); Students students1=studentsDao.findById(2); System.out.println("第二次查询:"+students1); System.out.println(students==students1); session.close(); }

image-20200330115051919

需要 登录 才可以提问哦