Mybatis的多对多映射

Posted 纪煜楷

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis的多对多映射相关的知识,希望对你有一定的参考价值。

一、Mybatis的多对多映射

  本例讲述使用mybatis开发过程中常见的多对多映射查询案例。只抽取关键代码和mapper文件中的关键sql和配置,详细的工程搭建和Mybatis详细的流程代码可参见《Mybatis入门和简单Demo》和《Mybatis的CRUD案例

  完整的工程代码已上传至https://files.cnblogs.com/files/jiyukai/MyBatis.zip

  案例:查询xx同学所选择的多个不同选修课,查询xx选修课被多少同学选修

  步骤1.建表脚本,分别创建学生表,课程表,以及学生课程表,作为学生关系到课程的中间关联表。

create table students(
    sid int(5) primary key,
    sname varchar(10)
);
create table courses(
    cid int(5) primary key,
    cname varchar(10)
);
create table course_stu(
    sid int(5),
    cid int(5),
    primary key(sid,cid)    
);
insert into students(sid,sname) values(1,\'cat\');
insert into students(sid,sname) values(2,\'dog\');
insert into courses(cid,cname) values(1,\'java\');
insert into courses(cid,cname) values(2,\'net\');
insert into course_stu(sid,cid) values(1,1);
insert into course_stu(sid,cid) values(1,2);
insert into course_stu(sid,cid) values(2,1);
insert into course_stu(sid,cid) values(2,2);

  步骤2.编写课程和学生实体类,学生可选择多门课程,课程中有多个学生,因此在各自的实体类中都以集合的形式引入对方

package com.jyk.mybatis.moreTomore;

import java.util.ArrayList;
import java.util.List;

public class Course {
    private Integer id;                        //课程id
    private String name;                    //课程名称
    private List<Student> studentList = new ArrayList<Student>();    //对应的学生名称
    public Course(){}
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<Student> getStudentList() {
        return studentList;
    }
    public void setStudentList(List<Student> studentList) {
        this.studentList = studentList;
    }
}
package com.jyk.mybatis.moreTomore;

import java.util.ArrayList;
import java.util.List;

public class Student {
    private Integer id;                //学生id
    private String name;            //学生姓名
    private List<Course> courseList = new ArrayList<Course>();   //选修的课程
    public Student(){}
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<Course> getCourseList() {
        return courseList;
    }
    public void setCourseList(List<Course> courseList) {
        this.courseList = courseList;
    }
}

  步骤3.编写mapper文件,在CourseMapper.xml中编写课程信息表字段与实体属性的映射关系,在StudentMapper.xml中编写学生实体和表字段的映射关系,并编写好根据学生姓名查询所有选修课程,以及根据选修课名称查询有多少学生的SQL,并将mapper文件和对应实体类的别名加入mybatis.xml(mybatis.xml的描述见Mybatis系列第一篇博客,此处由于配置type时指定了类的全路径,故无需将别名加入至mybatis.xml)

<?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="studentNamespace">
    <resultMap type="com.jyk.mybatis.moreTomore.Student" id="studentMap">
        <id property="id" column="sid" />
        <result property="name" column="sname"/>
    </resultMap>
    
    <!-- 查询java课程有哪些学生 -->
    <select id="findStudentByName" parameterType="string" resultMap="studentMap">
        select s.sid,s.sname
        from students s,course_stu m,courses c
        where s.sid = m.sid 
        and m.cid = c.cid
        and c.cname = #{name}
    </select>
</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="courseNamespace">
    <resultMap type="com.jyk.mybatis.moreTomore.Course" id="courseMap">
        <id property="id" column="cid" />
        <result property="name" column="cname"/>
    </resultMap>
    
    <!-- 查询cat选学的课程 -->
    <select id="findCourseByName" parameterType="string" resultMap="courseMap">
        select c.cid,c.cname
        from students s,course_stu m,courses c
        where s.sid = m.sid 
        and m.cid = c.cid
        and s.sname = #{name}
    </select>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

    <!-- 加载类路径下的属性文件 -->
    <properties resource="db.properties">
    </properties>
    
    <!-- 设置类型别名 -->
    <typeAliases>

    </typeAliases>

    <!-- 设置一个默认的连接环境信息 -->
    <environments default="mysql_env">
        <!-- 连接环境信息,取一个唯一的编号 -->
        <environment id="mysql_env">
            <!-- mybatis使用的jdbc事务管理方式 -->
            <transactionManager type="jdbc">
            </transactionManager>
            
            <!-- mybatis使用连接池方式来获取链接 -->
            <dataSource type="pooled">
                <!-- 配置与数据库交互的四个属性 -->
                <property name="driver" value="${mysql.driver}"/>
                <property name="url" value="${mysql.url}"/>
                <property name="username" value="${mysql.username}"/>
                <property name="password" value="${mysql.password}"/>
            </dataSource>
        </environment>
    </environments>
    
    <mappers>
        <mapper resource="com/jyk/mybatis/moreTomore/CourseMapper.xml"/>
        <mapper resource="com/jyk/mybatis/moreTomore/StudentMapper.xml"/>
    </mappers>
    
</configuration>

  步骤4.编写Java代码实现该多对多查询,需要注意的是,区分于一对一查询,此处由于查询的结果有多个,是集合的形式返回,故查询的API应使用SqlSession提供的selectList接口而不再是selectOne。

package com.jyk.mybatis.moreTomore;

import java.util.List;
import org.apache.ibatis.session.SqlSession;

import com.jyk.mybatis.util.MyBatisUtil;

public class StudentCourseDao {
    /**
     * 查询cat选学的课程
     */
    public List<Course> findCourseByName(String name) throws Exception{
        SqlSession sqlSession = null;
        try{
            sqlSession = MyBatisUtil.getSqlSession();
            return sqlSession.selectList("courseNamespace.findCourseByName",name);
        }catch(Exception e){
            e.printStackTrace();
            throw e;
        }finally{
            MyBatisUtil.closeSqlSession();
        }
    }
    /**
     * 查询java课程有哪些学生
     */
    public List<Student> findStudentByName(String name) throws Exception{
        SqlSession sqlSession = null;
        try{
            sqlSession = MyBatisUtil.getSqlSession();
            return sqlSession.selectList("studentNamespace.findStudentByName",name);
        }catch(Exception e){
            e.printStackTrace();
            throw e;
        }finally{
            MyBatisUtil.closeSqlSession();
        }
    }
    public static void main(String[] args) throws Exception{
        StudentCourseDao dao = new StudentCourseDao();
        List<Course> courseList = dao.findCourseByName("cat");
        for(Course c : courseList){
            System.out.println(c.getId()+":"+c.getName());
        }
        /*List<Student> studentList = dao.findStudentByName("java");
        for(Student s : studentList){
            System.out.println(s.getId()+":"+s.getName());
        }*/
    }     
}

 

以上是关于Mybatis的多对多映射的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis学习10高级映射之多对多查询

Mybatis 多对多(易百教程)

mybatis映射 一对一,一对多,多对多高级映射

Mybatis的多表(多对多)查询

在休眠中的多对多映射中仅插入一个表

没有集合的Hibernate中的多对多映射