mybatis二级缓存的作用范围_java缓存机制

mybatis二级缓存的作用范围_java缓存机制应用场景:      对于访问多的查询请求且用户对查询结果实时性要求不高,此时可采用mybatis二级缓存技术降低数据库访问量,提高访问速度,业务场景比如:耗时较高的统计分析sql、电话账单查询sql等。      实现方法如下:通过设置刷新间隔时间,由mybatis每隔一段时间自动清空缓存,根据数据变化频率设置缓存刷新间隔flushInterval,比如设置为30分钟、6…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

应用场景:
           对于访问多的查询请求且用户对查询结果实时性要求不高,此时可采用mybatis二级缓存技术降低数据库访问量,提高访问速度,业务场景比如:耗时较高的统计分析sql、电话账单查询sql等。
           实现方法如下:通过设置刷新间隔时间,由mybatis每隔一段时间自动清空缓存,根据数据变化频率设置缓存刷新间隔flushInterval,比如设置为30分钟、60分钟、24小时等,根据需求而定。

局限性:
           mybatis二级缓存对细粒度的数据级别的缓存实现不好,比如如下需求:对商品信息进行缓存,由于商品信息查询访问量大,但是要求用户每次都能查询最新的商品信息,
           此时如果使用mybatis的二级缓存就无法实现当一个商品变化时只刷新该商品的缓存信息而不刷新其它商品的信息,因为mybaits的二级缓存区域以mapper为单位划分,
           当一个商品信息变化会将所有商品信息的缓存数据全部清空。解决此类问题需要在业务层根据需求对数据有针对性缓存。
      缓存都是实现了Cache这个接口…..

如何开启 二级缓存,步骤如下:
        1.导入ehcache相关jar包  (ehcache: 缓存插件,插件:就是对现有应用软件功能的一个扩展)        

      ehcache-core-2.6.5.jar
        mybatis-ehcache-1.1.0.jar

      <dependency>
          <groupId>net.sf.ehcache</groupId>
          <artifactId>ehcache-core</artifactId>
          <version>2.6.6</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>

        2,开启mybatis的二级缓存          

在mybatis核心配置文件mybatis-config.xml中加入

            <settings>
                <!-- 开启二级缓存 -->
                <setting name="cacheEnabled" value="true" />
            </settings>

      3.在classpath下加入ehcache.xml文件
          

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">

    <diskStore path="java.io.tmpdir"/>

	<defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="true"
            maxElementsOnDisk="10000000"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"
            />
			
	<!--
		默认缓存配置,
		以下属性是必须的:
			name :cache的标识符,在一个CacheManager中必须唯一。
			maxElementsInMemory : 在内存中缓存的element的最大数目。
			maxElementsOnDisk : 在磁盘上缓存的element的最大数目。
			eternal : 设定缓存的elements是否有有效期。如果为true,timeouts属性被忽略。
			overflowToDisk : 设定当内存缓存溢出的时候是否将过期的element缓存到磁盘上。

		以下属性是可选的:
			 timeToIdleSeconds : 缓存element在过期前的空闲时间。
			 timeToLiveSeconds : 缓存element的有效生命期。
			 diskPersistent : 在VM重启的时候是否持久化磁盘缓存,默认是false。
			 diskExpiryThreadIntervalSeconds : 磁盘缓存的清理线程运行间隔,默认是120秒.
			 memoryStoreEvictionPolicy : 当内存缓存达到最大,有新的element加入的时候,
				移除缓存中element的策略。默认是LRU,可选的有LFU和FIFO
	-->
