(6)MyBatis之多对多关联

  • 引言
  • MyBatis之多对多
    • 1 创建我们的数据库
    • 2 创建Student持久化类
    • 3 创建Course持久化类
    • 4 创建CS持久化类用于查询某学生某课程的成绩
    • 5 根据需求编写映射文件
      • 51 Student的映射文件
      • 52 Course映射文件
      • 53 CS映射文件
    • 6 编写SQL相应的语句
      • 61 查询选修某课程的所有学生一个Course对象里面有Student数组
      • 62 查询某学生查询的课程信息一个Student对象里面有Course数组
      • 63 查询某学生某课程的成绩信息
    • 7 编写测试类
      • 71 查询选修某课程的所有学生一个Course对象里面有Student数组
      • 72 运行结果
      • 73 查询某学生查询的课程信息一个Student对象里面有Course数组
      • 74 运行结果
      • 75 查询某学生某课程的成绩信息
      • 76 运行结果
  • 代码下载
      • 本博客的代码下载地址为MyBatis之多对多

1.引言

在本篇博客中主要介绍:

  • MyBatis如何建立多对多的关联,在多对多关系中:映射文件应该如何编写,持久化类应该如何写?

2. MyBatis之多对多

在涉及到代码之前,我们先说一下数据库中的表结构:

  • 数据库中有三张表:student表(学生表),course表(课程表),course_student表(学生课程表)
student表:sid学号,sname学生名,hobit爱好
course表:cid课程号,name课程名称,dec课程描述
course_student表,sc_id主键,sid外键,cid外键,grade分数
  • 我们一共有三个需求:

    第一个:查询 选修某课程的学生信息
    第二个:查询 某学生选修的课程信息
    第三个:查询 某学生某课程 的学习成绩
    

2.1 创建我们的数据库

DROP DATABASE IF EXISTS school;
CREATE DATABASE IF NOT EXISTS school;
USE school;
CREATE TABLE `student`(
`sid` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`sname` VARCHAR(32) ,
`hobit` VARCHAR(20)
);
CREATE TABLE `course`(
`cid` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`name` VARCHAR(32) ,
`dec` VARCHAR(20)
);
CREATE TABLE `course_student`(
sc_id INT AUTO_INCREMENT PRIMARY KEY,
sid INT ,
cid INT,
grade INT
);
ALTER TABLE course_student ADD CONSTRAINT  FOREIGN KEY(sid) REFERENCES student(sid);
ALTER TABLE course_student ADD CONSTRAINT  FOREIGN KEY(cid) REFERENCES course(cid);
INSERT INTO `student` (`sid`,`sname`,`hobit`)
VALUES(1,"aaa","喜欢玩游戏");
INSERT INTO `student` (`sid`,`sname`,`hobit`)
VALUES(2,"bbb","喜欢学习");
INSERT INTO `student` (`sid`,`sname`,`hobit`)
VALUES(3,"ccc","喜欢打篮球");
INSERT INTO `course` (`cid`,`name`,`dec`)
VALUES(1,"math","数学课程");
INSERT INTO `course` (`cid`,`name`,`dec`)
VALUES(2,"english","英语课程");
INSERT INTO `course` (`cid`,`name`,`dec`)
VALUES(3,"chinese","语文课程");
INSERT INTO `course_student` (`sid`,`cid`,`grade`)
VALUES(1,1,82);
INSERT INTO `course_student` (`sid`,`cid`,`grade`)
VALUES(1,2,77);
INSERT INTO `course_student` (`sid`,`cid`,`grade`)
VALUES(1,3,65);
INSERT INTO `course_student` (`sid`,`cid`,`grade`)
VALUES(2,1,92);
INSERT INTO `course_student` (`sid`,`cid`,`grade`)
VALUES(2,2,100);
INSERT INTO `course_student` (`sid`,`cid`,`grade`)
VALUES(2,3,72);
INSERT INTO `course_student` (`sid`,`cid`,`grade`)
VALUES(3,1,65);
INSERT INTO `course_student` (`sid`,`cid`,`grade`)
VALUES(3,2,58);
INSERT INTO `course_student` (`sid`,`cid`,`grade`)
VALUES(3,3,57);

