• mybatis 一级缓存和二级缓存


    mybatis 缓存示例图:

    mybatis 一级缓存:

       第一次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,如果没有,从数据库查询用户
    信息。
    得到用户信息,将用户信息存储到一级缓存中。

      如果sqlsSession.去执行commit 操作(执行插入、更新、删除),清空sqlsession.中的一级缓存,这样做的目的为了
    让缓存中存储的是最新的信息,避免脏读。

      第二次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,缓存中有,直接从缓存中获取
    用户信息。 
     
    在源代码中:一级缓存是一个保存在一个hashMap当中。key:是由sql语句、sql参数、调用的mapper和系统生成的一些code等数据组成,每一次执行sql代码的时候,都会拼接key,
    若key相同就从map中取,否则去数据库查询。
    key:-1609322146:3847437185:com.ssm.dao.EmpMapper.selectByPrimaryKey:0:2147483647:select

    EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO
    from EMP
    where EMPNO = ?:7369

     
    一级缓存的应用
       正式开发,是将mybatis 和spring 进行整合开发,事务控制在service中。
    一个service 方法中包括很多mapper方法调用。
    service{
      //开始执行时,开启事务,创建Sqlsession 对象
      //第一次调用mapper.的方法findUserByld(1)
      //第二次调用mapper.的方法findUserByld(1),从一级缓存中取数据
      //方法结束,sqlsession关闭
    }
    如果是执行两次service 调用查询相同的用户信息,不走一级缓存,因为session方法结束,sqlsession就关闭,一
    级缓存就清空。
     
     二级缓存原理

    首先开启mybatis.的二级缓存。

    sqlSession1去查询用户id 为1的用户信息,查询到用户信息会将查询数据存储到二级缓存中。

    如果SqlSession3 去执行相同mapper.下sgl; 执行commit 提交,清空该mapper.下的二级缓存区域的数据。

    sqlSession2 去查询用户id为1的用户信息,去缓存中找是否存在数据,如果存在直接从缓存中取出数据。

    二级缓存与一级缓存区别,二级缓存的范围更大,多个sqlsession可以共享一个UserMapper.的二级缓存区域。UserMapper.有一个二级缓存区域(按namespace分)
    其它mapper.也有自己的二级缓存区域(按namespace分)。

    每一个namespace 的mapper.都 有一个二缓存 区域,两个mapper的namespace 如果相同,这两个mapper.执行sql
    查询到数据将存在相同的二级缓存区域中。

    配置步骤:在mybatis配置文件中加入:

    在要缓存的Mapper中加入

    假如说,已开启二级缓存的Mapper中有个statement要求禁用怎么办,那也不难,只需要在statement中设置useCache=false就可以禁用当前select语句的二级缓存,也就是每次都会生成sql去查询,ps:默认情况下默认是true,也就是默认使用二级缓存

     

    在mapper的同一个namespace中,如果有其他insert、update、delete操作后都需要执行刷新缓存操作,来避免脏读。这时我们只需要设置statement配置中的flushCache=“true“属性,就会默认刷新缓存,相反如果是false就不会了。

     

    设置时间间隔来刷新缓存。我们在mapper映射文件中添加<cache/>来表示开启缓存,那接下来,只需要我们在配置flushinterval(刷新间隔)就哦了:
     

    flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。 size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的可用内存资源数目。默认值是1024。 readOnly(只读)属性可以被设置为true或false。只读的缓存会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false。

    回收测量

    可用的收回策略有, 默认的是 LRU:

    1.      LRU – 最近最少使用的:移除最长时间不被使用的对象。

    2.      FIFO – 先进先出:按对象进入缓存的顺序来移除它们。

    3.      SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。

    4.      WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

     

    mybatis引入ehcache作为二级缓存

     pom.xml 导入相关的jar包

    <!-- https://mvnrepository.com/artifact/org.ehcache/ehcache -->
          <dependency>
              <groupId>org.ehcache</groupId>
              <artifactId>ehcache</artifactId>
              <version>3.5.2</version>
          </dependency>
    
          <!-- https://mvnrepository.com/artifact/org.mybatis.caches/mybatis-ehcache -->
          <dependency>
              <groupId>org.mybatis.caches</groupId>
              <artifactId>mybatis-ehcache</artifactId>
              <version>1.1.0</version>
          </dependency>

    加入ehcache的配置文件ehcache.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <ehcache>
        <diskStore path="d:/ehcache/"></diskStore>
    
        <!-- 默认缓存配置 -->
        <defaultCache
                maxElementsInMemory="10000"
                eternal="false"
                timeToIdleSeconds="120"
                timeToLiveSeconds="120"
                overflowToDisk="true"
        />
    
        <!-- User缓存配置 -->
        <cache
                name="User"
                maxElementsInMemory="10000"
                eternal="false"
                timeToIdleSeconds="300"
                timeToLiveSeconds="600"
                overflowToDisk="true"
        />
    
    </ehcache>

    在mapper文件中的cache标签下添加type属性。

    进入EhcacheCache类,发现它继承了Cache接口。其实:mybatis中引入ehcache就是引入继承了chache接口的类

    mybatis中的原生二级缓存,不支持多表联查的缓存,所以需要引入ehcache等缓存插件,这样做的好处还可以实现分布式和集群。

    应用场景.
    对于访问多的查询请求且用户对查询结果实时性要求不高,此时可采用mybatis 二级缓
    存技术降低数据库访问量,提高访问速度,业务场景比如: 耗时较高的统计分析sql、电话
    账单查询sql等。
    实现方法如下:通过设置刷新间隔时间,由mybatis 每隔一段时间自动清空缓存,根据
    数据变化频率设置缓存刷新间隔flushInterval,比如设置为30 分钟、60 分钟、24小时等,
    根据需求而定。
    局限性.
    mybatis 二级缓存对细粒度的数据级别的缓存实现不好,比如如下需求: 对商品信息进
    行缓存,由于商品信息查询访问量大,但是要求用户每次都能查询最新的商品信息,此时如
    果使用mybatis 的二级缓存就无法实现当一个商品变化时只刷新该商品的缓存信息而不刷新
    其它商品的信息,因为mybaits 的二级缓存区域以mapper 为单位划分,当一个商品信息变
    化会将所有商品信息的缓存数据全部清空。解决此类问题需要在业务层根据需求对数据有针
    对性缓存。

  • 相关阅读:
    自信你就赢了
    记移动开发者大会中国(MDCC)
    Android Google Map V2想说爱你不容易
    关于用好Android资料的一些总结和反思
    按钮添加四种点击事件
    Google的可穿戴设备Android Wear抢先看
    跟上潮流,做个微信开发者平台
    我也开始玩儿硬件——树莓派入门
    我也来自己做刷机包
    简单谈谈eclipse下搭建PhoneGap环境来开发Android程序
  • 原文地址:https://www.cnblogs.com/getchen/p/8603578.html
Copyright © 2020-2023  润新知