Mybatis-二级缓存

  1. 二级缓存默认关闭,去Mapper文件中配置缓存并开启。当readOnly为false时,对应的pojo对象需要实现序列化接口来保证数据安全。二级缓存用map实现。
  2. 二级缓存是命名空间级别的,同一个命名空间的Mapper可以使用同一个二级缓存。
  3. 当会话关闭时,一级缓存存放至二级缓存中。
  4. 提交的增删改操作默认清空一级缓存和该命名空间的二级缓存。
  5. 当启用二级缓存,会话先去二级缓存查找,数据不存在则再去一级缓存查找。

(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是否使用二级缓存。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值