Mybatis中的一对多关系,用collection。
一个学生表,Student,一个老师表,Teacher。一个老师下面有多个学生。学生表有一个字段 teacher_id。
学生表对应的类
1 2 3 4 5 6 7 8 9 10 @Data @Builder @AllArgsConstructor @NoArgsConstructor public class Student { private Integer id; private String name; private Integer teacherId; }
教师类
1 2 3 4 5 6 7 8 9 @Data @Builder @AllArgsConstructor @NoArgsConstructor public class Teacher { private Integer id; private Integer age; }
我们要查出教师及其学生的列表。
教师及学生列表类
1 2 3 4 5 6 7 8 9 10 @Data @Builder @AllArgsConstructor @NoArgsConstructor public class TeacherInfo { private Integer id; private String name; private List<Student> students; }
获取所以教师及学生列表信息的 DAO 层接口。
1 2 3 4 public interface TeacherDao { List<TeacherInfo> findTeachers () ; }
上述接口对应的 xml 文件的核心内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace ="gy.finolo.dao.TeacherDao" > <resultMap id ="teacherInfoMap" type ="gy.finolo.model.TeacherInfo" > <id column ="id" jdbcType ="INTEGER" property ="id" /> <result column ="age" jdbcType ="INTEGER" property ="age" /> <collection property ="students" ofType ="gy.finolo.model.Student" > <result column ="name" property ="name" /> </collection > </resultMap > <select id ="findTeachers" resultMap ="teacherInfoMap" > SELECT t.id, t.age, s.name FROM t_teacher t INNER JOIN t_student s ON (t.id = s.teacher_id); </select > </mapper >
需要说明的有以下几点:
主表和副表的 id 标签都可以不要,这时只是属性里面没有 id 的值而已。我之前以为是以 id 来判断两条记录是否相同的,现在看来并不是。
如果需要获取学生id值,为了避免column字段重复,所以在SQL语句写别名,同时在xml也做相应修改。
1 <id column ="student_id" property ="id" />
1 2 3 <select id ="findTeachers" resultMap ="teacherInfoMap" > SELECT t.id, t.age, s.id student_id, s.name FROM t_teacher t INNER JOIN t_student s ON (t.id = s.teacher_id); </select >