我们这里说的三层级联和二级缓存其实也是MyBatis映射器的知识点,只是因为比较难理解,所以单独拿出来讲解,下面是三层级联的内容;
       我们知道,在数据库中包含着一对一,一对多,多对多的关系,例如,我们希望在查出学生表的时候,能够连着查出学生证表的信息,这就是一对一的关系查询,我们又希望,能够在查出学生表的时候,能够连着查出你每一个学生的多门课程成绩,而课程成绩又与课程相关,所以呢,我们先用学生表与课程表实现一对多的关系,然后,再利用课程表与课程成绩实现一对一的查询,这样的话,你就实现了一对多的关系查询了。最后,我们说了,学生表中有男女性别的区别,那么,如果我要根据性别来分别查询男女的生理特征的话,那么这就是多对多的关系了。下面我们先来讲讲一对一;对了,这三种级联分别对应了三种元素,分别是association,collection,discriminator;
        一对一的关系:association;
        首先,我们按上面的学生表来做例子,Student代表学生,StudentSelfcard代表学生证;思路就是我们先做一个查询学生证的resultMap,然后我们再做一个查询学生表的resultMap,然后我们把查询学生证的resultMap注册到查询学生表的resultMap中去;

<?xml version = "1.0" encoding = "UTF-8">
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace = "com.learn.chapter4.mapper.StudentSelfcardMapper">
<resultMap type = "com.learn.chapter4.po.StudentSelfcardBean">
<id property = "id" column = "id"/>
<id property = "studentId" column = "student_id"/>
<id property = "native_" column = "native"/>
<id property = "issueDate" column = "issue_date"/>
<id property = "endDate" column = "end_date"/>
<id property = "note" column = "note"/>
</resultMap>
<select id = "findStudentSelfcardByStudentId" parameterType = "int" resultMap = "studentSelfcardMap">
select id,student_id,native,issue_date,end_date,note from t_student_selfcard where student_id = #{studentId}
</select>
</mapper>

  这个呢,就是我们的学生证查询resultMap定义了,接下来是我们的学生表查询;

<?xml version = "1.0" encoding = "UTF-8">
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace = "com.learn.chapter4.mapper.StudentMapper">
<resultMap id = "studentMap" type = "com.learn.chpater4.po.StudentBean">
<id property = "id" column = "id"/>
<result property = "cnname" column = "cnname"/>
<result property = "sex" column = "sex" jdbcType = "INTEGER" javaType = "com.learn.chapter4.enums.SexEnum"
typeHandler = "com.learn.chapter4.typehandler.SexTypeHandler"/>
<result property = "note" column = "note"/>
<association property = "studentSelfcard" column = "id" select = "com.learn.chapter4.mapper.StudentSelfcardMapper.findStudentSelfcardByStudentId"/>
</resultMap>
<select id = "getStudent" parameterType = "int" resultMap = "studentMap">
select id, cnname, sex, note from t_student where id = #{id}
</select>
</mapper>

  最后,做一下测试就可以了;

SqlSession sqlSession = null;
try{
sqlSession = SqlSessionFactoryUtil.openSqlSession();
StduentMapper stuMapper = sqlSession.getMapper(StudentMapper.class);
StudentBean stu = stuMapper.getStudent(1);
}finally{
if(sqlSession != null){
sqlSession.close();
}
}
接下来是collection一对多级联;
这个时候我们就要先建立一个LectureBean 的POJO来记录课程,而学生课程表则建立一个StudentLectureBean来记录成绩,里面有一个类型为LectureBean属性的lecture,用来记录学生成绩;毕竟学生课程表里面要有多个课程,所以我们建立了一个类型为lectureBean属性的lecture;
下面是LectureBean和StudentLectureBean设计;

public class LectureBean{
private Integer id;
private String lectureName;
private String note;
...setter and getter...
}
public class StudentLectureBean{
private int id;
private Integer studentId;
private LectureBean lecture;
private BigDecimal grade;
private String nte;
}

  接下来我们做一对多的级联;

