mybatis应用开发(14)映射之嵌套查询

     2022-03-16     422

关键词:

1.1.1. 嵌套查询

使用association结点的select属性可以建立嵌套查询。前文介绍的不使用select的方法在主表结果记录集包含N条记录,每个记录对应1条子表记录的情况下,总共执行一条SQL语句就可以满足整个查询操作的要求,而本文介绍的select属性建立嵌套查询的方法,则

需要执行1+NSQL语句(单向关联),或者1+N*2条语句(双向关联)

 

Mapper配置:

<!-- 主表resultMap:Person和IdCard的一对一关联:双向关联,嵌套查询 -->

<resultMap type="com.test.mybatis3.pojo.Person" id="personAndIdCardEmbeddedResultMap">

<id property="id" column="id" />

<result  property="name" column="name" />

<result  property="status" column="status" />

 

<!-- Person通过idCard属性导航到IdCard -->

<association property="idCard" javaType="com.test.mybatis3.pojo.IdCard" column="id" select="findIdCardByCardId">

</association>

 

</resultMap>

 

<!-- 子表resultMap:IdCard的映射 -->

<resultMap type="com.test.mybatis3.pojo.IdCard" id="idCardResultMap">

<id property="cardid" column="cardid" />

<result property="personid" column="personid" />

 

<!-- IdCard通过person属性导航到Person -->

<association property="person" column="personid" select="findPersonByPersonId">

</association>

</resultMap>

 

<!-- 主表:查找 Person和对应的IdCard:双向关联-->

<select id="findPersonAndIdCardEmbeded" resultMap="personAndIdCardEmbeddedResultMap">

select * from t_person

</select>

 

<!-- 子表:通过personid查找IdCard -->

<select id="findIdCardByCardId" parameterType="string" resultMap="idCardResultMap">

select * from t_idcard where personid=#{personid}

</select>

 

<!-- 用于IdCard的映射中从personid查找Person -->

<select id="findPersonByPersonId" parameterType="string" resultType="com.test.mybatis3.pojo.Person" >

select * from t_person where id=#{id}

</select>

 

 

 

Mapper接口:

/**

 * 嵌套查询:Person和IdCard.

 * @return

 * @throws Exception

 */

List<Person> findPersonAndIdCardEmbeded() throws Exception;

 

 

单元测试代码:

//打开Session。

session = sessionBuilder.openSession();

 

//找到MyBatis自动实现的PersonMapper接口的代理对象。

PersonMapper  personMapper = session.getMapper(PersonMapper.class);

 

//嵌套查询。

List<Person> persons = personMapper.findPersonAndIdCardEmbeded();

//输出查询结果。

for(Person person : persons){

System.out.println(person);

System.out.println(person.getIdCard());

//查看person和idCard的person是否同一个对象。

System.out.println(person == person.getIdCard().getPerson());

}

 

运行结果如下:

 

