与association同样,collection元素也有两种形式,现介绍以下: html
1、嵌套的resultMap mybatis
实际上之前的示例使用的就是这种方法,今天介绍它的另外一种写法。仍是以教师映射为例,修改映射文件TeacherMapper.xml以下(点击此处进入嵌套resultMap形式的示例×××页面。注:本示例代码是在修改本系列的上篇博文示例代码的基础上完成的,用到了MapperScannerConfigurer和注解等知识。对这些知识不熟悉的读者,可参考上篇博文:http://legend2011.blog.51cto.com/3018495/980150): app
<?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>
运行程序结果以下: ide
与之前的写法相比,这种写法的缺点是学生实体映射被嵌入到教师实体映射中,所以学生实体映射不能被重用。 学习
2、嵌套的select语句 spa
这种方式是使用一条单独的select语句来加载关联的实体(在本例中就是学生实体),而后在collection元素中引用此select语句(注:此方法会产生N+1问题,关于这个问题可参考本系列博客中的“MyBatis中的N+1问题”)。首先修改TeacherMapper.xml以下(点击此处进入嵌套select语句形式示例×××页面): 日志
<?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以下: xml
<?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>
执行结果以下: htm
从以上可看出,collection的这两种形式与association的两种形式很是类似。 blog
MyBatis技术交流群:188972810,或扫描二维码:
【MyBatis学习笔记】系列之预备篇一:ant的下载与安装
【MyBatis学习笔记】系列之二:MyBatis增删改示例
【MyBatis学习笔记】系列之三:MyBatis的association示例
【MyBatis学习笔记】系列之四:MyBatis association的两种形式
【MyBatis学习笔记】系列之五:MyBatis与Spring集成示例
【MyBatis学习笔记】系列之六:MyBatis与Spring集成示例续
【MyBatis学习笔记】系列之七:MyBatis一对多双向关联
【MyBatis学习笔记】系列之八:MyBatis MapperScannerConfigurer配置
【MyBatis学习笔记】系列之九:MyBatis collection的两种形式
【MyBatis学习笔记】系列之十:MyBatis日志之Log4j示例
【MyBatis学习笔记】系列之十一:MyBatis多参数传递之注解方式示例
【MyBatis学习笔记】系列之十二:MyBatis多参数传递之默认命名方式示例
【MyBatis学习笔记】系列之十三:MyBatis多参数传递之Map方式示例
【MyBatis学习笔记】系列之十四:MyBatis中的N+1问题
【MyBatis学习笔记】系列之十五:MyBatis多参数传递之混合方式
【MyBatis学习笔记】系列之十六:Spring声明式事务管理示例
【MyBatis学习笔记】系列之十七:MyBatis多对多保存示例
【MyBatis学习笔记】系列之十八:MyBatis多对多关联查询示例
【MyBatis学习笔记】系列之十九:如何在MyBatis-3.2.7中使用Log4j2 rc2