关于Mybatis的学习主要参考了狂神的视频

  1. 一级缓存

    (1).使用范围:从sqlSession会话开始到结束

    (2).使用:默认打开,无法关闭

    (3).测试使用(需要打开日志观察数据库的连接情况):

    public static void Maintest(){
    SqlSession sqlSession = Connection.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    HashMap map = new HashMap();
    map.put("UId","3180421016");
    List<UserBean> userBeans = userMapper.queryByIf(map);
    map.put("UName","关晨亮");
    //userMapper.updateById(map);
    System.out.println(userMapper.queryByIf(map).get(0).equals(userBeans.get(0)));
    sqlSession.close();
    }
    //result:true,将结果集打印,可以看出两次结果集打印之间是没有再做数据库连接的

    (4).缓存失效的4种情况:

    • sqlSession不同

      public static void Maintest(){
      SqlSession sqlSession1 = Connection.getSqlSession();
      SqlSession sqlSession2 = Connection.getSqlSession();
      UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
      UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
      HashMap map = new HashMap();
      map.put("UId","3180421016");
      List<UserBean> userBeans = userMapper1.queryByIf(map);
      System.out.println(userBeans);
      sqlSession1.close();
      System.out.println(userBeans.get(0).equals(userMapper2.queryByIf(map).get(0)));
      sqlSession2.close();
      }
    • sqlSession相同,两次查询操作之间存在增删改操作

      public static void Maintest(){
      SqlSession sqlSession = Connection.getSqlSession();
      UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
      HashMap map = new HashMap();
      map.put("UId","3180421016");
      List<UserBean> userBeans = userMapper.queryByIf(map);
      map.put("UName","关晨亮");
      userMapper.updateById(map);
      System.out.println(userMapper.queryByIf(map).get(0).equals(userBeans.get(0)));
      sqlSession.close();
      } //result:false,将结果集打印,可以看出两次结果集打印之间是有再次做过数据库连接的
    • sqlSession相同,查询条件不同(此时缓存中没有相关数据)

      public static void Maintest(){
      SqlSession sqlSession1 = Connection.getSqlSession();
      UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
      HashMap map = new HashMap();
      map.put("UId","3180421016");
      List<UserBean> userBeans = userMapper1.queryByIf(map);
      System.out.println(userBeans);
      map.put("UId","2");
      userBeans = userMapper1.queryByIf(map);
      System.out.println(userBeans);
      sqlSession1.close();
      }
      //打开日志可以看到,发生了两次对于数据库的连接请求
    • 通过session.clearCache()主动刷新缓存

      public static void Maintest(){
      SqlSession sqlSession1 = Connection.getSqlSession();
      UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
      HashMap map = new HashMap();
      map.put("UId","3180421016");
      List<UserBean> userBeans = userMapper1.queryByIf(map);
      System.out.println(userBeans);
      sqlSession1.clearCache();
      userBeans = userMapper1.queryByIf(map);
      System.out.println(userBeans);
      sqlSession1.close();
      }
  2. 二级缓存

    (1).简介

    • 作用范围:整个namespace,也就是一个mapper
    • 实现:不同的mapper查出的数据会放在对应的缓存(map)中

    (2).使用:

    • 在主配置文件中显式地开启二级缓存
    <settings>
    <!-- <setting name="logImpl" value="LOG4J"/>-->
    <setting name="logImpl" value="STDOUT_LOGGING"/>
    <setting name="cacheEnabled" value="true"/>
    </settings>
    • 在Mapper.xml中配置(为什么要开启readOnly会在后面解释)
    <cache readOnly="true"/>

    <cache
    eviction="FIFO"
    flushInterval="60000"
    size="512"
    readOnly="true"/>
    • 测试
    public static void Maintest(){
    SqlSession sqlSession1 = Connection.getSqlSession();
    SqlSession sqlSession2 = Connection.getSqlSession();
    UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
    UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
    HashMap map = new HashMap();
    map.put("UId","3180421016");
    List<UserBean> userBeans = userMapper1.queryByIf(map);
    sqlSession1.close();
    System.out.println(userBeans.get(0).equals(userMapper2.queryByIf(map).get(0)));
    sqlSession2.close();
    }
    /result:true

    (3).注意

    • 需要实体序列化

    客户端访问了某个能开启会话功能的资源, web服务器就会创建一个与该客户端对应的HttpSession对象,每个HttpSession对象都要站用一定的内存空间。如果在某一时间段内访问站点的用户很多,web服务器内存中就会积累大量的HttpSession对象,消耗大量的服务器内存,即使用户已经离开或者关闭了浏览器,web服务器仍要保留与之对应的HttpSession对象,在他们超时之前,一直占用web服务器内存资源。

    web服务器通常将那些暂时不活动但未超时的HttpSession对象转移到文件系统或数据库中保存,服务器要使用他们时再将他们从文件系统或数据库中装载入内存,这种技术称为Session的持久化。

    将HttpSession对象保存到文件系统或数据库中,需要采用序列化的方式将HttpSession对象中的每个属性对象保存到文件系统或数据库中;将HttpSession对象从文件系统或数据库中装载如内存时,需要采用反序列化的方式,恢复HttpSession对象中的每个属性对象。所以存储在HttpSession对象中的每个属性对象必须实现Serializable接口

    public class UserBean implements Serializable {
    private String UId;
    private String UName;
    private int USet;
    private int UAuth;
    private String UPassword;
    private int UState;
    }
    • 必须打开只读,否则两次比较的结果不同

    只读的缓存会给所有调用者返回缓存对象的相同实例。 因此这些对象不能被修改。这就提供了可观的性能提升。而可读写的缓存会(通过序列化)返回缓存对象的拷贝。 速度上会慢一些,但是更安全,因此默认值是 false。

    <cache readOnly="true"/>
    • 缓存优先放在以及会话中,当会话关闭后,缓存才会被转移到二级会话

      public static void Maintest(){
      SqlSession sqlSession1 = Connection.getSqlSession();
      SqlSession sqlSession2 = Connection.getSqlSession();
      UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
      UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
      HashMap map = new HashMap();
      map.put("UId","3180421016");
      List<UserBean> userBeans = userMapper1.queryByIf(map);
      System.out.println(userBeans);
      System.out.println(userBeans.get(0).equals(userMapper2.queryByIf(map).get(0)));
      sqlSession1.close();
      sqlSession2.close();
      }
      //false,因为还没有关闭就开始比较了
      public static void Maintest(){
      SqlSession sqlSession1 = Connection.getSqlSession();
      SqlSession sqlSession2 = Connection.getSqlSession();
      UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
      UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
      HashMap map = new HashMap();
      map.put("UId","3180421016");
      List<UserBean> userBeans = userMapper1.queryByIf(map);
      System.out.println(userBeans);
      sqlSession1.close();
      System.out.println(userBeans.get(0).equals(userMapper2.queryByIf(map).get(0)));
      sqlSession2.close();
      }
      //true,因为是会话关闭之后再比较的
    • 对于查询(select),我们可以使用useCache来选择是否取消缓存;对于增删改,可以使用flushCache来选择是否取消更新缓存

  3. 缓存原理,这边用狂神的图来加深理解

  4. 使用ehcache外部缓存

    (1).导包

    (2).写配置文件.xml

    (3).在主配置文件中使用:设定cache标签的type属性

    注:现在多用redis数据库

