zoukankan      html  css  js  c++  java
  • Mybatis一级缓存二级缓存使用总结

    Mybatis缓存简单使用

    MyBatis中的缓存分为一级缓存和二级缓存,一级缓存又被称为 SqlSession 级别的缓存,二级缓存又被称为表级缓存。

    一级缓存

    一级缓存是 SqlSession级别 的缓存。在操作数据库时需要构造 sqlSession 对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的 sqlSession 之间的缓存数据区域(HashMap)是互相不影响的。用一张图来表示一下一级缓存,其中每一个 SqlSession 的内部都会有一个一级缓存对象。

    在应用运行过程中,我们有可能在一次数据库会话中,执行多次查询条件完全相同的SQL,MyBatis 提供了一级缓存的方案优化这部分场景,如果是相同的SQL语句,会优先命中一级缓存,避免直接对数据库进行查询,提高性能

    一级缓存使用条件

    1. 必须是相同的SQL和参数
    2. 必须是相同的会话
    3. 必须是相同的namespace 即同一个mapper
    4. 必须是相同的statement 即同一个mapper 接口中的同一个方法
    5. 查询语句中间没有执行session.clearCache() 方法
    6. 查询语句中间没有执行 insert update delete 方法(无论变动记录是否与 缓存数据有无关系)

    一级缓存失效条件:

    1. 查询中途有增删改操作
    2. 不同SqlSession会话
    3. 同一SqlSession 使用不同的查询条件
    4. 使用 sqlSession.clearCache() 手动清理缓存

    二级缓存

    业务系统中存在很多的静态数据如,字典表、菜单表、权限表等,这些数据的特性是不会轻易修改但又是查询的热点数据。一级缓存针对的是同一个会话当中相同SQL,并不适合这情热点数据的缓存场景。为了解决这个问题引入了二级缓存,它脱离于会话之外。

    查询流程:二级缓存->一级缓存->数据库

    注意!!! 会话关闭之后才会触发缓存!

    图中namespace1 namespace2所在灰色区域,就是二级缓存!

    开启二级缓存方式:

    在mapper接口上,加@CacheNamespace注解

    //使用示例:
    @CacheNamespace()
    public interface LabelMapper {
        @Select("select * from t_label where id =#{id}")
        Label getById(Integer id);
    }
    

    @CacheNamespace注解属性说明

    @CacheNamespace(
            implementation = PerpetualCache.class, //  缓存实现 Cache接口 实现类
            eviction = LruCache.class,// 缓存算法
            flushInterval = 60000, // 刷新间隔时间 毫秒
            size = 1024,   // 最大缓存引用对象
            readWrite = true, // 是否可写
            blocking = false  // 是否阻塞
    )
    

    二级缓存使用条件:

    1. 当会话提交或关闭之后,才会填充二级缓存
    2. 必须是在同一个命名空间之下
    3. 必须是相同的statement 即同一个mapper接口中的同一个方法
    4. 必须是相同SQL语句和参数
    5. 如果readWrite = true(@CacheNamespace 注解的参数,默认就是true),实体对象必须实现Serializable接口

    二级缓存清除条件:

    1. 只有修改会话提交之后,才会执行清空操作
    2. 任何一种增删改操作,都会清空整个namespace中的缓存
    3. xml配置通过标签开启的缓存,是另外一个namespace的缓存,所以不会命中

    是否应该使用二级缓存?

    那么究竟应该不应该使用二级缓存呢?先来看一下二级缓存的注意事项:

    1. 缓存是以namespace为单位的,不同namespace下的操作互不影响。
    2. insert,update,delete操作会清空所在namespace下的全部缓存。
    3. 通常使用MyBatis Generator生成的代码中,都是各个表独立的,每个表都有自己的namespace
    4. 多表操作一定不要使用二级缓存,因为多表操作进行更新操作,一定会产生脏数据。

    如果你遵守二级缓存的注意事项,那么你就可以使用二级缓存。

    但是,如果不能使用多表操作,二级缓存不就可以用一级缓存来替换掉吗?而且二级缓存是表级缓存,开销大,没有一级缓存直接使用 HashMap 来存储的效率更高,所以二级缓存并不推荐使用

  • 相关阅读:
    HBase学习之路 (六)过滤器
    Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'userController' method
    Java简答题附答案
    Java习题附答案
    精选30道Java笔试题附答案分析
    Java数据结构面试题
    NoSuchBeanDefinitionException: No qualifying bean of type 'com.bj186.ssm.mapper.EmployeeMapper' available: expected at least 1 bean which qualifies as autowire candidate
    Caused by: java.lang.ClassNotFoundException: java.com.bj186.ssm.controller.UserController
    Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/dispatcher-servlet.xml]
    Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/config/spring/applicationContext.xml]
  • 原文地址:https://www.cnblogs.com/liuyingke/p/14863399.html
Copyright © 2011-2022 走看看