<?xml version = "1.0" encoding = "UTF-8">
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace = "com.learn.chpater4.mapper.StudentMapper">
<resultMap id = "studentMap" type = "com.learn.chpater4.po.StudentBean">
<id property = "id" column = "id"/>
<result property = "cnname" column = "cnname"/>
<result property = "sex" column = "sex" jdbcType = "INTEGER"
javaType = "com.learn.chapter4.enums.SexEnum"
jdbcType = "com.learn.chapter4.typehandler.SexTypeHandler"/>
<result property = "note" column = "note"/>
<association property = "studentSelfcard" column = "id" select = "com.learn.chapter4.mapper.StudentSelfcardMapper.findStudentSelfcardByStudentId"/>
<collection property = "studentLectureList" column = "id" select = "com.learn.chapter4.mapper.StudentLectureMapper.findStudentLectureByStudentId"/>
</resultMap>
<select id = "getStudent" parameterType = "int" resultMap = "studentMap">
select id, cnname, sex, note from t_student where id = #{id}
</select>
</mapper>

     StudentLectureMapper.xml

<?xml version = "1.0" encoding = "UTF-8">
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace = com.learn.chapter4.mapper.StudentLectureMapper">
<resultMap id = "studentLectureMap" type = "com.learn.chpater4.po.StudentLectureBena">
<id property = "id" column = "id"/>
<id property = "studentId" column = "student_id"/>
<id property = "grade" column = "grade"/>
<id property = "note" column = "note"/>
<association property = "lecture" column = "lecture_id" select = "com.learn.chpater4.mapper.LectureMapper.getLecture"/>
</resultMap>
<select id = "findStudentLectureByStuId" parameterType = "int" resultMap = "studetntLectureMap">
select id, student_id,lecture_id,grade,note from t_student_lecture where student_id = #{id}
</select>
</mapper>

         LectureMapper.xml

<?xml version = "1.0" encoding = "UTF-8">
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace = "com.learn.chapter4.mapper.LectureMapper">
<select id = "getLecture" parameterType = "int" resultTYpe = "com.learn.chapter4.po.LectureBean">
select id,lecture_name as lectureName,note from t_lecture where id = #{id}
</select>
</mapper>

  下面是一对多的测试类;

Logger logger = Logger.getLogger(Chpater4Main.class);
SqlSession sqlSession = null;
try{
sqlSession = SqlSessionFactoryUtil.openSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
StudentBean student = studentMapper/getStudent(1);
logger.info(student.getStudentSelfcard().getNative_());
StudentLectureBean studentLecture = student.getStudentLectureList().get(0);
LectureBean lecture = studentLecture.getLecture();
logger.info(student.getCnname() + "\t" + lecture.getLectureName())
}finally{
if(sqlSession != null){
sqlSession.close();
}
}
discriminator鉴别器级联;
先来看个设计;

public class MaleStudentBean extends StudentBean{
privaate List<StudentHealthMaleBean> studentHealthMaleList = null;
}
public class FemaleStudentBean extends StudentBean{
private List<StudentHealthFemaleBean> studentHealthFemaleList = null;
}

  下面是鉴别器的内容;

<?xml version = "1.0" encoding = "UTF-8">
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace = "com.learn.chpater4.mapper.StudentMapper">
<resultMap id = "studentMap" type = "com.learn.chapter4.po.StudentBean">
<id property = "id" column = "id"/>
<result property = "cnname" column = "cnname"/>
<result property = "sex" column = "sex" jdbcType = "INTEGER" typeHandler = "com.learn.chpater4.typeHandler.SexTypeHandler"/>
<result property = "note" column = "note"/>
<association property = "studentSelfcard" column = "id" select = "com.learn.chapter4.mapper.StudentSelfcardMapper.findStudentSelfcardByStudentId"/>
<collection property = "studentLectureList" column = "id" select = "com.learn.chpater4.mapper.StudentLectureMapper.findStudentLectureByStuId"/>
<discriminator javaType = "int" column = "sex">
<case value = "1" resultMap = "maleStudentMap"/>
<case value = "2" resultMap = "femaleStudentMap"/>
</discriminator>
</resultMap>
<select id = "getStudent" parameterType = "int" resultMap = "studentMap">
select id,cnname,sex,note form t_student where id = #{id}
</select>
<resultMap id = "maleStudentMap" type = "com.learn.chpater4.po.MaleStudentBean" extends = "studentMap">
<collection property = "studentHealthMaleList" select = "com.learn.chapter4.mapper.StudentHealthMaleMapper.findStudentHealthMaleByStuId" column = "id"/>
</resultMap>
<resultMap id = "femaleStudentMap" type = "com.learn.chapter4.po.FemaleStudentBean" extends = "studentMap">
<collection property = "studentHealthFemaleList" select = "com.learn.chapter4.mapper.StudentHealthFemaleMapper.findStudentHealthFemaleByStuId" column = "id"/>
</resultMap>
</mapper>

  