Mybatis——一级缓存与二级缓存的更多相关文章

  1. [原创]关于mybatis中一级缓存和二级缓存的简单介绍

    关于mybatis中一级缓存和二级缓存的简单介绍 mybatis的一级缓存: MyBatis会在表示会话的SqlSession对象中建立一个简单的缓存,将每次查询到的结果结果缓存起来,当下次查询的时候 ...

  2. MyBatis 延迟加载,一级缓存,二级缓存设置

    什么是延迟加载 resultMap中的association和collection标签具有延迟加载的功能. 延迟加载的意思是说,在关联查询时,利用延迟加载,先加载主信息.使用关联信息时再去加载关联信息 ...

  3. mybatis高级(3)_延迟加载_深度延迟_一级缓存_二级缓存

    设置延迟加载需要在mybatis.xml中设置 注: 侵入式延迟加载为真时是延迟加载 侵入式延迟加载为假时是深度延迟加载 <!-- 延迟加载和深度延迟加载 --> <settings ...

  4. 9.Mybatis一级缓存和二级缓存

    所谓的缓存呢?其实原理很简单,就是在保证你查询的数据是正确的情况下,没有去查数据库,而是直接查找的内存,这样做有利于缓解数据库的压力,提高数据库的性能,Mybatis中有提供一级缓存和二级缓存. 学习 ...

  5. 八 mybatis查询缓存(一级缓存,二级缓存)和ehcache整合

    1       查询缓存 1.1     什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存.

  6. myBatis学习(9):一级缓存和二级缓存

    正如大多数持久层框架一样,MyBatis同样提供了一级缓存和二级缓存的支持 1. MyBatis一级缓存基于PerpetualCache的HashMap本地缓存,其存储作用域为 Session,默认情 ...

  7. mybatis 详解(九)------ 一级缓存、二级缓存

    上一章节,我们讲解了通过mybatis的懒加载来提高查询效率,那么除了懒加载,还有什么方法能提高查询效率呢?这就是我们本章讲的缓存. mybatis 为我们提供了一级缓存和二级缓存,可以通过下图来理解 ...

  8. MyBatis从入门到放弃六:延迟加载、一级缓存、二级缓存

    前言 使用ORM框架我们更多的是使用其查询功能,那么查询海量数据则又离不开性能,那么这篇中我们就看下mybatis高级应用之延迟加载.一级缓存.二级缓存.使用时需要注意延迟加载必须使用resultMa ...

  9. Mybatis第八篇【一级缓存、二级缓存、与ehcache整合】

    Mybatis缓存 缓存的意义 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题. myba ...

  10. MyBatis 一级缓存,二级缓存,延迟加载设置

       1  什么是延迟加载  resultMap中的association和collection标签具有延迟加载的功能. 延迟加载的意思是说,在关联查询时,利用延迟加载,先加载主信息.使用关联信息时再 ...

