延迟加载配置:

什么时候用延迟加载?比如现在有班级和学生表,一对多关系,你可能只需要班级的信息,而不需要该班级学生的信息,这时候可以进行配置,让查询时先查询到班级的信息,在之后需要学生信息时候,再进行查询,避免不必要的查询。

需要进行如下配置:这里以一对多为例,其他关系类似:

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延迟加载,一级缓存,二级缓存的更多相关文章

  1. Mybatis 的一级、二级缓存?

    1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 C ...

  2. Mybatis 的一级、二级缓存?

    1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 C ...

  3. mybatis的缓存机制(一级缓存二级缓存和刷新缓存)和mybatis整合ehcache

    1.1  什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 一级缓存是SqlSession级别的缓存.在操作数据库时需要构造 s ...

  4. 【mybatis源码学习】mybtias一级,二级缓存

    转载:https://www.cnblogs.com/ysocean/p/7342498.html mybatis 为我们提供了一级缓存和二级缓存,可以通过下图来理解: ①.一级缓存是SqlSessi ...

  5. Mybatis一级、二级缓存

      Mybatis一级.二级缓存   一级缓存 首先做一个测试,创建一个mapper配置文件和mapper接口,我这里用了最简单的查询来演示. <mapper namespace="c ...

  6. MyBatis(七):MyBatis缓存详解(一级缓存/二级缓存)

    一级缓存 ​ MyBatis一级缓存上SqlSession缓存,即在统一SqlSession中,在不执行增删改操作提交事务的前提下,对同一条数据进行多次查询时,第一次查询从数据库中查询,完成后会存入缓 ...

  7. mybatis 使用redis实现二级缓存(spring boot)

    mybatis 自定义redis做二级缓存 前言 如果关注功能实现,可以直接看功能实现部分 何时使用二级缓存 一个宗旨---不常变的稳定而常用的 一级是默认开启的sqlsession级别的. 只在单表 ...

  8. Hibernate 再接触 一级缓存 二级缓存 查询缓存

    缓存 就是把本来应该放在硬盘里的东西放在内存里  将来存内存里读 一级缓存: session缓存 二级缓存: sessionFactory级别的   (适合经常访问,数据量有限,改动不大) 很多的se ...

  9. hibernate的获取session的两方法比较,和通过id获取对象的比较,一级缓存二级缓存

    opensession与currentsession的联系与区别 在同一个线程中opensession的session是不一样的,而currentsession获取的session是一样的,这就保证了 ...

随机推荐

  1. Kubernetes 会不会“杀死” DevOps?

    作者丨孙健波(天元)  阿里巴巴技术专家 导读:DevOps 这个概念最早是在 2007 年提出的,那时云计算基础设施的概念也才刚刚提出没多久,而随着互联网的逐渐普及,应用软件的需求爆发式增长,软件开 ...

  2. EXE和DLL调用关系,DLL制作,钩子

    制作DLL时,在cpp种引入了头文件,但头文件里的全局变量在cpp种却不能用 参考大佬博客https://blog.csdn.net/speargod/article/details/88854344 ...

  3. Spring HTTP invoker简介

    Spring HTTP invoker简介 Spring HTTP invoker是spring框架中的一个远程调用模型,执行基于HTTP的远程调用(意味着可以通过防火墙),并使用java的序列化机制 ...

  4. wepy怎么在生命周期中调用methods方法

    很简单: 比如在 onLoad () { imgRemove(e) {         this.methods.onRemove(e)     } } 在methods中就可以直接调用属于它的方法, ...

  5. 1z0-062 题库解析3

    The hr user executes the following query on the employees table but does not issue commit, rollback, ...

  6. vue-cookies

    vue-cookies用于登录,一般和vuex一起使用 vuex在各个组件共享值,cookie恒久保留值 一.安装 npm install vue-cookies --save 二.引用(在store ...

  7. Java入门 - 高级教程 - 08.Applet

    原文地址:http://www.work100.net/training/java-applet.html 更多教程:光束云 - 免费课程 Applet 序号 文内章节 视频 1 概述 2 Apple ...

  8. Browser Security-基本概念

    URL格式: scheme://[login[:password]@](host_name|host_address)[:port][/hierarchical/path/to/resource[?s ...

  9. Qt Installer Framework翻译(7-2)

    包文件夹 安装程序包含的组件,要么是内嵌的,要么可以从远程存储库加载.在这两种情况下,都需要为组件使用一种安装程序可以读取的文件格式和结构. 包文件夹结构 将所有组件放在相同的根文件夹中,即包文件夹. ...

  10. jquery的版本 纵多 , 各个版本的插件的融合 ,

    有些插件在哪些版本下没有 插件之间因为版本冲突 是得不偿失的事情