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

2022-08-16 10:47:23

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

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

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

packagepojo;importlombok.Data;@DatapublicclassStudent{privateint id;privateString name;//学生需要关联一个老师privateint tid;}
packagepojo;importlombok.Data;importjava.util.List;@DatapublicclassTeacher{privateint tid;privateString name;privateList<Student> students;}

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

1.通过结果嵌套查询:

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

select s.idas sid,s.nameas sname,t.nameas tname,t.tidfrom studentas s,teacheras twhere s.tid=t.tidand t.tid=#{tid};

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

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

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

<!--按结果嵌套查询--><selectid="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><resultMapid="TeacherStudent"type="pojo.Teacher"><resultproperty="tid"column="tid"/><resultproperty="name"column="tname"/><collectionproperty="students"ofType="pojo.Student"><resultproperty="id"column="sid"/><resultproperty="name"column="sname"/><resultproperty="tid"column="tid"/></collection></resultMap>

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

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

@TestpublicvoidgetStudentByTeacher(){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
*/publicTeachergetStudentByTeacher2(@Param("tid")int tid);

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

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

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

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

然后再按照tid查一遍student表

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

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

<resultMapid="TeacherStudent2"type="pojo.Teacher"><!--java类型是返回值类型也就是列表--><collectionproperty="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)])
  • 作者:yui方木
  • 原文链接:https://blog.csdn.net/weixin_44976835/article/details/111473410
    更新时间:2022-08-16 10:47:23