简介
MyBatis 提供了两种联合查询的方式,一种是嵌套查询,一种是嵌套结果。先说结论:在项目中不建议使用嵌套查询,会出现性能问题,可以使用嵌套结果。
测试类:com.yjw.demo.JointQueryTest,提供了对嵌套查询和嵌套结果的测试。
数据库表模型关系
学生信息级联模型关系:链接
学生信息级联模型关系是一个多种类型关联关系,包含了如下几种情况:
- 其中学生表是我们关注的中心,学生证表和它是一对一的关联关系;
- 而学生表和课程成绩表是一对多的关系,一个学生可能有多门课程;
- 课程表和课程成绩表也是一对多的关系;
- 学生有男有女,而健康项目也有所不一,所以女性学生和男性学生的健康表也会有所不同,这些是根据学生的性别来决定的,而鉴别学生性别的就是鉴别器。
关联关系
在联合查询中存在如下几种对应关系:
- 一对一的关系;
- 一对多的关系;
- 多对多的关系,实际使用过程中是把多对多的关系分解为两个一对多的关系,以降低关系的复杂度;
- 还有一种是鉴别关系,比如我们去体检,男女有别,男性和女性的体检项目并不完全一样;
所以在 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