• java学习day46-Mybatis缓存机制


    mybatis-缓存

    一级缓存

       Mybatis对缓存提供支持,但是在没有配置的默认情况下,它只开启一级缓存,一级缓存只是相对于同一个SqlSession而言。所以在参数和SQL完全一样的情况下,我们使用同一个SqlSession对象调用一个Mapper方法,往往只执行一次SQL,因为使用SelSession第一次查询后,MyBatis会将其放在缓存中,以后再查询的时候,如果没有声明需要刷新,并且缓存没有超时的情况下,SqlSession都会取出当前缓存的数据,而不会再次发送SQL到数据库。

    1593939013954

    1、一级缓存的生命周期有多长?

    a、MyBatis在开启一个数据库会话时,会 创建一个新的SqlSession对象,SqlSession对象中会有一个新的Executor对象。Executor对象中持有一个新的PerpetualCache对象;当会话结束时,SqlSession对象及其内部的Executor对象还有PerpetualCache对象也一并释放掉。
    
    b、如果SqlSession调用了close()方法,会释放掉一级缓存PerpetualCache对象,一级缓存将不可用。
    
    c、如果SqlSession调用了clearCache(),会清空PerpetualCache对象中的数据,但是该对象仍可使用。
    
    d、SqlSession中执行了任何一个update操作(update()、delete()、insert()) ,都会清空PerpetualCache对象的数据,但是该对象可以继续使用
    

    2、怎么判断某两次查询是完全相同的查询?

    mybatis认为,对于两次查询,如果以下条件都完全一样,那么就认为它们是完全相同的两次查询。
    2.1 传入的statementId
    2.2 查询时要求的结果集中的结果范围
    2.3. 这次查询所产生的最终要传递给JDBC java.sql.Preparedstatement的Sql语句字符串(boundSql.getSql() )
    2.4 传递给java.sql.Statement要设置的参数值
    
    

    二级缓存:

    MyBatis的缓存机制整体设计以及二级缓存的工作模式

    1593938747786

    MyBatis 内置了一个强大的事务性查询缓存机制,它可以非常方便地配置和定制。 为了使它更加强大而且易于配置,我们对 MyBatis 3 中的缓存实现进行了许多改进。

    默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存。 要启用全局的二级缓存,只需要在你的 SQL 映射文件(mapper)中添加一行:

    <cache/>
    

    基本上就是这样。这个简单语句的效果如下:

    • 映射语句文件中的所有 select 语句的结果将会被缓存。
    • 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
    • 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
    • 缓存不会定时进行刷新(也就是说,没有刷新间隔)。
    • 缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。
    • 缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

    提示:缓存只作用于 cache 标签所在的映射文件中的语句。如果你混合使用 Java API 和 XML 映射文件,在共用接口中的语句将不会被默认缓存。你需要使用 @CacheNamespaceRef 注解指定缓存作用域。

    这些属性可以通过 cache 元素的属性来修改。比如:

    <cache
      eviction="FIFO"
      flushInterval="60000"
      size="512"
      readOnly="true"/>
    <!--可以通过设置useCache来规定这个sql是否开启缓存,ture是开启,false是关闭-->
    <select id="selectAllStudents" resultMap="studentMap" useCache="true">
        SELECT id, name, age FROM student
    </select>
    

    ​ 这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突。

    可用的清除策略有:

    • LRU – 最近最少使用:移除最长时间不被使用的对象。
    • FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
    • SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。
    • WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。

    默认的清除策略是 LRU。

    flushInterval(刷新间隔)属性可以被设置为任意的正整数,设置的值应该是一个以毫秒为单位的合理时间量。 默认情况是不设置,也就是没有刷新间隔,缓存仅仅会在调用语句时刷新。

    size(引用数目)属性可以被设置为任意正整数,要注意欲缓存对象的大小和运行环境中可用的内存资源。默认值是 1024。

    readOnly(只读)属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓存对象的相同实例。 因此这些对象不能被修改。这就提供了可观的性能提升。而可读写的缓存会(通过序列化)返回缓存对象的拷贝。 速度上会慢一些,但是更安全,因此默认值是 false。

    提示: 二级缓存是事务性的。这意味着,当 SqlSession 完成并提交时,或是完成并回滚,但没有执行 flushCache=true 的 insert/delete/update 语句时,缓存会获得更新。

    在 mybatis-config.xml中开启二级缓存

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <settings>
            <!--这个配置使全局的映射器(二级缓存)启用或禁用缓存-->
            <setting name="cacheEnabled" value="true" />
            .....
        </settings>
        ....
    </configuration>
    
  • 相关阅读:
    Chapter 4: Using Custom Property Types
    Chapter 2: Connecting to C++ Methods and Signals
    C++ Extensions: Reference examples
    qt exec
    qt component desktop
    Qt事件处理机制
    Tutorial: Writing QML Extensions with C++
    label for
    (一) HTTP 1.1支持的状态代码
    一些常用的特殊字符
  • 原文地址:https://www.cnblogs.com/liqbk/p/13246719.html
Copyright © 2020-2023  润新知