mybatis多对多关联查询

多对多关系

一个学生可以选多门课程,而一门课程可以由多个学生选择,这就是一个典型的多对多关联关系。所谓多对多关系,其实是由两个互反的一对多关系组成。即多对多关系都会通过一个中间表来建立,例如选课表。学生对于选课表来说是一对多,课程对于选课表来说也是一对多。

创建数据库表

学生表我们之前已经创建了t_student,这里就不再重新创建了,下面创建一个课程表

CREATE TABLE `t_course` (
  `id` INT NOT NULL,
  `name` VARCHAR(20) NULL,
  PRIMARY KEY (`id`));

选课表:

CREATE TABLE `t_student_course` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `sid` INT NULL,
  `cid` INT NULL,
  PRIMARY KEY (`id`));

初始化数据:

INSERT INTO `t_course` (`id`, `name`) VALUES ('1001', 'SpringMVC');
INSERT INTO `t_course` (`id`, `name`) VALUES ('1002', 'mybatis');
INSERT INTO `t_course` (`id`, `name`) VALUES ('1003', 'Spring');

INSERT INTO `t_student_course` (`sid`, `cid`) VALUES ('1', '1001');
INSERT INTO `t_student_course` (`sid`, `cid`) VALUES ('1', '1002');
INSERT INTO `t_student_course` (`sid`, `cid`) VALUES ('1', '1003');
INSERT INTO `t_student_course` (`sid`, `cid`) VALUES ('3', '1001');
INSERT INTO `t_student_course` (`sid`, `cid`) VALUES ('3', '1002');
INSERT INTO `t_student_course` (`sid`, `cid`) VALUES ('4', '1001');

创建javabean

创建Course类

package com.monkey1024.bean;

import java.util.List;

public class Course {

    private int id;

    private String name;

    private List<Student> students;

    //省略getter、setter和toString
}

在之前的Student类中添加List属性表示课程:

 private List<Course> courses;

创建mapper

<?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="com.monkey1024.dao.CourseDao">

    <resultMap id="courseMapper" type="Course">

        <id property="id" column="cid"/>
        <result property="name" column="cname"/>
        <collection property="students" ofType="Student">
            <id property="id" column="sid"/>
            <result property="name" column="sname"/>
        </collection>
    </resultMap>


    <select id="selectCourseStudent" resultMap="courseMapper">
        SELECT
            c.id cid, c.name cname, s.id sid, s.name sname
        FROM
            t_course c,
            t_student s,
            t_student_course sc
        WHERE
            c.id = #{id}
            AND s.id = sc.sid
            AND c.id = sc.cid;
    </select>
</mapper>

上面sql语句是三张表的关联查询,在collection中表示查询出的学生数据,这里其实可以看做是一对多的查询,因为我们指定了课程编号。

创建Dao

package com.monkey1024.dao;

import com.monkey1024.bean.Course;

public interface CourseDao {

    Course selectCourseStudent(int id);
}

创建测试类

package com.monkey1024.test;

import com.monkey1024.bean.Course;
import com.monkey1024.bean.Employee;
import com.monkey1024.dao.CourseDao;
import com.monkey1024.dao.EmployeeDao;
import com.monkey1024.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.List;

public class CourseTest01 {

    private SqlSession sqlSession;

    private CourseDao courseDao;

    /**
     * 测试时先执行该方法创建EmployeeDao对象
     */
    @Before
    public void initStudentDao(){
        sqlSession = MyBatisUtil.getSqlSession();
        //通过该方法可以获取CourseDao的对象
        courseDao = sqlSession.getMapper(CourseDao.class);
    }

    /**
     * 执行完成后需要关闭sqlSession
     */
    @After
    public void closeSession() {
        if (sqlSession != null) {
            sqlSession.close();
        }
    }

    @Test
    public void selectCourseStudent(){
        Course course = courseDao.selectCourseStudent(1001);
        System.out.println(course);
    }

}

执行结束后可以看到将课程和选择该课程的所有学生全部查询出来了。