1. 程式人生 > >Mybatis的多對多映射

Mybatis的多對多映射

tco pooled size pass har ssi s系列 多對多 find

一、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的多對多映射