mybatis缓存之二级缓存

二级缓存(全局缓存):基于namespace级别的缓存,一个namespace对应一个二级缓存。

工作机制:

  • 一个会话,查询一条数据,这条数据会放在当前会话的一级缓存中;
  • 如果会话关闭,该会话对应的一级缓存就消失了;
  • 可以使用二级缓存将保存之前的一级缓存,新的会话要查询相同的信息就可以从二级缓存中获取。

使用过程:

  • 开启二级缓存全局配置;
  • <setting name="cacheEnabled" value="true"/>
  • 在mapper.xml配置使用二级缓存<cache></cache>
  • POJO需要实现序列化接口
<setting name="lazyLoadingEnabled" value="true"/>
mapper namespace="com.gong.mybatis.dao.EmployeeMapper">
    cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024">
        <!-- 
            eviction:缓存的回收策略,默认LRU
            flushInterval:缓存刷新间隔,默认不清空,可以设置一个毫秒值
            readOnly:只读为true,所有从缓存中获取操作都是只读操作,不会修改数据,直接将数据在缓存中的引用交给用户;
                     非只读,获取的数据可能会被修改,会利用序列化&反序列化的技术克隆一份新的数据,安全,但速度慢。
            size:缓存存放多少元素
            type:指定自定义缓存的全类名,实现Cache接口即可
         -->
    </cache>

    ......
mapper>
public class Employee implements Serializable

测试:

package com.gong.mybatis.test;

import java.io.IOException;
 java.io.InputStream;
 java.util.ArrayList;
 java.util.Arrays;
 java.util.HashMap;
 java.util.List;
 java.util.Map;

 org.apache.ibatis.io.Resources;
 org.apache.ibatis.session.SqlSession;
 org.apache.ibatis.session.SqlSessionFactory;
 org.apache.ibatis.session.SqlSessionFactoryBuilder;
 org.junit.Test;

 com.gong.mybatis.bean.Department;
 com.gong.mybatis.bean.Employee;
 com.gong.mybatis.dao.EmployeeMapper;
 com.gong.mybatis.mapper.EmployeeMapperDynamicSql;

class TestMybatis4 {
    
    public SqlSessionFactory getSqlSessionFactory() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream is = Resources.getResourceAsStream(resource);
        return new SqlSessionFactoryBuilder().build(is);
    }

    @Test
    void test()  IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        SqlSession openSession = sqlSessionFactory.openSession();
        SqlSession openSession2 = sqlSessionFactory.openSession();
        
        try {
            EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.);
            EmployeeMapper mapper2 = openSession2.getMapper(EmployeeMapper.);
            Employee em = mapper.getEmpById(1);
            System.out.println(em);
            openSession.close();
            Employee em2 = mapper2.getEmpById(1);
            System.out.println(em2);
            openSession.close();
        } finally {
            // TODO: handle finally clause
            
        }
            
    }
    
}

输出:

DEBUG 01-22 10:59:28,726 Cache Hit Ratio [com.gong.mybatis.dao.EmployeeMapper]: 0.0  (LoggingCache.java:62) 
DEBUG 01-22 10:59:29,055 ==>  Preparing: select id,last_name lastName,email,gender from tbl_employee where id = ?   (BaseJdbcLogger.java:145) 
DEBUG 01-22 10:59:29,102 ==> Parameters: 1(Integer)  (BaseJdbcLogger.java:145) 
DEBUG 01-22 10:59:29,148 ==      Total: 1  (BaseJdbcLogger.java:145) 
Employee [id=1,lastName=dema,1)">genderemail=dema@qq.com,1)">dept=null]
DEBUG 01-22 10:59:29,242 Cache Hit Ratio [com.gong.mybatis.dao.EmployeeMapper]: 0.5  (LoggingCache.java:62) 
Employee [id=null]

需要注意是要在第一个会话结束之后要先关闭,否则如果在最后一起关闭,就变成一级缓存的情况了。

和缓存相关的设置:

  • cacheEnabled:true为开启二级缓存
  • 每个select标签都有useCache属性,该属性默认为true,如果置为false,表明不使用二级缓存
  • 每个增删改标签都有flushCache属性,该属性默认为true,执行后清除缓存。(一级缓存、二级缓存都会被清空)
  • 每个select标签也有flushCache属性,默认为false
  • sqlSession.clearCache()只清除一级缓存
  • localCacheScope设置:本地缓存作用域,取SESSION表明一级缓存:当前会话的所有数据保存在会话缓存中。取STATEMENT可以禁用一级缓存。

相关文章

1.pom.xml引入依赖 &lt;dependency&gt; &lt;gro...
&lt;?xml version=&quot;1.0&quot; encoding=&a...
准备工作 ① 创建数据库&amp;数据表 ## 创建数据库 CREA...
MyBatis逆向工程是指根据数据库表结构自动生成对应的实体类、...
MyBatis获取参数值的两种方式:${}和#{} ${}的本质就是字符串...
resultMap作用是处理数据表中字段与java实体类中属性的映射关...