• MyBatis缓存通俗易懂


    1.1     mybatis缓存介绍

    如下图,是mybatis一级缓存和二级缓存的区别图解:

    Mybatis一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。当遇到增删改时会清空缓存。Mybatis默认开启一级缓存。

    Mybatis二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当遇到增删改时会清空缓存。Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。

    1.2     一级缓存

    1.2.1  原理

    下图是根据id查询用户的一级缓存图解:

     

    一级缓存区域是根据SqlSession为单位划分的。

    每次查询会先从缓存区域找,如果找不到从数据库查询,查询到数据将数据写入缓存。

    Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象

    sqlSession执行insert、update、delete等操作commit提交后会清空缓存区域。

    1.2.2  测试1

    //获取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();

    1.2.3  测试2

    //获取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);
    
     

    1.3     二级缓存

    1.3.1  原理

    下图是多个sqlSession请求UserMapper的二级缓存图解。

     

    二级缓存区域是根据mapper的namespace划分的,相同namespace的mapper查询数据放在同一个区域,如果使用mapper代理方法每个mapper的namespace都不同,此时可以理解为二级缓存区域是根据mapper划分。

    每次查询会先从缓存区域找,如果找不到从数据库查询,查询到数据将数据写入缓存。

    Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象

    sqlSession执行insert、update、delete等操作commit提交后会清空缓存区域。

    1.3.2  开启二级缓存:

    在核心配置文件SqlMapConfig.xml中加入

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

     

    描述

    允许值

    默认值

    cacheEnabled

    对在此配置文件下的所有cache 进行全局性开/关设置。

    true false

    true

    要在你的Mapper映射文件中添加一行:  <cache /> ,表示此mapper开启二级缓存。

    1.3.3  实现序列化

             二级缓存需要查询结果映射的pojo对象实现java.io.Serializable接口实现序列化和反序列化操作,注意如果存在父类、成员pojo都需要实现序列化接口。

             public class Orders implements Serializable

             public class User implements Serializable

             ....

    1.3.4  测试

    //获取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();
    
     

    1.3.5  禁用二级缓存

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

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

    1.3.6  刷新缓存

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

     设置statement配置中的flushCache="true" 属性,默认情况下为true即刷新缓存,如果改成false则不会刷新。使用缓存时如果手动修改数据库表中的查询数据会出现脏读。

    如下:

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

  • 相关阅读:
    live555学习之RTSP连接建立以及请求消息处理过程
    RTSP协议学习笔记
    RTP头结构解析
    Doubango ims 框架 分析之 多媒体部分
    VMware虚拟机 NAT模式 配置静态ip
    计算机网络: IP地址,子网掩码,网段表示法,默认网关,DNS服务器详解
    VMWare VMNet 8 的配置使用
    VMware虚拟机CentOS7
    如何禁止虚拟机自动获取DHCP分配的ip地址
    Linux之VMware虚拟机取消DHCP
  • 原文地址:https://www.cnblogs.com/xiaolovewei/p/9427016.html
Copyright © 2020-2023  润新知