</ehcache>

        属性说明:
         diskStore:指定数据在磁盘中的存储位置。
         defaultCache:当借助CacheManager.add(“demoCache”)创建Cache时,EhCache便会采用<defalutCache/>指定的的管理策略
        以下属性是必须的:
         maxElementsInMemory – 在内存中缓存的element的最大数目 
         maxElementsOnDisk – 在磁盘上缓存的element的最大数目,若是0表示无穷大
       eternal – 设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断
         overflowToDisk – 设定当内存缓存溢出的时候是否将过期的element缓存到磁盘上
        以下属性是可选的:
         timeToIdleSeconds – 当缓存在EhCache中的数据前后两次访问的时间超过timeToIdleSeconds的属性取值时,这些数据便会删除,默认值是0,也就是可闲置时间无穷大
         timeToLiveSeconds – 缓存element的有效生命期,默认是0.,也就是element存活时间无穷大
             diskSpoolBufferSizeMB 这个参数设置DiskStore(磁盘缓存)的缓存区大小.默认是30MB.每个Cache都应该有自己的一个缓冲区.
         diskPersistent – 在VM重启的时候是否启用磁盘保存EhCache中的数据,默认是false。
        diskExpiryThreadIntervalSeconds – 磁盘缓存的清理线程运行间隔,默认是120秒。每个120s,相应的线程会进行一次EhCache中数据的清理工作
        memoryStoreEvictionPolicy – 当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略。默认是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO(先进先出)        

4.在UserMapper.xml中开启二缓存,UserMapper.xml下的sql执行完成会存储到它的缓存区域(HashMap)

    <cache type="org.mybatis.caches.ehcache.EhcacheCache">
                <!-- timeToLiveSeconds 缓存自创建日期起至失效时的间隔时间 -->
                <property name="timeToIdleSeconds" value="3600" />

                <!-- timeToIdleSeconds 缓存创建以后,最后一次访问缓存的日期至失效之时的时间间隔 -->
                <property name="timeToLiveSeconds" value="3600" />

                <!-- 同ehcache参数maxElementsInMemory -->
                <property name="maxEntriesLocalHeap" value="1000" />

                <!-- 同ehcache参数maxElementsOnDisk -->
                <property name="maxEntriesLocalDisk" value="10000000" />
                
                <!-- 当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略。默认是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO 
                    (先进先出) -->
                <property name="memoryStoreEvictionPolicy" value="LRU" />
     </cache>


            <!--mybatis ehcache缓存配置 -->
            <!-- 以下两个<cache>标签二选一,第一个可以输出日志,第二个不输出日志 -->
             <cache type="org.mybatis.caches.ehcache.LoggingEhcache" />
           
             <cache type="org.mybatis.caches.ehcache.EhcacheCache"/> 

    测试:需求获取员工表所有记录数(测试二级缓存),
          执行一次查询后,关闭session;然后获得一个全新的Session,再执行查询,若此时控制台未输出sql语句,且磁盘相应缓存目录下有缓存文件产生,证明二级缓存发挥了作用。     
    
sql映射文件中:

<cache type="org.mybatis.caches.ehcache.EhcacheCache">
        <!-- timeToLiveSeconds 缓存自创建日期起至失效时的间隔时间 -->
        <property name="timeToIdleSeconds" value="3600" />

        <!-- timeToIdleSeconds 缓存创建以后,最后一次访问缓存的日期至失效之时的时间间隔 -->
        <property name="timeToLiveSeconds" value="3600" />

        <!-- 同ehcache参数maxElementsInMemory -->
        <property name="maxEntriesLocalHeap" value="1000" />

        <!-- 同ehcache参数maxElementsOnDisk -->
        <property name="maxEntriesLocalDisk" value="10000000" />

        <!-- 当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略。默认是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO
            (先进先出) -->
        <property name="memoryStoreEvictionPolicy" value="LRU" />
    </cache>    