2.2 创建Student持久化类

package com;

import java.util.List;

public class Student {
    private Integer sid;
    private String sname;
    private String hobit;
    //创建多对多关系
    private List<Course> courses;
    public Integer getSid() {
        return sid;
    }
    public void setSid(Integer sid) {
        this.sid = sid;
    }
    public String getSname() {
        return sname;
    }
    public void setSname(String sname) {
        this.sname = sname == null ? null : sname.trim();
    }
    public String getHobit() {
        return hobit;
    }
    public void setHobit(String hobit) {
        this.hobit = hobit == null ? null : hobit.trim();
    }
    public List<Course> getCourses() {
        return courses;
    }
    public void setCourses(List<Course> courses) {
        this.courses = courses;
    }
}

2.3 创建Course持久化类

package com;

import java.util.List;

public class Course {
    private Integer cid;
    private String name;
    private String dec;
    //创建多对多关系
    private List<Student> students;
    public Integer getCid() {
        return cid;
    }
    public void setCid(Integer cid) {
        this.cid = cid;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name == null ? null : name.trim();
    }
    public String getDec() {
        return dec;
    }
    public void setDec(String dec) {
        this.dec = dec == null ? null : dec.trim();
    }
    public List<Student> getStudents() {
        return students;
    }
    public void setStudents(List<Student> students) {
        this.students = students;
    }
}

2.4 创建CS持久化类(用于查询某学生某课程的成绩)

package com;
public class CS {
    private Integer sc_id;
    //某学生
    private Student student;
    //某课程
    private Course course;
    //该课程的成绩
    private String grade;
    public Integer getSc_id() {
        return sc_id;
    }
    public void setSc_id(Integer sc_id) {
        this.sc_id = sc_id;
    }
    public Student getStudent() {
        return student;
    }
    public void setStudent(Student student) {
        this.student = student;
    }
    public Course getCourse() {
        return course;
    }
    public void setCourse(Course course) {
        this.course = course;
    }
    public String getGrade() {
        return grade;
    }
    public void setGrade(String grade) {
        this.grade = grade;
    }
}

2.5 根据需求编写映射文件

2.5.1 Student的映射文件

<resultMap id="StudentMap" type="com.Student" >
    <id column="sid" property="sid" jdbcType="INTEGER" />
    <result column="sname" property="sname" jdbcType="VARCHAR" />
    <result column="hobit" property="hobit" jdbcType="VARCHAR" />
    <collection property="courses" ofType="com.Course">
      <id column="cid" property="cid" jdbcType="INTEGER" />
      <result column="name" property="name" jdbcType="VARCHAR" />
      <result column="dec" property="dec" jdbcType="VARCHAR" />
    </collection>
</resultMap>

2.5.2 Course映射文件

<resultMap id="CourseMap" type="com.Course" >
    <id column="cid" property="cid" jdbcType="INTEGER" />
    <result column="name" property="name" jdbcType="VARCHAR" />
    <result column="dec" property="dec" jdbcType="VARCHAR" />
    <collection property="students" ofType="com.Student">
      <id column="sid" property="sid" jdbcType="INTEGER" />
      <result column="sname" property="sname" jdbcType="VARCHAR" />
      <result column="hobit" property="hobit" jdbcType="VARCHAR" />
    </collection>
</resultMap>

2.5.3 CS映射文件

<resultMap id="CSMap" type="com.CS" >
        <id column="sc_id" property="sc_id" jdbcType="INTEGER" />
        <result column="grade" property="grade" jdbcType="VARCHAR" />
        <association property="student" javaType="com.Student">
            <id column="sid" property="sid" jdbcType="INTEGER" />
            <result column="sname" property="sname" jdbcType="VARCHAR" />
            <result column="hobit" property="hobit" jdbcType="VARCHAR" />
        </association>
        <association property="course" javaType="com.Course">
            <id column="cid" property="cid" jdbcType="INTEGER" />
            <result column="name" property="name" jdbcType="VARCHAR" />
            <result column="dec" property="dec" jdbcType="VARCHAR" />
        </association>
