Mybatis缓存

Posted 一个年轻淫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis缓存相关的知识,希望对你有一定的参考价值。

资料来自
一级缓存和二级缓存
一级缓存和二级缓存
注解
mapper

一级缓存
一级缓存,是指SqlSession级别的缓存。一级缓存是一直开启的,在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的

public void TestCache01() throws IOException {
    SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
    SqlSession openSession = sqlSessionFactory.openSession();
    try {
        EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
        Employee emp01 = mapper.getEmpById(1);
        System.out.println(emp01);
        Employee emp02 =mapper.getEmpById(1);
        System.out.println(emp02);

        //从日志中可以看到sql查询只执行了一次,这就是mybatis的一级缓存
        //第二次与第一次查询语句相同,第二次查询返回值直接使用第一次的结果
        //从==判断地址也可以看出
        System.out.println(emp01==emp02);
     }finally {
        openSession.close();
     }
}

一级缓存失效

  • sqlSession不同
  • sqlSession相同,查询条件不同
  • sqlSession相同,两次查询之间执行了增删改操作
  • 如果SqlSession调用了close()方法
  • 如果SqlSession调用了clearCache()

技术图片

二级缓存
二级缓存,是指mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的,二级缓存默认是不开启的,因为需要配置

技术图片

基本配置步骤

  • 相关的bean需要序列化,为了将缓存数据取出执行反序列化操作,因为二级缓存数据存储介质多种多样,不一定只存在内存中,有可能存在硬盘中,如果我们要再取这个缓存的话,就需要反序列化了,所以mybatis中的pojo都去实现Serializable接口
public class Student implements Serializable {
    private String id;
    private String name;
    private String age;
    private String sex;
    ...
}
  • Mybatis缓存配置
// mybatis-config.xml
<configuration>
    <settings>
        <!-- 开启二级缓存 -->
        <setting name="cacheEnabled" value="true"/>
    </settings>
   ...
</configuration>
  • 注解模式使用
// CacheNamespace这个注解的参数可以自己查看
@CacheNamespace(blocking=true)
public interface UserMapper{
    @Select("select * from t_user where user_id = #{userId}")
    @Options(useCache = true)  // 针对每次查询都需要最新的数据 sql,要设置成 useCache=false,禁用二级缓存
    List<User> getUser(User u);
}
  • mapper模式使用
<?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="cn.mybatis.UserMapper">

? ? // eviction="FIFO"? FIFO(先进先出),LRU(最近使用次数最少的 被优先清除),LFU(最近一段时间内使用次数最少)
? ? // flushInterval="60000"? ? 自动刷新时间60s
? ? // size="512"? ? ?最多缓存512个引用对象
? ? // readOnly="true ?只读
? ? // type?指定自己实现的cache的路径,默认PerpetualCache
    <cache eviction="LRU" />

    // 针对每次查询都需要最新的数据 sql,要设置成 useCache=false,禁用二级缓存
    <select id="selectById" useCache="false">
        select * from test where id = #{id}
    </select >
</mapper>

上面的两个模式都是使用Mybatis默认的缓存类PerpetualCache,但是这个缓存是单服务器工作,无法实现分布式缓存,流行的两个代替默认缓存的插件是,ehcacheredis

如何看出有没有使用缓存
在日记打印区域里,没有执行sql就是调用的缓存

以上是关于Mybatis缓存的主要内容,如果未能解决你的问题,请参考以下文章

Mybatis关于复杂的SQL查询的处理&Mybatis的缓存机制

Mybatis 学习笔记总结

推荐学java——MyBatis高级

推荐学java——MyBatis高级

推荐学java——MyBatis高级

推荐学java——MyBatis高级