一个是鉴别器的关键代码;
        <discriminator javaType = "int" column = "sex">
接下来是继承类
    extends = "studentMap"
    接下来是关于延迟加载的问题,我们既然,学了关于级联的相关操作就知道,我们如果只是想要查找某一个对象的话,如果是通过级联,我们可能会不经意地把相关的数据也给查了出来,这样就会造成性能的问题,所以我们提出来两个概念,延迟加载LazyLoadingEnabled和完整加载aggressiveLazyLoading;其中,如果你将延迟加载设置为true,即表示可以按需加载,不然的话就是即时加载,而完整加载的意思是你是按照层次来加载呢?还是一次性全部加载,如果说你想找的课程成绩,而查找课程成绩,你就会相关地查找到学生证信息,但这不是我们想要的,所以,我们这个时候就要按照层次加载了,我们要将aggressiveLazyLoading设置为false,即关闭掉完整加载;
    上面的这两个加载都是通过mybatisXML文件来设置加载的;

<settings>
<setting naem = "lazyLoadingEnabled" value = "true"/>
</settings>

  这是开启延迟加载的;

<setting name = "aggressiveLazyLoading" value = "false"/>
这个是关闭掉完整加载,实现层次加载;
但是现在又有一个问题出现了,我们在xml文件中设置的相当于全局变量,而我们有时候有些文件需要实现延迟和层次,而有些又不用,这个时候,我们可以使用局部变量设置的方式来实现;
代码如下;

<association property = "studentSelfcard" column = "id" fetchType = "lazy"
select = "com.learn.chapter4.mapper.StudentSelfcardMapper.findStudentSelfcardByStudentId"/>
<collection property = "studentLectureList" column = "id" fetchType = "eager"
select = "com.learn.chapter4.mapper.StudentLectureMapper.findStudentLectureByStuId"/>
这个时候,你把aggressiveLazyLoading设置为false,这样的话,完整加载关闭,层次加载实现,而设置为lazy的为延迟层次加载,eager的为即时完整加载了;
    讲完了三层吉级联,我们来讲讲二层缓存;概念较为简单,所谓一级缓存是指建立在SqlSession的层面上的,如果在你的SqlSession还没有commit提交之前的话,用SqlSession所创建出来的对象可以进行多次查询,而二级缓存则是建立在SqlSessionFactory的层面上,能够实现SqlSession的对象共享;
而默认二级缓存是关闭的,需要手动开启;
开启的方式也很简单,只需要在映射XML文件配置就可以了;

<cache/>

  

