(二)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是一样的,这就保证了 ...
随机推荐
- VScode(一):C/C++ & MinGW & Code Runner
目录 1 VScode配置安装 2 MinGW配置安装 2.1 MinGW下载安装 2.2 MinGW环境配置 3 VScode编译C/C++ 3.1 扩展插件安装 3.2 项目配置 3.2.1 配置 ...
- 8款极具表现力的jQuery/CSS3网页菜单
上一篇我向大家分享了7款效果震憾的HTML5应用组件,今天主要来分享一下CSS3网页菜单,因为在一个网站中,菜单起着举足轻重的作用,所以作为WEB开发人员,我们有必要将网站的菜单设计得尽量完美,下面向 ...
- 《【面试突击】— Redis篇》-- Redis的线程模型了解吗?为啥单线程效率还这么高?
能坚持别人不能坚持的,才能拥有别人未曾拥有的.关注编程大道公众号,让我们一同坚持心中所想,一起成长!! <[面试突击]— Redis篇>-- Redis的线程模型了解吗?为啥单线程效率还这 ...
- Lambda表达式(lambda expression)⭐⭐⭐⭐⭐
原作者 lambda表达式(lambda expression)实际上是匿名函数一种表示形式, 即没有函数名的函数:参数列表=>表达式或语句块,在我看来主要目是为了简化代码编写,提高代码可读性而 ...
- StampedLock的理解和使用
StampedLock介绍 StampedLock是为了优化可重入读写锁性能的一个锁实现工具,jdk8开始引入 相比于普通的ReentranReadWriteLock主要多了一种乐观读的功能 在API ...
- CTF-Keylead(ASIS CTF 2015)
将keylead下载到本地用7-ZIP打开,发现主要文件 keylead~ 在ubuntu里跑起来,发现是个游戏,按回车后要摇出3,1,3,3,7就能获得flag. 拖进IDA 直接开启远程调试,跑起 ...
- 推荐几个高质量图片网站,再也不怕没图装X了
这几个图片网站都是高质量的图片网站,建议收藏! 找个高逼格的图片发票圈,不再难了. Unsplash 网址:https://unsplash.com Unsplash是一个免费高质量照片的网站,照片都 ...
- XSS Cheat Sheet
Basic and advanced exploits for XSS proofs and attacks. Work in progress, bookmark it. Technique Vec ...
- 什么是LakeHouse?
1. 引入 在Databricks的过去几年中,我们看到了一种新的数据管理范式,该范式出现在许多客户和案例中:LakeHouse.在这篇文章中,我们将描述这种新范式及其相对于先前方案的优势. 数据仓库 ...
- ios--->ios消息机制(NSNotification 和 NSNotificationCenter)
问题的背景 IOS中委托模式和消息机制基本上开发中用到的比较多,一般最开始页面传值通过委托实现的比较多,类之间的传值用到的比较多,不过委托相对来说只能是一对一,比如说页面A跳转到页面B,页面的B的值改 ...