1    [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findPersonAndIdCardEmbeded  - ==>  Preparing: select * from t_person

43   [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findPersonAndIdCardEmbeded  - ==> Parameters:

67   [main] TRACE com.test.mybatis3.mapper.PersonMapper.findPersonAndIdCardEmbeded  - <==    Columns: id, name, status

67   [main] TRACE com.test.mybatis3.mapper.PersonMapper.findPersonAndIdCardEmbeded  - <==        Row: lisi, li si, 0

70   [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findIdCardByCardId  - ====>  Preparing: select * from t_idcard where personid=?

70   [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findIdCardByCardId  - ====> Parameters: lisi(String)

71   [main] TRACE com.test.mybatis3.mapper.PersonMapper.findIdCardByCardId  - <====    Columns: personid, cardid

72   [main] TRACE com.test.mybatis3.mapper.PersonMapper.findIdCardByCardId  - <====        Row: lisi, 222222222222222222

72   [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findPersonByPersonId  - ======>  Preparing: select * from t_person where id=?

72   [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findPersonByPersonId  - ======> Parameters: lisi(String)

72   [main] TRACE com.test.mybatis3.mapper.PersonMapper.findPersonByPersonId  - <======    Columns: id, name, status

73   [main] TRACE com.test.mybatis3.mapper.PersonMapper.findPersonByPersonId  - <======        Row: lisi, li si, 0

74   [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findPersonByPersonId  - <======      Total: 1

74   [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findIdCardByCardId  - <====      Total: 1

74   [main] TRACE com.test.mybatis3.mapper.PersonMapper.findPersonAndIdCardEmbeded  - <==        Row: zhangsan, zhang san, 0

75   [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findIdCardByCardId  - ====>  Preparing: select * from t_idcard where personid=?

75   [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findIdCardByCardId  - ====> Parameters: zhangsan(String)

75   [main] TRACE com.test.mybatis3.mapper.PersonMapper.findIdCardByCardId  - <====    Columns: personid, cardid

77   [main] TRACE com.test.mybatis3.mapper.PersonMapper.findIdCardByCardId  - <====        Row: zhangsan, 1111111111111111

77   [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findPersonByPersonId  - ======>  Preparing: select * from t_person where id=?

78   [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findPersonByPersonId  - ======> Parameters: zhangsan(String)

78   [main] TRACE com.test.mybatis3.mapper.PersonMapper.findPersonByPersonId  - <======    Columns: id, name, status

78   [main] TRACE com.test.mybatis3.mapper.PersonMapper.findPersonByPersonId  - <======        Row: zhangsan, zhang san, 0

78   [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findPersonByPersonId  - <======      Total: 1

79   [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findIdCardByCardId  - <====      Total: 1

79   [main] DEBUG com.test.mybatis3.mapper.PersonMapper.findPersonAndIdCardEmbeded  - <==      Total: 2

Person [id=lisi, name=li si, status=0,address=null]

IdCard [cardid=222222222222222222, personid=lisi, person=Person [id=lisi, name=li si, status=0,address=null]]

false

Person [id=zhangsan, name=zhang san, status=0,address=null]

IdCard [cardid=1111111111111111, personid=zhangsan, person=Person [id=zhangsan, name=zhang san, status=0,address=null]]

false

 

观察运行结果可以发现,在双向关联的情况下,主表2条记录(N=2),总共执行了1+N+N=5SQL语句。如果换成让MyBatis做单向关联,在Service方法中编写代码实现反向关联,则只需要执行1+NSQL语句。

 

mybatis注解开发之一对多查询(代码片段)

文章目录0.MyBatis的注解实现复杂映射开发1.一对多查询1.1一对多查询的模型1.2一对多查询的语句1.3创建StudentMapper接口1.4使用注解配置Mapper1.5测试类1.6一对多配置总结0.MyBatis的注解实现复杂映射开发实现复杂关系映射之前我们可以... 查看详情

mybatis注解开发之一对一查询(代码片段)

文章目录0.MyBatis的注解实现复杂映射开发1.一对一查询1.1一对一查询的模型1.2一对一查询的语句1.3创建PersonMapper接口1.4使用注解配置Mapper1.5测试类1.6一对一配置总结0.MyBatis的注解实现复杂映射开发实现复杂关系映射之前我们可以... 查看详情

mybatis注解开发之多对多查询(代码片段)

文章目录0.MyBatis的注解实现复杂映射开发1.多对多查询1.1多对多查询的模型1.2多对多查询的语句1.3添加CourseMapper接口方法1.4使用注解配置Mapper1.5测试类1.6多对多配置总结0.MyBatis的注解实现复杂映射开发实现复杂关系映射之前我们... 查看详情

mybatis应用开发(10)映射之结果映射resulttype

1.1. resultType1.1.1. 结果为单条记录查询结果为单条记录时,resultType应该为一个JavaBean类型。 select语句的查询结果字段列表可以和resultType指定的JavaBean类型的属性列表不同,字段可以没有对应的属性,属性也可以没有对... 查看详情

mybatis应用开发(16)延迟加载之概念

1.1.1. 延迟加载的概念延迟加载是指在存在关联关系时,在加载主表数据时,仅仅加载主表数据到映射的JavaBean对象中,而不会立即将关联的子表数据加载到存在关联关系的从属JavaBean中。在访问到关联的JavaBean的有关方法时,... 查看详情

mybatisxml数据层框架应用--mybatis关系映射之一对多关系映射

...到了对象与对象之间的关联关系。针对多表之间的操作,MyBatis提供了关联映射,通过关联映射就可以很好的处理对象与对象之间的关联关系。目录你需要了解的知识点1、关联关系种类数据库:java2、关联查询方式使用1、创建实... 查看详情

mybatis应用开发(12)映射之结果映射resultmap

1.1.1. 使用resultMap映射字段和属性MyBatis的resultMap可以方便的定义字段和属性之间的映射关系,字段和属性的名称可以相同,也可以不相同。<!--personResultMap:将t_person的记录的字段映射到SomeBean的属性上--><resultMaptype="com.tes... 查看详情

mybatis学习09高级映射之一对多查询

上一篇博文总结了一下一对一的映射,本文主要总结一下一对多的映射,从上一篇文章中的映射关系图中可知,订单项和订单明细是一对多的关系,所以本文主要来查询订单表,然后关联订单明细表,这样就有一对多的问题出来... 查看详情

mybatis学习10高级映射之多对多查询

本文来总结一下mybatis中的多对多映射,从第8节的文章中可以看出,用户表和商品表示多对多关系,它们两的多对多是通过订单项和订单明细这两张表所关联起来的,那么这一节主要来总结一下用户表和商品表之间的多对多映射... 查看详情

mybatis应用开发(15)映射之一对多关联

1.1.1. 一对多关联一个Person可以拥有一个或多个Address,而每个Address对应于唯一一个Person,因此Person和Address之间存在一对多的关系。本文介绍使用MyBatis如何进行基于List的一对多映射。 Person类:/***@Title:Person.java*@Packagecom.te... 查看详情

mybatis应用开发应用之开发方式api方式篇

1.1. API方式 1.1.1. 开发步骤目标:使用MyBatis从数据库中查询t_person表的全部记录。 MyBatis还可以使用直接使用API来配置数据库中的记录与Java对象之间的映射关系以及其它各种必需的配置。此时不再需要使用任何XML配... 查看详情

mybatis一对一映射

From《MyBatis从入门到精通》  <!--6.1高级映射结果杂谈:在RBAC权限系统中还存在着一个用户拥有多个角色,一个角色拥有多个权限这样复杂的嵌套关系。在面对这种关系时,我们可以写出多个方法分别查询这些数据,然... 查看详情

5.mybatis一对一表关联查询

方式一:嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集,封装联表查询的数据(去除重复的数据) SELECT*FROMclassc,teachertWHEREc.tid=t.tidANDc.cid=#{id}方式二:嵌套查询,通过执行另外一个SQL映射语句来返回预期的复杂类... 查看详情

mybatis学习第20节--嵌套结果

执行流程先执行关联查询,一次性将所有数据都查询出来再将所有查询出来的列组织成嵌套的结果对象其实是与嵌套查询的区别在于,嵌套结果是将每次查询出来的结果集进行组装,嵌套查询是依照结果集中的某个column比如说id来去... 查看详情

mybatis应用开发(11)映射之结果映射字段别名和hashmap

1.1.1. 字段别名的特殊功能通过SQL语句的字段别名功能,可以将记录映射到resultType指定的JavaBean类型的属性的属性上。 <!--通过定义select语句的字段别名为XXX.YYY的形式,可以将字段值赋值给PersonWrapper类的属性person的属性... 查看详情

mybatis学习xml配置文件之sql映射的xml文件

SQL映射文件常用的元素:  1.select  查询语句是MyBatis最常用的语句之一。  执行简单查询的select元素是非常简单的:<selectid=”selectUser”parameterType=”int”resultType=”hashmap”>    SELECT*FROMPERSONWHEREID=#{id}</select>... 查看详情

mybatis应用开发映射之参数绑定parametertype

 1.1. parameterTypeparameterType表示SQL语句中存在占位符,对应于Mapper接口中对应方法的参数。当SQL语句中只有一个占位符时,parameterType可以是Java基本类型,也可以是JavaBean类型。当存在多个占位符时,parameterType只能是JavaBean... 查看详情

mybatis嵌套查询解析(代码片段)

Mybatis表现关联关系比hibernate简单,没有分那么细致one-to-many、many-to-one、one-to-one。而是只有两种association(一)、collection(多),表现很简洁。下面通过一个实例,来展示一下Mybatis对于常见的一对多和... 查看详情