MyBatis的三层级联和二层缓存的更多相关文章

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

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

  2. MyBatis高级篇之整合ehcache缓存框架

    MyBatis高级篇之整合ehcache缓存框架  2017-09-01  0 Comments  1,671 Views  0 Times 一.前言 MyBatis为我们提供了Cache接口,也提供 ...

  3. SSM框架之Mybatis(7)延迟加载、缓存及注解

    Mybatis(7)延迟加载.缓存及注解 1.延迟加载 延迟加载: 就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据.延迟加载也称懒加载. **好处:**先从单表查询,需要时再从关联表去关 ...

  4. Mybatis源码研究7:缓存的设计和实现

    Mybatis源码研究7:缓存的设计和实现 2014年11月19日 21:02:14 酷酷的糖先森 阅读数:1020   版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog ...

  5. Mybatis基于注解开启使用二级缓存

    关于Mybatis的一级缓存和二级缓存的概念以及理解可以参照前面文章的介绍.前文连接:https://www.cnblogs.com/hopeofthevillage/p/11427438.html, ...

  6. MyBatis学习笔记(2)--缓存

    一.什么是缓存 --存在于内存中的临时数据. 为什么使用缓存?--减少和数据库的交互次数,提高执行效率. 适用于缓存的数据: 1.经常查询并且不经常改变的数据. 2.数据的正确与否对最终结果影响较小的 ...

  7. Mybatis中使用级联查询,一对多的查询

    一.需求描述 自己在开发一个小程序的过程中,需要做的一个查询是稍微比较复杂的查询,根据用户信息去查询用户所对应的宠物信息. 一个用户可能对应多个宠物,所以在用户和宠物信息的对应关系就是一对多的关系. ...

  8. mybatis多参数传递,延迟加载,缓存,注解开发

    1.Mybatis的多参数传递方式 需求:更具id 和 名字查询用户: select * from user where id = ? and name = ?: 1):QueryVo 或者 User ...

  9. MyBatis 中的级联

    MyBatis 的级联分为 3 种. 1.鉴别器(discriminator):它是根据某些条件决定采用具体实现类级联的方案,比如体检表要根据性别去区分. 2.一对一(association):比如学 ...

随机推荐

  1. python入门学习笔记(二)

    6.6替换元素 7.tuple类型 7.1创建tuple 7.2创建单元素tuple    7.3"可变"的tuple 8.条件判断和循环 8.1,if语句   8.2,if... ...

  2. 将Word表格中单元格中的文字替换成对应的图片

    示例 原文件结构: 替换后文档结构: 软件截图: 代码: using System;using System.Collections.Generic;using System.ComponentMod ...

  3. 使用Git的hook实现代码的自动部署

    这个功能非常的好用,可以省去诸多麻烦!我自己也是摸索了好久,才完全掌握的.希望能对大家有所帮助! 1,首先在我的阿里云服务器上已经创建好了一个代码远程的管理仓库,/srv/cmp.git 2, 在服务 ...

  4. Yii2中后台用前台的代码设置验证码显示不出来?

    我说的是直接修改advanced模板.细心人会发现模板里在contact里有,登录也想要就仿照contact中的做法.前台好了,后台登录也要验证码,就把前台代码拿过来,可惜前后台的SiteContro ...

  5. windows转mac-开发环境搭建(一):mac上搭建maven环境

    1.下载地址:https://maven.apache.org/download.cgi 将下载的maven压缩包进行解压,放入到一个方便管理的文件当中,解压命令:tar zxvf apache-ma ...

  6. python语言基础语法笔记<note2--面向对象编程>

    Python面向对象编程(OOP) 一.面向对象过程的优点特征: 封装 模型的特征和能力打包在一起 模型的改变由模型自身完成 隐藏模型的细节,外界只能使用,不能改变 继承 符合自然界分类规律 快速实现 ...

  7. apue.h头文件(UNIX环境高级编程)

    在看UNIX环境高级编程是,碰到一个头文件"apue.h",搜一下别人的帖子,其实apue.h是作者自己写的一个文件,包含了常用的头文件,系统不自带.其中包含了常用的头文件,以及出 ...

  8. 嵌入式 Linux 与linux启动时自动加载模块

    一.在ARM linux 下,一般而言,产品在启动的过程中应该加载模块,最简单的方法是修改启动过程的rc脚本(/etc/init.d/rcS),增加ismod /../xxx.ko这个命令.例如:加载 ...

  9. Android热修复(动态加载)方案汇总

    整理了以下动态加载的方案,便于在项目中使用时查阅: Dexposed github (https://github.com/alibaba/dexposed) AndFix github (https ...

  10. Emacs编辑器配置

    以前总是用的vim编辑器,今天突然想换emacs 用下.折腾了很久终于搞定.使用的是windows测试环境 emacs下载地址http://ftp.gnu.org/gnu/emacs/windows/ ...