(二)MyBatis延迟加载,一级缓存,二级缓存
延迟加载配置:
什么时候用延迟加载?比如现在有班级和学生表,一对多关系,你可能只需要班级的信息,而不需要该班级学生的信息,这时候可以进行配置,让查询时先查询到班级的信息,在之后需要学生信息时候,再进行查询,避免不必要的查询。
需要进行如下配置:这里以一对多为例,其他关系类似:
PersonMapping.xml
<select id="selectPersonByClassId" resultMap="class_person_map" parameterType="int">
select * from class where classId=#{id}
</select>
<resultMap id="class_person_map" type="class">
<id column="classId" property="classId"/>
<result property="number" column="number"/>
<collection property="persons" ofType="person" select="mappers.ClassMapper.queryPersonByClassId" column="classId">
</collection>
</resultMap>
注意我们的映射,只映射了班级id和班级Number两个信息,并没有映射学生信息,而是通过<cllection>来配置的,标签属性
select:当需要persons属性时,执行select值所对应的id的sql语句进行查询(mappers.ClassMapper,xml)
column:执行sql语句时传入的参数
mappers.ClassMapper.xml
当需要班级学生信息时,会通过select属性来寻找到指定id的sql语句查询,如下
<select id="queryPersonByClassId" parameterType="int" resultType="Person">
select * from person where classId=#{classid}
</select>
之后设置断点调试可以看到只有调用了Class.getPersons()方法才会执行查询学生的sql语句。
一级缓存:
当通过一个SqlSession对象查询到一个数据时,MyBatis会将该数据放入该sqlsession当中,当下一次再次查询该数据时,会从该sqlsession直接取得该数据,不需要再与数据库交互查询,自动开启。不过注意第二次查询必须也是在同一个SQLSESSION之下进行的。
二级缓存:
myBatis内置的:
接上面,通过一个SQLSession对象查询到了一个数据,不仅会放入一级缓存,还会放入二级缓存当中。当你下一次通过另一个不同的SQLSEssion对象查询相同的数据时,会从二级缓存当中进行获取,不过查询时SQLSession必来自同一个mapper.class。
总的来说两句话:一级缓存同一个sqlsession,二级缓存同一个mapper.class初始化的,即同一个namespace,是否进入缓存就是依据这个判断的。
开启配置方式:
config.xml:
<setting name="cacheEnabled" value="true"/>
mapper,xml
<cache/>
另外二级缓存是将数据进行序列化的,所以必要要让开启二级缓存的对象继承序列化接口才行。序列化就是将数据从内存放入到硬盘之中。
即给mapper.xml对应的指定class 加上
implements Serializable
而且如果当前mapper对应的class继承了其他类或者里面有级联属性,其他类或者级联属性也必须要序列化。
相当于序列化三个:本类,父类,级联属性
一级缓存二级缓存的缓存时机:
一级缓存只要查询了就放入一级缓存当中,相当于是实时的,
二级缓存是在一个sqlsession.close()之后才会将该sqlsession所查询到的放入到二级缓存当中。
示例:
//加载配置信息
Reader reader = Resources.getResourceAsReader("config.xml");
//connection
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
//第一个sqlsession
SqlSession sqlSession = sessionFactory.openSession();
PersonMapping personMapping = sqlSession.getMapper(PersonMapping.class);
personMapping.selectPersonById();
System.out.println("---");
sqlSession.close();
//第二个sqlsession
SqlSession sqlSession2 = sessionFactory.openSession();
PersonMapping personMapping2 = sqlSession2.getMapper(PersonMapping.class);
personMapping2.selectPersonById();
sqlSession2.close();
执行后,查看日志可以看到只执行了一条sql语句,PersonMapping.class共享同一个二级缓存
清理缓存:commit()会清除缓存(一级二级都是的),另外注意这个commit()不能是查询自身的commit,即这个commit所属于的sqlsession对象必须是执行了增删改的sqlsession。
(二)MyBatis延迟加载,一级缓存,二级缓存的更多相关文章
- Mybatis 的一级、二级缓存?
1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 C ...
- Mybatis 的一级、二级缓存?
1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 C ...
- mybatis的缓存机制(一级缓存二级缓存和刷新缓存)和mybatis整合ehcache
1.1 什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 一级缓存是SqlSession级别的缓存.在操作数据库时需要构造 s ...
- 【mybatis源码学习】mybtias一级,二级缓存
转载:https://www.cnblogs.com/ysocean/p/7342498.html mybatis 为我们提供了一级缓存和二级缓存,可以通过下图来理解: ①.一级缓存是SqlSessi ...
- Mybatis一级、二级缓存
Mybatis一级.二级缓存 一级缓存 首先做一个测试,创建一个mapper配置文件和mapper接口,我这里用了最简单的查询来演示. <mapper namespace="c ...
- MyBatis(七):MyBatis缓存详解(一级缓存/二级缓存)
一级缓存 MyBatis一级缓存上SqlSession缓存,即在统一SqlSession中,在不执行增删改操作提交事务的前提下,对同一条数据进行多次查询时,第一次查询从数据库中查询,完成后会存入缓 ...
- mybatis 使用redis实现二级缓存(spring boot)
mybatis 自定义redis做二级缓存 前言 如果关注功能实现,可以直接看功能实现部分 何时使用二级缓存 一个宗旨---不常变的稳定而常用的 一级是默认开启的sqlsession级别的. 只在单表 ...
- Hibernate 再接触 一级缓存 二级缓存 查询缓存
缓存 就是把本来应该放在硬盘里的东西放在内存里 将来存内存里读 一级缓存: session缓存 二级缓存: sessionFactory级别的 (适合经常访问,数据量有限,改动不大) 很多的se ...
- hibernate的获取session的两方法比较,和通过id获取对象的比较,一级缓存二级缓存
opensession与currentsession的联系与区别 在同一个线程中opensession的session是不一样的,而currentsession获取的session是一样的,这就保证了 ...
随机推荐
- Python在Windows下列出所有的安装包和模块
1.查看python安装的module python -m pydoc module 或 >>>help('module') 2.用pip查看 pip list
- 【转】8 个效果惊人的 WebGL/JavaScript 演示
英文原文:9 IMPRESSIVE WEBGL JAVASCRIPT EFFECT SHOWCASE,翻译:iteye WebGL 是一种 3D 绘图标准,这种绘图技术标准允许把 JavaScript ...
- linux文件通配符
* #匹配任意字符 ? #匹配任意单个字符 ~ #当前用户家目录 ~user #用户user的家目录 ~+ #当前工作目录 ~- #前一个工作目录 [0-9] #匹配的数字范围 [a-z] #匹配小写 ...
- forkjoin及其性能分析,是否比for循环快?
最近看了网上的某公开课,其中有讲到forkjoin框架.在这之前,我丝毫没听说过这个东西,很好奇是什么东东.于是,就顺道研究了一番. 总感觉这个东西,用的地方很少,也有可能是我才疏学浅.好吧,反正问了 ...
- Java小白集合源码的学习系列:ArrayList
ArrayList源码学习 本文基于JDK1.8版本,对集合中的巨头ArrayList做一定的源码学习,将会参考大量资料,在文章后面都将会给出参考文章链接,本文用以巩固学习知识. ArrayList的 ...
- k8s内运行ubuntu容器
k8s内运行ubuntu镜像 环境 互相能访问的4台机器master,node01,node02,node03,4核心,内存8G 使用root操作 安装k8s 在master安装docker.kube ...
- Ubuntu16安装NVIDIA驱动后重复登录 简单粗暴
第一步 卸载所有NVIDIA的东西 第二步 开机,应该能进入默认驱动的桌面了,在设置里关闭开机密码,开机自动登录 第三步 安装英伟达驱动
- python条件(三元)运算符
条件运算符 是 三元运算符 语法: 语句1 if 条件表达式 else 语句2 执行流程: 条件运算符在执行时,会先对条件表达式进行求值判断 如果判断结果为True,则执行 ...
- Java8 新特性(三) - 日期时间对象以及一些其他特性
日期时间对象 关于日期时间的操作可以分为两种: 转换:与字符串的互相转换,与时间戳的互相转换 计算:计算两个时间点之间的间隔.时间点与时间段的计算(计算下周N.下个月D日.去年M月D日等等) Java ...
- ForkJoin统计文件夹中包含关键词的数量
2018-06-09总结: ForkJoin确实可以很快速的去解析文件并统计关键词的数量,但是如果文件过大就会出现内存溢出,是否可以通过虚拟内存方式解决内存溢出的问题呢? package com.ox ...