与association一样,collection元素也有两种形式,现介绍如下:
一、嵌套的resultMap
实际上以前的示例使用的就是这种方法,今天介绍它的另一种写法。还是以教师映射为例,修改映射文件TeacherMapper.xml如下(点击此处进入嵌套resultMap形式的示例源码下载页面。注:本示例代码是在修改本系列的上篇博文示例代码的基础上完成的,用到了MapperScannerConfigurer和注解等知识。对这些知识不熟悉的读者,可参考上篇博文:http://legend2011.blog.51cto.com/3018495/980150):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
<?
xml
version
=
"1.0"
encoding
=
"utf8"
?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--与以前一样,namespace的值是对应的映射器接口的完整名称-->
<
mapper
namespace
=
"com.abc.mapper.TeacherMapper"
>
<!--TeacherMapper接口中getById方法对应的SQL语句。
查询教师及其指导的学生的信息。由于教师、学生都有
id、name、gender等属性,因此给教师的字段都起了别名-->
<
select
id
=
"getById"
parameterType
=
"int"
resultMap
=
"supervisorResultMap"
>
select t.id t_id, t.name t_name, t.gender t_gender,
t.research_area t_research_area, t.title t_title,
s.id,s.name, s.gender,s.major,s.grade
from teacher t,student s where t.id=#{id}
and s.supervisor_id = t.id
</
select
>
<!--教师实体映射-->
<
resultMap
id
=
"supervisorResultMap"
type
=
"Teacher"
>
<
id
property
=
"id"
column
=
"t_id"
/>
<
result
property
=
"name"
column
=
"t_name"
/>
<
result
property
=
"gender"
column
=
"t_gender"
/>
<
result
property
=
"researchArea"
column
=
"t_research_area"
/>
<
result
property
=
"title"
column
=
"t_title"
/>
<!--需要注意的是,上面的select语句中学生的字段名/别名应与
下面的column属性一致。ofType指collection包含的元素的类型,
此属性不可少-->
<
collection
property
=
"supStudents"
ofType
=
"Student"
>
<
id
property
=
"id"
column
=
"id"
/>
<
result
property
=
"name"
column
=
"name"
/>
<
result
property
=
"gender"
column
=
"gender"
/>
<
result
property
=
"major"
column
=
"major"
/>
<
result
property
=
"grade"
column
=
"grade"
/>
<!--映射学生的指导教师属性,用到了
supervisorResultMap本身-->
<
association
property
=
"supervisor"
resultMap
=
"supervisorResultMap"
/>
</
collection
>
</
resultMap
>
</
mapper
>
|
运行程序结果如下:
与以前的写法相比,这种写法的缺点是学生实体映射被嵌入到教师实体映射中,因此学生实体映射不能被重用。
二、嵌套的select语句
这种方式是使用一条单独的select语句来加载关联的实体(在本例中就是学生实体),然后在collection元素中引用此select语句(注:此方法会产生N+1问题,关于这个问题可参考本系列博客中的“MyBatis中的N+1问题”)。首先修改TeacherMapper.xml如下(点击此处进入嵌套select语句形式示例源码下载页面):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<?
xml
version
=
"1.0"
encoding
=
"utf8"
?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--与以前一样,namespace的值是对应的映射器接口的完整名称-->
<
mapper
namespace
=
"com.abc.mapper.TeacherMapper"
>
<!--TeacherMapper接口中getById方法对应的SQL语句。
查询教师的信息。-->
<
select
id
=
"getById"
parameterType
=
"int"
resultMap
=
"supervisorResultMap"
>
select * from teacher where id=#{id}
</
select
>
<!--教师实体映射-->
<
resultMap
id
=
"supervisorResultMap"
type
=
"Teacher"
>
<
id
property
=
"id"
column
=
"id"
/>
<
result
property
=
"name"
column
=
"name"
/>
<
result
property
=
"gender"
column
=
"gender"
/>
<
result
property
=
"researchArea"
column
=
"research_area"
/>
<
result
property
=
"title"
column
=
"title"
/>
<!--ofType指collection包含的元素的类型,此属性不可少。
column属性指把上述的getById的select语句中的教师id列的值作为参数
传递给将要引用到的下述的getStudents的select语句,此属性不可少。
引用的形式为:命名空间.select语句id-->
<
collection
property
=
"supStudents"
column
=
"id"
ofType
=
"Student"
select
=
"com.abc.mapper.StudentMapper.getStudents"
/>
</
resultMap
>
</
mapper
>
|
在这里把根据指导教师id查询学生信息的SQL语句写在StudentMapper.xml中,并引用其中的学生实体映射studentResultMap。修改StudentMapper.xml如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<?
xml
version
=
"1.0"
encoding
=
"utf8"
?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<
mapper
namespace
=
"com.abc.mapper.StudentMapper"
>
<
resultMap
id
=
"studentResultMap"
type
=
"Student"
>
<
id
property
=
"id"
column
=
"id"
/>
<
result
property
=
"name"
column
=
"name"
/>
<
result
property
=
"gender"
column
=
"gender"
/>
<
result
property
=
"major"
column
=
"major"
/>
<
result
property
=
"grade"
column
=
"grade"
/>
<!--在这里引用supervisorResultMap和getById,
亦采用命名空间名.相关元素id的形式。
column="supervisor_id"属性不可少-->
<
association
property
=
"supervisor"
resultMap
=
"com.abc.mapper.TeacherMapper.supervisorResultMap"
select
=
"com.abc.mapper.TeacherMapper.getById"
column
=
"supervisor_id"
/>
</
resultMap
>
<!--根据指导教师id查询学生信息-->
<
select
id
=
"getStudents"
parameterType
=
"int"
resultMap
=
"studentResultMap"
>
select * from student where supervisor_id = #{id}
</
select
>
</
mapper
>
|
执行结果如下:
从以上可看出,collection的这两种形式与association的两种形式非常相似。
本文转自 NashMaster2011 51CTO博客,原文链接:http://blog.51cto.com/legend2011/985907,如需转载请自行联系原作者