0%

Mybatis一对多关系collection

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">
<!-- <id column="student_id" property="id" /> -->
<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>

需要说明的有以下几点:

  1. 主表和副表的 id 标签都可以不要,这时只是属性里面没有 id 的值而已。我之前以为是以 id 来判断两条记录是否相同的,现在看来并不是。

  2. 如果需要获取学生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>