- 二级缓存默认关闭,去Mapper文件中配置缓存并开启。当readOnly为false时,对应的pojo对象需要实现序列化接口来保证数据安全。二级缓存用map实现。
- 二级缓存是命名空间级别的,同一个命名空间的Mapper可以使用同一个二级缓存。
- 当会话关闭时,一级缓存存放至二级缓存中。
- 提交的增删改操作默认清空一级缓存和该命名空间的二级缓存。
- 当启用二级缓存,会话先去二级缓存查找,数据不存在则再去一级缓存查找。
(1)实体类
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Employee implements Serializable {
private Long id;
private String name;
private Long deptId;
private Department department;
}
(2)Mapper文件(此处采用默认的cache配置)
<?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.wsh.mapper.UserMapper">
<cache></cache>
<resultMap id="EmployeeResult" type="Employee">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="deptId" column="dept_id"/>
</resultMap>
<select id="selectEmployeeList" resultMap="EmployeeResult">
select
*
from
employee
where
id = #{id}
</select>
</mapper>
(3)接口文件
public interface UserMapper {
public List<Employee> selectEmployeeList(Long id);
}
(4)JAVA程序
public void test() throws IOException {
//读取配置文件创建SqlSession工厂
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//利用SqlSession工厂创建SqlSession实例
SqlSession sqlSession1 = sqlSessionFactory.openSession();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
try {
//利用SqlSession创建代理对象
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
mapper1.selectEmployeeList(1L);
sqlSession1.close();
mapper2.selectEmployeeList(1L);
sqlSession2.close();
}finally {
}
}
输出
2022-04-05 17:24:46,590 [main] DEBUG [com.wsh.mapper.UserMapper] - Cache Hit Ratio [com.wsh.mapper.UserMapper]: 0.0
2022-04-05 17:24:46,596 [main] DEBUG [com.wsh.mapper.UserMapper.selectEmployeeList] - ==> Preparing: select * from employee where id = ?
2022-04-05 17:24:46,620 [main] DEBUG [com.wsh.mapper.UserMapper.selectEmployeeList] - ==> Parameters: 1(Long)
2022-04-05 17:24:46,643 [main] DEBUG [com.wsh.mapper.UserMapper.selectEmployeeList] - <== Total: 1
2022-04-05 17:24:46,649 [main] WARN [org.apache.ibatis.io.SerialFilterChecker] - As you are using functionality that deserializes object streams, it is recommended to define the JEP-290 serial filter. Please refer to https://docs.oracle.com/pls/topic/lookup?ctx=javase15&id=GUID-8296D8E8-2B93-4B9A-856E-0A65AF9B8C66
2022-04-05 17:24:46,651 [main] DEBUG [com.wsh.mapper.UserMapper] - Cache Hit Ratio [com.wsh.mapper.UserMapper]: 0.5
当会话1未关闭时,对应的一级缓存则未存放至二级缓存
public void test() throws IOException {
//读取配置文件创建SqlSession工厂
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//利用SqlSession工厂创建SqlSession实例
SqlSession sqlSession1 = sqlSessionFactory.openSession();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
try {
//利用SqlSession创建代理对象
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
mapper1.selectEmployeeList(1L);
mapper2.selectEmployeeList(1L);
sqlSession1.close();
sqlSession2.close();
}finally {
}
}
输出
2022-04-05 17:27:41,820 [main] DEBUG [com.wsh.mapper.UserMapper] - Cache Hit Ratio [com.wsh.mapper.UserMapper]: 0.0
2022-04-05 17:27:41,826 [main] DEBUG [com.wsh.mapper.UserMapper.selectEmployeeList] - ==> Preparing: select * from employee where id = ?
2022-04-05 17:27:41,853 [main] DEBUG [com.wsh.mapper.UserMapper.selectEmployeeList] - ==> Parameters: 1(Long)
2022-04-05 17:27:41,871 [main] DEBUG [com.wsh.mapper.UserMapper.selectEmployeeList] - <== Total: 1
2022-04-05 17:27:41,872 [main] DEBUG [com.wsh.mapper.UserMapper] - Cache Hit Ratio [com.wsh.mapper.UserMapper]: 0.0
2022-04-05 17:27:41,901 [main] DEBUG [com.wsh.mapper.UserMapper.selectEmployeeList] - ==> Preparing: select * from employee where id = ?
2022-04-05 17:27:41,901 [main] DEBUG [com.wsh.mapper.UserMapper.selectEmployeeList] - ==> Parameters: 1(Long)
2022-04-05 17:27:41,902 [main] DEBUG [com.wsh.mapper.UserMapper.selectEmployeeList] - <== Total: 1
测试提交的增删改操作清空该命名空间二级缓存
public void test() throws IOException {
//读取配置文件创建SqlSession工厂
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//利用SqlSession工厂创建SqlSession实例
SqlSession sqlSession1 = sqlSessionFactory.openSession();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
SqlSession sqlSession3 = sqlSessionFactory.openSession();
try {
//利用SqlSession创建代理对象
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
UserMapper mapper3 = sqlSession3.getMapper(UserMapper.class);
mapper1.selectEmployeeList(1L);
sqlSession1.close();
mapper2.updateEmployee();
sqlSession2.commit();
sqlSession2.close();
mapper3.selectEmployeeList(1L);
sqlSession3.close();
}finally {
}
}
输出
2022-04-05 17:32:12,417 [main] DEBUG [com.wsh.mapper.UserMapper] - Cache Hit Ratio [com.wsh.mapper.UserMapper]: 0.0
2022-04-05 17:32:12,423 [main] DEBUG [com.wsh.mapper.UserMapper.selectEmployeeList] - ==> Preparing: select * from employee where id = ?
2022-04-05 17:32:12,451 [main] DEBUG [com.wsh.mapper.UserMapper.selectEmployeeList] - ==> Parameters: 1(Long)
2022-04-05 17:32:12,471 [main] DEBUG [com.wsh.mapper.UserMapper.selectEmployeeList] - <== Total: 1
2022-04-05 17:32:12,477 [main] DEBUG [com.wsh.mapper.UserMapper.updateEmployee] - ==> Preparing: update employee set id = 1 where id = 1
2022-04-05 17:32:12,480 [main] DEBUG [com.wsh.mapper.UserMapper.updateEmployee] - ==> Parameters:
2022-04-05 17:32:12,482 [main] DEBUG [com.wsh.mapper.UserMapper.updateEmployee] - <== Updates: 1
2022-04-05 17:32:12,483 [main] DEBUG [com.wsh.mapper.UserMapper] - Cache Hit Ratio [com.wsh.mapper.UserMapper]: 0.0
2022-04-05 17:32:12,483 [main] DEBUG [com.wsh.mapper.UserMapper.selectEmployeeList] - ==> Preparing: select * from employee where id = ?
2022-04-05 17:32:12,483 [main] DEBUG [com.wsh.mapper.UserMapper.selectEmployeeList] - ==> Parameters: 1(Long)
2022-04-05 17:32:12,484 [main] DEBUG [com.wsh.mapper.UserMapper.selectEmployeeList] - <== Total: 1
附:
(1)Mapper文件中的增删改查标签属性flushCache,表示执行完语句后是否清空一级缓存和二级缓存,增删改默认为true,查默认为false。
(2)Mapper文件中的select标签属性useCache,表示该select是否使用二级缓存。