zoukankan      html  css  js  c++  java
  • [MyBatis]缓存机制

    MyBatis提供查询缓存,用于减轻数据库压力,提高数据库性能

    MyBatis提供一级缓存和二级缓存

    一级缓存:sqlsession级别的缓存

          在操作数据库时,需要构造sqlsession对象,在对象中有一个数据结构(HashMap)

                    用于存储缓存数据,不同的sqlsession之间的缓存区域是互相不影响的。

    二级缓存:Mapper级别的缓存

        多个sqlsession去操作同一个mapper的sql语句,多个sqlsession可以共用二级缓存,

        所得到的数据会存在二级缓存区域,二级缓存是跨sqlsession的

    一级缓存工作原理:

    操作过程:

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

      第二次发起查询ID为1的用户,再去缓存中查找,如果找到直接从缓存中获取用户信息

      如果sqlsession执行 insert、update、delete 等操作 commit 提交后会清空sqlsession中的一级缓存,避免脏读。

     一级缓存 测试1:同一个sqlsession下  第一次查询和第二次查询


    //获取session
    
           SqlSession session = sqlSessionFactory.openSession();
    
           //获限mapper接口实例
    
           UserMapper userMapper = session.getMapper(UserMapper.class);
    
           //第一次查询
    
           User user1 = userMapper.findUserById(1);
    
           System.out.println(user1);
    
    //第二次查询,由于是同一个session则不再向数据发出语句直接从缓存取出
    
           User user2 = userMapper.findUserById(1);
    
           System.out.println(user2);
    
    //关闭session
    
           session.close();

    一级缓存 测试2:同一个sqlsession下  第一次查询后,执行修改操作缓存区被清空,再次查询从数据库获取数据


    //获取session
    
           SqlSession session = sqlSessionFactory.openSession();
    
           //获限mapper接口实例
    
           UserMapper userMapper = session.getMapper(UserMapper.class);
    
           //第一次查询
    
           User user1 = userMapper.findUserById(1);
    
           System.out.println(user1);
    
           //在同一个session执行更新
    
           User user_update = new User();
    
           user_update.setId(1);
    
           user_update.setUsername("李奎");
    
           userMapper.updateUser(user_update);
    
           session.commit();
    
           //第二次查询,虽然是同一个session但是由于执行了更新操作session的缓存被清空,这里重新发出sql操作
    
           User user2 = userMapper.findUserById(1);
    
           System.out.println(user2);

    二级缓存工作原理:

    首先要手动开启MyBatis二级缓存。

    1:在mybatis-config.xml设置二级缓存开关,还要在具体的mapper.xml中开启二级缓存

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

      描述 允许值 默认值
    cacheEnabled 对在此配置文件下的所有cache 进行全局性开/关设置 true | flase true

    2: <!--开启本Mapper的namespace下的二级缓存-->

      <cache eviction="LRU" flushInterval="10000"/>

      cache属性的简介:

       eviction:代表的是缓存回收策略,目前MyBatis提供以下策略。

        (1) LRU(Least Recently Used),最近最少使用的,最长时间不用的对象

        (2) FIFO(First In First Out),先进先出,按对象进入缓存的顺序来移除他们

        (3) SOFT,软引用,移除基于垃圾回收器状态和软引用规则的对象  

        (4) WEAK,弱引用,更积极的移除基于垃圾收集器状态和弱引用规则的对象。这里采用的是LRU,移除最长时间不用的对形象

      flushInterval:刷新间隔时间,单位为毫秒,这里配置的是100秒刷新,如果你不配置它,那么当SQL被执行的时候才会去刷新缓存。

    3:对应的pojo实现序列化(implements Serializable)

    二级缓存 测试:不同的sqlsession下  执行同样的SQL语句 第一次从数据库查询 再次查询从缓存区获取


    //获取session1
    
           SqlSession session1 = sqlSessionFactory.openSession();
    
           UserMapper userMapper = session1.getMapper(UserMapper.class);
    
           //使用session1执行第一次查询
    
           User user1 = userMapper.findUserById(1);
    
           System.out.println(user1);
    
           //关闭session1
    
           session1.close();
    
           //获取session2
    
           SqlSession session2 = sqlSessionFactory.openSession();
    
           UserMapper userMapper2 = session2.getMapper(UserMapper.class);
    
           //使用session2执行第二次查询,由于开启了二级缓存这里从缓存中获取数据不再向数据库发出sql
    
           User user2 = userMapper2.findUserById(1);
    
           System.out.println(user2);
    
           //关闭session2
    
           session2.close();

    禁用二级缓存:

      在 statement 中设置 useCache=false 可以禁用当前select语句的二级缓存,即每次查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。

      <select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">

    刷新缓存:

      在mapper的同一个namespace中,如果有其它insert、update、delete操作数据后需要刷新缓存,如果不执行刷新缓存会出现脏读。  

      设置statement配置中的flushCache="true" 属性,默认情况下为true即刷新缓存,如果改成false则不会刷新。

      使用缓存时如果手动修改数据库表中的查询数据会出现脏读。

      如下:

      <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User" flushCache="true">

  • 相关阅读:
    BZOJ2301——莫比乌斯&&整除分块
    2019HDU多校第五场A fraction —— 辗转相除法|类欧几里得
    AKS素性检测
    2019牛客多校B generator 1——十进制快速幂
    BZOJ 3884——欧拉降幂和广义欧拉降幂
    libevent HTTP client 的实现
    google proto buffer安装和简单示例
    setenv LD_LIBRARY_PATH
    Centos6.4下安装protobuf及简单使用
    lrzsz
  • 原文地址:https://www.cnblogs.com/yan-sh/p/13039826.html
Copyright © 2011-2022 走看看