</resultMap>

2.6 编写SQL相应的语句

2.6.1 查询选修某课程的所有学生(一个Course对象里面有Student数组)

<select id="findById" parameterType="int" resultMap="CourseMap">
    select * from course c
    join course_student cs on c.cid=cs.cid
    join student s on cs.sid=s.sid
    where c.cid=#{id}
</select>

2.6.2 查询某学生查询的课程信息(一个Student对象里面有Course数组)

<select id="findById" parameterType="int" resultMap="StudentMap">
    select * from course c
    join course_student cs on c.cid=cs.cid
    join student s on cs.sid=s.sid
    where s.sid=#{id}
</select>

2.6.3 查询某学生某课程的成绩信息

<select id="findById" parameterType="map" resultMap="CSMap">
        select * from course c
        join course_student cs on c.cid=cs.cid
        join student s on cs.sid=s.sid
        where c.cid=#{cid} and s.sid=#{sid}
</select>

2.7 编写测试类

2.7.1 查询选修某课程的所有学生(一个Course对象里面有Student数组)

    @Test
    public void testCourse()
    {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        try{
            Course course=sqlSession.selectOne("com.CourseMapper.findById", 1);
            System.out.print(course);
        }catch(Exception e){
            e.printStackTrace();
            sqlSession.rollback();
        }finally{
            sqlSession.commit();
        }
        MyBatisUtil.closeSqlSession();
    }

2.7.2 运行结果

2.7.3 查询某学生查询的课程信息(一个Student对象里面有Course数组)

     @Test
    public void testStudent()
    {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        try{
            Student student=sqlSession.selectOne("com.StudentMapper.findById", 1);
            System.out.print(student);
        }catch(Exception e){
            e.printStackTrace();
            sqlSession.rollback();
        }finally{
            sqlSession.commit();
        }
        MyBatisUtil.closeSqlSession();
    }

2.7.4 运行结果

2.7.5 查询某学生某课程的成绩信息

    @Test
     public void testCS()
    {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        try{
            Map<String,String> map=new HashMap<String,String>();
            map.put("cid","1");
            map.put("sid","1");
            CS cs=sqlSession.selectOne("com.CSMapper.findById", map);
            System.out.print(cs);
        }catch(Exception e){
            e.printStackTrace();
            sqlSession.rollback();
        }finally{
            sqlSession.commit();
        }
        MyBatisUtil.closeSqlSession();
    }

2.7.6 运行结果

3. 代码下载

本博客的代码下载地址为:MyBatis之多对多

时间: 2024-11-01 15:37:43

(6)MyBatis之多对多关联的相关文章

mybatis多对一关联

mybatis多对一关联查询实现 1.定义实体 定义实体的时候需要注意,若是双向关联,就是说双方的属性中都含有对方对象作为域属性出现, 那么在写toString()方法时需要注意,只让某一方输出即可,不要让双方的toString()都输出对方, 这样会形成递归调用,程序会出错,报堆栈溢出. Country实体类 Minsiter 实体类 2.数据库设计 a) country数据库 b) minsiter数据库 3.DAO层设计 4.service层设计 5.impl实现类 6.Controlle

Mybatis 一对一、一对多、多对多关联

