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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis应用开发(14)映射之嵌套查询相关的知识,希望对你有一定的参考价值。

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应用开发(14)映射之嵌套查询的主要内容,如果未能解决你的问题,请参考以下文章

Mybatis从入门到精通系列 15——嵌套查询与嵌套结果

MyBatis注解开发之一对多查询

Mybatis结果集映射(resultMap)

MyBatis注解开发之多对多查询

MyBatis注解开发之一对一查询

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