随机推荐

  1. Linux常用命令精华讲解 上部 (下部下回分解)不要催很忙的

    Linux常用命令讲解 1.Linux命令基础 2.Linux命令帮助 3.目录与文件的基操 1.Shell是系统中运行的一种特殊程序在用户和内核之间充当"翻译官"的角色,登录li ...

  2. 【AGC035D】Add and Remove(脑洞 DP 分治)

    题目链接 大意 给出\(N\)个数的序列,每次操作可以选择连续的三个数,将中间的那个数抽出,将另外两个数的数值加上中间那个数的数值. 一直执行以上操作直到只剩最后两个数,求最后两个数的所有可能的和的最 ...

  3. Lesson10——NumPy 迭代数组

    NumPy 教程目录 NumPy 迭代数组 NumPy 迭代器对象  numpy.nditer  提供了一种灵活访问一个或者多个数组元素的方式. 迭代器最基本的任务的可以完成对数组元素的访问. Exa ...

  4. MySql索引分析及查询优化

    B-Tree 核心特点: 多路,非二叉树 每个节点既保存索引,又保存数据 搜索时相当于二分查找 B+Tree 核心特点 多路非二叉 只有叶子节点保存数据 搜索时相当于二分查找 增加了相邻接点的指向指针 ...

  5. Solution -「AT 3913」XOR Tree

    \(\mathcal{Description}\)   Link.   给定一棵树,边 \((u,v)\) 有边权 \(w(u,v)\).每次操作可以使一条简单路径上的边权异或任意非负整数.求最少的操 ...

  6. Solution -「CF 757F」Team Rocket Rises Again

    \(\mathcal{Description}\)   link.   给定 \(n\) 个点 \(m\) 条边的无向图和一个源点 \(s\).要求删除一个不同与 \(s\) 的结点 \(u\),使得 ...

  7. Note/Solution -「洛谷 P6466」分散层叠算法

    \(\mathcal{Description}\)   Link.   给定 \(m\) 个长度为 \(n\) 的有严格升序且不包含重复元素的序列 \(a_1,a_2,\cdots,a_m\),\(q ...

  8. 痞子衡嵌入式:对比MbedTLS算法库纯软件实现与i.MXRT上DCP,CAAM硬件加速器实现性能差异

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是MbedTLS算法库纯软件实现与i.MXRT上DCP,CAAM硬件加速器实现性能差异. 近期有 i.MXRT 客户在集成 OTA SBL ...

  9. Aluminum: An Asynchronous, GPU-Aware Communication Library Optimized for Large-Scale Training of Deep Neural Networks on HPC Systems

    本文发表在MLHPC 2018上,主要介绍了一个名为Aluminum通信库,这个库针对Allreduce做了一些关于计算通信重叠以及针对延迟的优化,以加速分布式深度学习训练过程. 分布式训练的通信需求 ...

  10. DubboSPI机制二之Dubbo中SPI初体验

    Dubbo高级之一SPI机制之JDK中的SPI - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中阐述了JDK标准的SPI,并对其应用做了相应的实践.在实际应用中,很多框架都会对其进行扩展 ...