MyBatis复杂的结果集映射(一对多关系)

一对多关系:一个老师对多个学生

对于老师来说就是一对多关系
首先建表:
在这里插入图片描述

拷贝db.properties、log4j.properties、mybatis-config.xml文件
创建Student、Teacher实体类。

package pojo;

import lombok.Data;

@Data
public class Student {
private int id;
private String name;
//学生需要关联一个老师
private int tid;
}
package pojo;

import lombok.Data;

import java.util.List;

@Data
public class Teacher {
private int tid;
private String name;
private List<Student> students;
}

创建StudentMapper、TeacherMapper接口
创建StudentMapper.xml、TeacherMapper.xml文件
在mubatis-config.xml中注册StudentMapper、TeacherMapper映射器。

1.通过结果嵌套查询:

要查找一个老师对应的所有学生:先确定sql语句:

select s.id as sid,s.name as sname,t.name as tname,t.tid from student as s,teacher as t
where s.tid=t.tid and t.tid=#{tid};

因为最终我们的目标是查找老师表然后将实体类Teacher内的students属性映射为学生对象,所以在TeacherMapper接口内写方法:

/**
* 获取指定老师下的所有学生信息
* @return
*/
public Teacher getStudentByTeacher(@Param("tid") int tid);

然后就是在TeacherMapper.xml内 实现方法:

<!--按结果嵌套查询-->
<select id="getStudentByTeacher" parameterType="int" resultMap="TeacherStudent">
select s.id as sid,s.name as sname,t.name as tname,t.tid from student as s,teacher as t
where s.tid=t.tid and t.tid=#{tid};
</select>

<resultMap id="TeacherStudent" type="pojo.Teacher">
<result property="tid" column="tid"/>
<result property="name" column="tname"/>
<collection property="students" ofType="pojo.Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>

下面来解析一下这个实现方法:
首先需要确定sql,那么就需要一个select标签把sql语句放进去,查出来的是老师表,对应的Teacher实体类中有一个List<Student> students属性,正常的查询students的值读不到,所以就需要结果集映射,将Student类对象映射到结果上,所以还需要一个resultMap标签。,在这个标签内,先将Teacher的tid和name映射为别名,然后就是根据结果来嵌套处理映射出的学生对象,因为是一对多关系,所以要用到<collection>标签而不能使用<association>对象标签。而列表标签的映射类型需要用到ofType而不是javaType。然后就是在<collection>标签内部映射学生的属性,将学生的三个属性映射为别名

然后就可以使用测试类测试了。

@Test
public void getStudentByTeacher(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
Teacher studentByTeacher = mapper.getStudentByTeacher(1);
System.out.println(studentByTeacher);
sqlSession.close();
}

可以看到结果为:

Teacher(tid=1, name=秦老师, students=[Student(id=1, name=小明, tid=1), Student(id=2, name=小红, tid=1), Student(id=3, name=小张, tid=1), Student(id=4, name=小李, tid=1), Student(id=5, name=小王, tid=1)])

2.通过子查询嵌套查询:

​首先还是在TeacherMapper接口中写方法,因为查的是teacher表

/**
* 通过子查询方式查询一对多关系
* @param tid
* @return
*/
public Teacher getStudentByTeacher2(@Param("tid") int tid);

然后就是在啊TeacherMapper.xml中实现接口中的方法:

<!--子查询方式-->
<select id="getStudentByTeacher2" parameterType="int" resultMap="TeacherStudent2">
select * from mybatis.teacher where tid = #{tid};
</select>
<resultMap id="TeacherStudent2" type="pojo.Teacher" >
<result property="id" column="id"/>
<result property="name" column="name"/>
<!--java类型是返回值类型也就是列表-->
<collection property="students" javaType="ArrayList" ofType="pojo.Student" select="getStudentByTeacherID" column="tid"/>
</resultMap>
<select id="getStudentByTeacherID" resultType="pojo.Student">
select * from mybatis.student where tid = #{tid};
</select>

这种方式是用两个查询语句嵌套起来使用:就相当于把一个sql语句拆开来看,先按tid查一遍teacher表,然后再按tid查一遍student表,然后再把结果合起来
所以首先要按照tid查teacher表

<select id="getStudentByTeacher2" parameterType="int" resultMap="TeacherStudent2">
select * from mybatis.teacher where tid = #{tid};
</select>

然后再按照tid查一遍student表

<select id="getStudentByTeacherID" resultType="pojo.Student">
select * from mybatis.student where tid = #{tid};
</select>

那么怎么把这两个表关联起来呢,也就是把查出来的student数据列表作为对象映射给teacher的students属性,所以就要用到结果集映射:

<resultMap id="TeacherStudent2" type="pojo.Teacher" >
<!--java类型是返回值类型也就是列表-->
<collection property="students" javaType="ArrayList" ofType="pojo.Student" select="getStudentByTeacherID" column="tid"/>
</resultMap>

因为id和name与要映射的一样,就可以省略,重点还是看怎么把学生的列表映射给老师的students属性,因为是列表,还是要用到<collection>,那么看一下<collection>中的属性值,property是要被映射的属性,要注意一下在一对多的查询中,<collection>是映射一个列表所需要的标签,所以要传递一个列表的Type,这里也就是ArrayList,所以需要javaType:实体类要被映射属性的数据结构,然后再ofType:实体类要被影射的属性的数据类型,最后关联两个查询,也就是在<collection>标签内嵌套一个查询select,colum就当做传递给子查询的参数也就是参数名。

可以看到最后查询出的结果为:

Teacher(tid=0, name=秦老师, students=[Student(id=1, name=小明, tid=1), Student(id=2, name=小红, tid=1), Student(id=3, name=小张, tid=1), Student(id=4, name=小李, tid=1), Student(id=5, name=小王, tid=1)])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yui方木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值