zoukankan      html  css  js  c++  java
  • mybatis缓存的设计

    继续用提问的方式来看Mybatis的缓存设计。

    1、Mybatis如何开启缓存

    Mybatis对查询结果进行缓存,所以缓存的对象为具体的Statement

    通过在Statement上是否使用缓存来启用。

    <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap"  fetchSize="5" statementType="PREPARED" useCache="true" >
    useCache默认值为true

    2、谁持有缓存?

     Mybatis中有两个对象持有缓存。

    CachingExecutor以及BaseExecutor

       

    CachingExecutor和SimpleExecutor的关系是持有的关系
    public class CachingExecutor implements Executor {
    
      private final Executor delegate;
      private final TransactionalCacheManager tcm = new TransactionalCacheManager();

    3、缓存何时开启?

      当开启Mapper级别的缓存时,缓存被开启

      缓存是一直开启的

    4、缓存何时被命中?

      5、缓存清空的时机

      ①数据库发生变更(update,insert,delete),即使事物没有提交,缓存失效

      ②对于相同命名空间Mapper的缓存,多个线程,并发使用相同Mapper的不同语句,任意一个执行事物提交,可导致缓存失效

      实际效果:

      缓存 会和Mysql的rr隔离级别一致,不会导致幻读(read uncommited)

      缓存 在不使用缓存的时候,有效

      验证缓存

              

      使用代码验证:

      两次查询,只访问了数据库1次.第二次不再请求数据库

        

      一次查询,一次更新(不提交),一次查询.缓存失效,出发了两次数据库查询。

          

      缓存的验证

      不配置缓存时,验证不同的sqlSesiion缓存是否通用

      触发2次数据库访问

        

       配置缓存参数

    <settings>
            <setting name="cacheEnabled" value="true"/>
        </settings>
      <cache/>

       

      结果出乎意料,缓存竟然没有命中。分析下原因:

       

      即使打开了缓存,首先也是保存在事物级别的缓存里,TransactionalCache里.

      只有当实物提交时,才会真正将缓存转移到delegate中(delegate是真正的Mapper之间公用的缓存)

      调整代码,后缓存生效。

      

      让人不理解的,出于什么目的,要commit后,再共享?

      如果在某一秒,有10个并发共同访问数据库。那他们会同时产生10个连接,并不会命中。  

    6、Mybatis缓存设计的目的

      简单,不配置也可以使用。用与在一个sqlSession中多次使用相同条件多次查询。

    7、Mybatis缓存设计的目的

      增强版,也支持事物级别的缓存,同时支持不同sqlSession之间的共享。扩大可缓存的可用性。

  • 相关阅读:
    c++跨平台技术学习(一)--使用公共的代码
    软件项目将死的27个征兆
    Java中的方法重载应用
    Java成员变量的初始化和在內存中的运行机制
    Java源文件结构和Java常用包
    细说Java访问控制符
    构造函数与this
    linux基础学习-6.3-DNS的配置文件
    linux基础学习-6.2-网卡配置文件
    linux基础学习-6.1-目录结构的特点
  • 原文地址:https://www.cnblogs.com/marioS/p/10353468.html
Copyright © 2011-2022 走看看