MyBatis 示例-联合查询

本文详细介绍了 MyBatis 中的联合查询,包括嵌套查询(不建议使用,易导致 N+1 问题)和嵌套结果两种方式。文中讲解了一对一、一对多、鉴别器的关系映射,并给出了示例代码,强调了嵌套查询的性能问题及如何通过延迟加载进行优化。最后提到了嵌套结果作为更优的解决方案,避免了 N+1 问题。
摘要由CSDN通过智能技术生成

简介

MyBatis 提供了两种联合查询的方式,一种是嵌套查询,一种是嵌套结果。先说结论:在项目中不建议使用嵌套查询,会出现性能问题,可以使用嵌套结果。

测试类:com.yjw.demo.JointQueryTest,提供了对嵌套查询嵌套结果的测试。

数据库表模型关系

学生信息级联模型关系:链接

image.png

学生信息级联模型关系是一个多种类型关联关系,包含了如下几种情况:

  • 其中学生表是我们关注的中心,学生证表和它是一对一的关联关系;
  • 而学生表和课程成绩表是一对多的关系,一个学生可能有多门课程;
  • 课程表和课程成绩表也是一对多的关系;
  • 学生有男有女,而健康项目也有所不一,所以女性学生和男性学生的健康表也会有所不同,这些是根据学生的性别来决定的,而鉴别学生性别的就是鉴别器。
关联关系

在联合查询中存在如下几种对应关系:

  • 一对一的关系;
  • 一对多的关系;
  • 多对多的关系,实际使用过程中是把多对多的关系分解为两个一对多的关系,以降低关系的复杂度;
  • 还有一种是鉴别关系,比如我们去体检,男女有别,男性和女性的体检项目并不完全一样;

所以在 MyBatis 中联合分为这么3种:association、collection 和 discriminator。

  • association:代表一对一关系;
  • collection:代表一对多关系;
  • discriminator:代表鉴别器,它可以根据实际选择采用哪种类作为实例,允许你根据特定的条件去关联不同的结果集;

嵌套查询(不建议使用)

一对一关系

以学生表作为关注的中心,学生表和学生证表是一对一的关系。POJO 对象和映射文件的实现如下:

StudentDO

public class StudentDO {

    private Long id;
    private String name;
    private Sex sex;
    private Long selfcardNo;
    private String note; private StudentSelfcardDO studentSelfcard; // get set 方法 }

StudentMapper.xml

<!-- 联合查询:嵌套查询 -->
<resultMap id="studentMap1" type="studentDO">
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="name" jdbcType="VARCHAR" property="name" />
    <result column="sex" jdbcType="TINYINT" property="sex"
            typeHandler="com.yjw.demo.mybatis.common.type.SexEnumTypeHandler"/>
    <result column="selfcard_no" jdbcType="BIGINT" property="selfcardNo" />
    <result column="note" jdbcType="VARCHAR" property="note" />
    <!-- 嵌套查询:一对一级联 -->
    <association property="studentSelfcard" column="{studentId=id}"
                 select="com.yjw.demo.mybatis.biz.dao.StudentSelfcardDao.listByConditions" />
</resultMap>

一对一的关系建立通过 <association> 元素实现,该元素中的属性描述如下所示:

  • property:JavaBean 中对应的属性字段;
  • column:数据库的列名或者列标签别名。与传递给 resultSet.getString(columnName) 的参数名称相同。注意: 在处理组合键时,您可以使用 column= "{prop1=col1,prop2=col2}" 这样的语法,设置多个列名传入到嵌套查询语句。这就会把 prop1 和 prop2 设置到目标嵌套选择语句的参数对象中;
  • select:通过这个属性,通过 ID 引用另一个加载复杂类型的映射语句。
  • fetchType: 设置局部延迟加载,它有两个取值范围,即 eager 和 lazy。它的默认值取决于你在配置文件settings 的配置,如果没有配置它,默认是 eager,一旦配置了,全局配置(lazyLoadingEnabled)就会被他们覆盖;
一对多关系

以学生表作为关注的中心,学生表和课程表是一对多的关系。POJO 对象和映射文件的实现如下:

StudentDO

public class StudentDO {

    private Long id;
    private String name;
    private Sex sex;
    private Long selfcardNo;
    private String note; private StudentSelfcardDO studentSelfcard; private List<StudentLectureDO> studentLectures; // get set 方法 }

StudentMapper.xml

<!-- 联合查询:嵌套查询 -->
<resultMap id="studentMap1" type="studentDO">
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="name" jdbcType="VARCHAR" property="name" />
    <result column="sex" jdbcType="TINYINT" property="sex"
            typeHandler="com.yjw.demo.mybatis.common.type.SexEnumTypeHandler"/>
    <result column="selfcard_no" jdbcType="BIGINT" property="selfcardNo" />
    <result column="note" jdbcType="VARCHAR" property="note" />
    <!-- 嵌套查询:一对一级联 -->
    <association property="studentSelfcard" column="{studentId=id}"
                 select="com.yjw.demo.mybatis.biz.dao.StudentSelfcardDao.listByConditions" />
    
    <!-- 嵌套查询:一对多级联 -->
    <collection property="studentLectures" column="{studentId=id}"
                select="com.yjw.demo.mybatis.biz
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值