mybatis学习18:缓存

mybatis学习18:缓存

  • 什么是缓存【Cache】:

    • 存在内存中的临时数据

    • 将用户经常查询的数据放在缓存中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询;

    • 从缓存中查询:从而提高查询效率,解决了高并发的性能问题

    • 三高问题:高并发,高可用,高性能!

       

 

  • 为什么使用缓存:

    • 减少和数据库的交互次数,减少系统开销,提高系统效率!

      --所有的查询 -- 都要连接数据库  -- 耗资源!

      怎么优化:
      --1,一次查询的结果,给它暂存在一个可以直接取到的地方!(内存)
      --2,这些暂存在内存中的数据,就是缓存

      我们再次查询相同数据的时候:
      --1,直接走缓存,就不用走数据库了!

       

       

  • 什么样的数据能使用缓存:

    • 经常查询并且不经常改变的数据!【可以使用缓存】

 

  • Mybatis缓存:

    • Mybatis包含了一个非常强大的查询缓存特性

    • 它可以非常方便地定制和配置缓存,缓存可以极大的提升查询效率;

       

    • Mybatis系统中默认定义了两级缓存:一级缓存和二级缓存:

      • 默认情况下,只有一级缓存开启SqlSession级别的缓存,也称为本地缓存);

      • 二级缓存需要手动开启和配置,他是基于namespace级别的缓存;

      • 为了提高扩展性,Mybatis定义了缓存接口Cache,我们可以通过实现Cache接口来定义二级缓存;

 



 

  • 一级缓存:

    • 一级缓存也叫本地缓存:

      • 与数据库同一次会话期间查询到的数据会放在本地缓存中;

      • 以后如果需要获取相同的数据,直接从缓存中拿,没必要再去查询数据库;

         

    • 测试:重点

      • 1,开启日志:

        <settings>
           <setting name="logImpl" value="STDOUT_LOGGING"/>
        </settings>
      • 2,测试在一个Session中查询2次一样的记录!

      • 3,查看日志输出:

         

         

    • 缓存失效的情况:

      • 1,查询不同的东西;

      • 2,增删改操作,可能会改变原来的数据,所以必定会刷新缓存;

      • 3,查询不同的Mapper.xml;

      • 4,手动清理缓存:sqlSession.clearCache();

         

    • 总结:

      • 一级缓存默认是开启的,只在一次SqlSession中有效,也就是拿到连接到关闭连接这个区间段!

      • 一级缓存相当于一个map

 



 

  • 二级缓存:

    • 二级缓存也叫全局缓存,一级缓存的作用域太低了,所以诞生了二级缓存;

    • 基于namespace级别的缓存,一个命名空间,对应一个二级缓存

    • 工作机制:

      • 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;

      • 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;

      • 二级缓存生效前提:一级缓存死掉;

      • 新的会话查询信息,就可以从二级缓存中获取内容;

      • 不同的mapper查出的数据会放在自己对应的缓存(map)中;

         

    • 语法:

      • 要启用全局的二级缓存,只需要在你的 SQL 映射文件中添加一行;

        <cache/>

         

    • 使用步骤:

      • 1,开启全局缓存;

        <!--显示开启全局缓存-->
        <settings>
           <setting name="cacheEnabled" value="true"/>
        </settings>
      • 2,mapper.xml中引入缓存:

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE mapper
               PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
               "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        <mapper namespace="com.ljxdemo.dao.UserMapper">

        <!--在当前Mapper.xml中使用二级缓存:方式1
        使用时:要确认pojo实体类必须实现Serializable接口;序列化
        (public class User implements Serializable)
        -->
           <cache/>
           
           <!--在当前Mapper.xml中使用二级缓存:方式2-->
           <cache  eviction="FIFO"
                   flushInterval="60000"
                   size="512"
                   readOnly="true"/>
         
        </mapper>
      • 3,测试:

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE mapper
               PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
               "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        <mapper namespace="com.ljxdemo.dao.UserMapper">

        <!--   在当前Mapper.xml中使用二级缓存-->
           <cache  eviction="FIFO"
                   flushInterval="60000"
                   size="512"
                   readOnly="true"/>

           <select id="queryUserById" resultType="user" useCache="true">
              select * from user where id=#{id}
           </select>

        </mapper>
        @Test
           public void queryUserById(){
               SqlSession sqlSession1 = MybatisUtils.getSqlSession();
               SqlSession sqlSession2 = MybatisUtils.getSqlSession();
               UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
               List<User> users1 = mapper1.queryUserById(1);
               for (User user : users1) {
                   System.out.println(user);
              }

               sqlSession1.close();//一次缓存崩掉
               System.out.println("=====================");

               UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
               List<User> users2 = mapper2.queryUserById(1);
               for (User user : users2) {
                   System.out.println(user);
              }

               sqlSession2.close();
          }

         

      • 测试结果:

    • 总结:

      • 只要开启了二级缓存,在同一个Mapper下才有效;

      • 所有的数据都会先放在一级缓存中;

      • 只有当会话提交或者关闭的时候,才会提交到二级缓存中;

 

 



 

  • Mybatis缓存原理:

     

 

 



 

 

  • 自定义缓存-Ehcache:

    • Ehcache是一种广泛使用的开源Java分布式缓存,主要面向通用缓存,Java EE和轻量级容器;

       

    • 要在程序中使用:

      • 1,导包;

        <!-- https://mvnrepository.com/artifact/org.mybatis.caches/mybatis-ehcache -->
        <dependency>
           <groupId>org.mybatis.caches</groupId>
           <artifactId>mybatis-ehcache</artifactId>
           <version>1.2.1</version>
        </dependency>
      • 2,mapper.xml中去配置自定义cache:

        <!--在当前Mapper.xml中使用二级缓存-->
        <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
      • 3,新建ehcache.xml:缓存策略配置

        <?xml version="1.0" encoding="UTF-8" ?>
        <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
                updateCheck="false">

           <diskStore path="./tmpdir/Tmp_EhCache"/>

           <defaultCache
                   eternal="false"
                   maxElementsInMemory="10000"
                   overflowToDisk="false"
                   diskPersistent="false"
                   timeToIdleSeconds="1800"
                   timeToLiveSeconds="259200"
                   memoryStoreEvictionPolicy="LRU"/>

           <cache
                   name="cloud_user"
                   eternal="false"
                   maxElementsInMemory="5000"
                   overflowToDisk="false"
                   diskPersistent="false"
                   timeToIdleSeconds="1800"
                   timeToLiveSeconds="1800"
                   memoryStoreEvictionPolicy="LRU"/>

           <!--
               defaultCache:默认缓存策略,当ehcache找不到定义的缓存时,则使用这个缓存策略,只能定义一个
           -->

           <!--
               name:缓存名称
               maxElementsInMemory:缓存最大数目
               eternal:对象是否永久有效,一旦设置了,timeout将不起作用
               overflowToDisk:是否保存到磁盘,当系统宕机时
               timeToIdleSeconds:设置对象在失效前的允许闲置时间,单位:秒
               timeToLiveSeconds:设置对象在失效前的允许存活时间,单位:秒

               memoryStoreEvictionPolicy:可选策略有:LRU(最近最少使用,默认策略),FIFO(先进先出),LFU(最少访问次数)

           -->
        </ehcache>
      • 4,测试即可!

         

  • 总结:

    • 映射语句文件中的所有 select 语句的结果将会被缓存;

    • 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存; 

 

 

 

 

 

 

posted @   gzs1024  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示