作用:在Mybaits中collection标签是用来实现连表查询的。
使用的场景:collection的使用场景为1:n和n:n两种情况。
添加的内容:使用collection的时候需要在类中添加关联集合(查询哪个类就在哪个类中添加)。

一、第一种情况:
一对多: 一个班级有多个学生,一个学生只能有一个班级
查询信息:查询班级信息的时候返回学生信息

1、查询班级信息的时候返回学生信息,所以应该在班级类中添加一个学生的信息作为两个表之间的关联,又因为一个班级对应多个学生,所以关联的字段应该是集合。
这里的@Data注解采用了lombok,@JsonFormat和@DateTimeFormat注解是将时间属性的入参和出参格式化,班级类如下:

@Data
public class ClassInfo {
    private Long id;
    private Long classInfoId;
    private String classInfoName;
    @JsonFormat(pattern="yyyy-MM-dd")
    @DateTimeFormat(pattern="yyyy-MM-dd")
    private LocalDateTime classInfoCreateTime;

    private List<Student> studentList;//关联属性:集合
}

学生类没有任何变动:

@Data
public class Student {
    private Long id;
    private Long studentId;
    private String studentName;
    private Long studentClassInfoId;
    private Integer studentSex;
}

2、ClassIndoMapper.xml中的代码如下:

<resultMap id="BaseResultMapWithStudentList" type="com.example.demo.entity.ClassInfo">
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="class_info_id" jdbcType="BIGINT" property="classInfoId" />
    <result column="class_info_name" jdbcType="VARCHAR" property="classInfoName" />
    <result column="class_info_create_time" jdbcType="TIMESTAMP" property="classInfoCreateTime" />
    <collection property="studentList" column="class_info_id" select="com.example.demo.mapper.StudentMapper.selectStudentByClassId"/>
</resultMap>

<select id="classInfoSelectAll" resultMap="BaseResultMapWithStudentList">
    select * from class_info
</select>

3、StudentMapper.xml中的代码如下:

<select id="selectStudentByClassId" resultType="com.example.demo.entity.Student">
    select * from student where student_class_info_id = #{id}
</select>

4、ClassInfo的controller层如何调用如下:

@RequestMapping("classInfoSelectAll")
@ResponseBody
public List<ClassInfo> classInfoSelectAll(){
    return classInfoService.classInfoSelectAll();
}

5、查询结果如下图:
在这里插入图片描述
二、第二种情况:
多对多: 一个教师教多个班级,一个班级被多个教师教
查询信息:查询教师信息的时候返回班级信息

1、教师类中添加班级集合(第一种情况中谈到了哦):

@Data
public class Teacher {
    private Long id;
    private Long teacherId;
    private Integer teacherSex;
    private String teacherName;

    private List<ClassInfo> classInfoList;//关联属性:集合
}

班级类没有任何变动:

@Data
public class ClassInfo {
    private Long id;
    private Long classInfoId;
    private String classInfoName;
    @JsonFormat(pattern="yyyy-MM-dd")
    @DateTimeFormat(pattern="yyyy-MM-dd")
    private LocalDateTime classInfoCreateTime;
}

2、TeacherMapper.xml中的代码如下:

<resultMap id="BaseResultMapWithClassInfo" type="com.example.demo.entity.Teacher">
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="teacher_id" jdbcType="BIGINT" property="teacherId" />
    <result column="teacher_sex" jdbcType="INTEGER" property="teacherSex" />
    <result column="teacher_name" jdbcType="VARCHAR" property="teacherName" />
    <collection property="classInfoList" column="teacher_id" select="com.example.demo.mapper.ClassInfoMapper.selectClassInfoByTeacherId"/>
</resultMap>

<select id="teacherSelectAll" resultMap="BaseResultMapWithClassInfo">
    select * from teacher
</select>

association与collection不同的是,association标签内property属性接受的是对象,而collection标签内property属性接受的是集合。teacher表中的teacher_id作为下一条执行sql的入参,select属性中的内容为下一条sql执行的位置,执行下一条sql后将其结果映射到property属性的classInfoList集合中。

3、ClassInfoMapper.xml中的代码如下:

<select id="selectClassInfoByTeacherId" resultType="com.example.demo.entity.ClassInfo">
    SELECT
     c.*
    FROM
     class_info c
 LEFT JOIN ( SELECT r.* FROM relationship_teacher_class r LEFT JOIN teacher t ON r.teacher_id = t.teacher_id ) x
     ON c.class_info_id = x.class_info_id
    WHERE
     x.teacher_id = #{id}
</select>

这里使用到了left join连表查询,教师和班级是多对多关系,其中关联表作为连接两张表的桥梁。利用入参在关联表中找出相应的班级ID的集合和其对应的教师ID作为一个新表,然后利用班级ID作为连接条件连接新表和班级表查询出班级信息。

4、teacher的controller层如何调用如下:

@RequestMapping("teacherSelectAll")
@ResponseBody
public List<Teacher> teacherSelectAll(){

    return teacherService.teacherSelectAll();
}

5、查询结果如下图:
在这里插入图片描述
在这里插入图片描述

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