示例项目:MIPO_CRM 一.一对一关联 示例:订单与销售机会 描述:在业务员与客户的联系人的联系记录中可以生成一条销售机会,而此条销售机会可生成一条订单,两者呈一对一关联. 1.表设计 opportunity(销售机会) orders(订单) 2.pojo Opportunity /** * 销售机会机会 * @author Administrator * */ public class Opportunity implements Serializable{ private int opi

MyBatis 系列五 之 关联映射

MyBatis 系列五 之 关联映射 一对多的关联映射 一对多关联查询多表数据 1.1在MyBatis映射文件中做如下配置 <!--一对多单向的连接两表的查询--> <resultMap type="Dept" id="deptMapper"> <id property="deptNo" column="deptNo"/> <result property="deptName

Mybatis的多对多映射

一.Mybatis的多对多映射 本例讲述使用mybatis开发过程中常见的多对多映射查询案例.只抽取关键代码和mapper文件中的关键sql和配置,详细的工程搭建和Mybatis详细的流程代码可参见<Mybatis入门和简单Demo>和<Mybatis的CRUD案例> 完整的工程代码已上传至https://files.cnblogs.com/files/jiyukai/MyBatis.zip 案例:查询xx同学所选择的多个不同选修课,查询xx选修课被多少同学选修 步骤1.建表脚本,

一口一口吃掉Hibernate(六)——多对多关联映射

今天来说说hibernate中的多对多关联映射,多对多关联映射涉及到单向映射和双向映射2种. 首先举个多对多关联例子:用户User和角色Role,一个用户可以属于多个角色,一个角色可以有多个用户.这就是典型的多对多关联的例子.而单向关联映射则是只能由A端去操作B端,B端不能操作A端的数据.而双向关联映射则是A,B两端都可以操作另一端的数据. 先说单向关联映射,实体类如下: <span style="font-size:18px">/** * 学生类 * @author Lo

Mybatis一对多双向关联

在弄Mybatis的一对多关联的时候,不知道有没有遇到这样的问题,本来数据库中对应有多条数据,然而关联出来却只有一条数据,比如数据库中有个班级表和学生表,数据库中一个班级中对应了多个学生,但使用Mybatis做一对多关联的时候,查询出来的却只有一条.如果出现这样的问题,那么就是两张数据表中的主键重名了,导致在关联查询时分不清到底是那一张表了,因此有关联的数据表时,主键id不要重名,一对多关联实现如下: 数据表: CREATE TABLE tab_class ( c_id INT PRIMARY

Hibernate ManyToOne Mappings 多对一关联映射

Hibernate框架的使用步骤: 1.创建Hibernate的配置文件(hibernate.cfg.xml) 2.创建持久化类,即其实例需要保存到数据库中的类(Employee.java) 3.创建对象-关系映射文件(Employee.hbm.xml) 4.通过Hibernate API编写访问数据库的代码 例子:多个员工对应一个地址. 一.创建hibernate.cfg.xml 配置文件: 注意数据库名.用户名.密码是否填写正确. <?xml version="1.0" en

MyBatis:学习笔记(3)——关联查询

MyBatis:学习笔记(3)--关联查询 关联查询 理解联结 SQL最强大的功能之一在于我们可以在数据查询的执行中可以使用联结,来将多个表中的数据作为整体进行筛选. 模拟一个简单的在线商品购物系统,如果我们将用户信息和订单信息都保存在user表中,这样就不存在联结关系,因为我们仅仅操作一张表就好. 但是这是非常不明智的选择,举例来说,一个用户可以拥有多个订单,如果保存在一个表中,势必会导致用户信息的多次出现,因为每个订单绑定的用户信息都是相同的. 所以我们尽量要将不同的信息存储与不同的表中,但

【SSH系列】Hibernate映射 -- 多对多关联映射

     映射原理 在数据库学习阶段,我们知道,如果实体和实体之间的关系是多对多,那么我们就抽出来第三张表,第一张表和第二张表的主键作为第三表的联合主键,结合我们的hibernate,多对多关联,无论是单向关联还是双向关联都是通过第三张表,将两个表中的主键放到第三张表中做一个关联,用第三张表来解决可能造成的数据冗余问题.今天这篇博文小编来简单的介绍一下hibernate中的多对多关联映射. 在某些系统中,一个用户可以有多个角色,一个角色也可以有多个用户,so,她们之间的关系就是多对多,多对多关联