dao实现类中:

 @Override
    public List<Person> selectAll() {
        //步骤:
        //通过工具类获得SqlSession的实例
        SqlSession sqlSession = MyBatisUtil.getSqlSessionInstance();

        List<Person> persons = sqlSession.selectList("com.uplooking.dao.PersonDao.selectAll");
        System.out.println("第一次查询到的员工数是:" + persons);

        //关闭sqlSession(让一级缓存失效)
        MyBatisUtil.releaseResource(sqlSession);

        //执行完下面的代码行,控制台若没有sql语句输出,证明结果来自于二级缓存,而不是重新查询的数据库。
        sqlSession = MyBatisUtil.getSqlSessionInstance();
        persons = sqlSession.selectList("com.uplooking.dao.PersonDao.selectAll");
        System.out.println("第二次查询到的员工数是:" + persons);

        //释放资源
        MyBatisUtil.releaseResource(sqlSession);

        return persons;
    }

建议:放弃二级缓存,在业务层使用可控制的缓存代替更好。
<select id=”selectUserRoles” resultType=”UserRoleVO”>
    select * from user_role a,role b where a.roleid = b.roleid and a.userid = #{userid}
</select>
像上面这个查询,你会写到那个xml中呢??
不管是写到RoleMapper.xml还是UserRoleMapper.xml,或者是一个独立的XxxMapper.xml中。如果使用了二级缓存,都会导致上面这个查询结果可能不正确。
如果你正好修改了这个用户的角色,上面这个查询使用缓存的时候结果就是错的。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/191453.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 仿朋友圈相册图片选择以及画廊效果「建议收藏」

    仿朋友圈相册图片选择以及画廊效果「建议收藏」仿朋友圈相册图片选择以及画廊效果1.效果展示2.导入相关第三方库依赖3.编写选择图片页面a.编写布局b.编写Activityc.相册选择工具类部分代码d.相册4宫图适配器4.编写画廊页面a.编写画廊页面b.编写Activityc.画廊适配器5.源码1.效果展示该demo适配Android6、7、10。画廊效果,支持缩放效果。视频展示:(等我B站视频审核通过再来修改)部分截图:文章有点长,如果没时间就拉到最底下下载源码,再给个一键三联哈(* ̄︶ ̄)2.导入相关第三方库依赖站在巨人的肩膀上,

  • 创客基地oDrive第一课 入门配置

    创客基地oDrive第一课入门配置第1部分硬件准备oDriveV3.6-56V主板 1块12V2.0A电源适配器 1个microUSB线 1条oDriveV3.6主板相关硬件资料可从Q群(732557609)下载。欢迎使用Markdown编辑器你好!这是你第一次使用Markdown编辑器所展示的欢迎页。如果你想学习如何使用Markdown编辑器,可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。新的改变我们对Markdown编辑器进行了一些功能拓展与

  • 支付风控模型

    支付风控模型支付风控数据仓库建设 。支付风控涉及到多方面的内容,包括反洗钱、反欺诈、客户风险等级分类管理等。其中最核心的功能在于对实时交易进行风险评估,或者说是欺诈检测。如果这个交易的风险太高,则会执行拦截。由于反欺诈检测是在交易时实时进行的,在要求不能误拦截的同时,还有用户体验上的要求,即不能占用太多时间,一般要求风控操作必须控制在100ms以内,对于交易量大的业务,10ms甚至更低的性能要求都是必须的。

  • SSDP协议_mpp协议

    SSDP协议_mpp协议privatevoidsendDatagramPacket(finalStringip){newThread(newRunnable(){@Overridepublicvoidrun(){try{MulticastSocketmu

  • c#输出心形图片

    c#输出心形图片

  • Android浏览器调用APP「建议收藏」

    Android浏览器调用APP「建议收藏」有时我们想通过点击浏览器中某些广告链接来启动或下载APP,以启动APP来说,我们知道APP可以定义一个scheme,如果我们在浏览器中定义一个URL,这个URL使用定义的scheme,这样点击后我们就可以打开我们的客户端了,但目前市面上有些浏览器支持性不好,或者直接就不支持,认为这个打开是一个有害的链,那么我们还有没有其它的办法来结合,下面我们以web服务做为功能基础来实现我们知道如果在地址栏

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号