mybatis學習筆記(七):多對多映射


項目結構:

創建三個表:學生表,課程表,和中間表(多對多關係)

CREATE TABLE students(
	sid INT(5) PRIMARY KEY,
	sname VARCHAR(10)
);

CREATE TABLE courses(
	cid INT(5) PRIMARY KEY,
	cname VARCHAR(10)
);

CREATE TABLE middles(
	sid INT(5),
	cid INT(5),
	PRIMARY KEY(sid,cid)	
);

INSERT INTO students(sid,sname) VALUES(1,'哈哈');
INSERT INTO students(sid,sname) VALUES(2,'呵呵');

INSERT INTO courses(cid,cname) VALUES(1,'java');
INSERT INTO courses(cid,cname) VALUES(2,'net');

INSERT INTO middles(sid,cid) VALUES(1,1);
INSERT INTO middles(sid,cid) VALUES(1,2);
INSERT INTO middles(sid,cid) VALUES(2,1);
INSERT INTO middles(sid,cid) VALUES(2,2);

學生實體類 Student.java:

package com.mybatis.many2many;

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

/**
 * 學生實體類
 */
public class Student {
    private int id;
    private String name;
    private List<Course> courseList = new ArrayList<Course>(); // 關聯屬性

    public int getId() {
        return id;
    }

    public void setId(int 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;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

學生實體類 與 學生表 的映射配置文件 StudentMapper.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 標籤:映射實體與表的關係 -->
    <resultMap id="studentMap" type="com.mybatis.many2many.Student">
        <id property="id" column="sid"/>
        <result property="name" column="sname"/>
        <!-- 引入 CourseMapper.xml 中的映射信息 -->
        <association property="courseList" resultMap="courseNamespace.courseMap"/>
    </resultMap>

    <!-- 根據 課程名稱 查詢該課程下有哪些學生 -->
    <select id="findStudentsByCourse" parameterType="string" resultType="com.mybatis.many2many.Student" resultMap="studentMap">
        select s.sid, s.sname
        from students s, middles m, courses c
        where s.sid = m.sid
        and m.cid = c.cid
        and c.cname = #{name}
    </select>

</mapper>

課程實體類 Course.java:

package com.mybatis.many2many;

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

/**
 * 課程實體類
 */
public class Course {
    private int id;
    private String name;
    private List<Student> studentList = new ArrayList<Student>(); // 關聯屬性

    public int getId() {
        return id;
    }

    public void setId(int 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;
    }

    @Override
    public String toString() {
        return "Course{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

課程實體類 與 課程表 的映射配置文件 CourseMapper.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="courseNamespace">

    <!-- resultMap 標籤:映射實體與表的關係 -->
    <resultMap id="courseMap" type="com.mybatis.many2many.Course">
        <id property="id" column="cid"/>
        <result property="name" column="cname"/>
        <!-- 引入 StudentMapper.xml 中的映射信息 -->
        <association property="studentList" resultMap="studentNamespace.studentMap"/>
    </resultMap>

    <!-- 根據 學生名 查詢該學生學習了哪些課程 -->
    <select id="findCoursesByStudent" parameterType="string" resultMap="courseMap">
        select c.cid, c.cname
        from courses c, middles m, students s
        where c.cid = m.cid
        and m.sid = s.sid
        and s.sname = #{name}
    </select>

    <!-- 根據 id 查詢課程信息(包括課程下的學生信息) -->
    <select id="findCoursesById" parameterType="int" resultMap="courseMap">
        select c.cid, c.cname, s.sid, s.sname
        from courses c, middles m, students s
        where c.cid = m.cid
        and m.sid = s.sid
        and c.cid = #{id}
    </select>

</mapper>

數據庫配置文件 db.properties:

# mysql 配置
mysql.driver=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/mybatis
mysql.username=root
mysql.password=root

# oracle 配置
oracle.driver=oracle.jdbc.driver.OracleDriver
oracle.url=jdbc:oracle:thin:@localhost:1521:orcl
oracle.username=scott
oracle.password=tiger

主配置文件 mybatis.xml:

<?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>

    <!--
        加載 src 路徑下的 配置文件(db.properties);
        下面通過 ${ 鍵 } 獲取對應的值;
    -->
    <properties resource="db.properties"/>

    <!-- 設置一個默認的連接環境信息 -->
    <environments default="mysql_developer">

        <!-- 連接環境信息:取一個任意唯一的名字 -->
        <environment id="mysql_developer">
            <!-- mybatis 使用 jdbc 事務管理方式 -->
            <transactionManager type="jdbc"/>
            <!-- mybatis 使用連接池方式來獲取連接 -->
            <dataSource type="pooled">
                <!--
                    配置與數據庫交互的4個必要屬性 ;
                    ${mysql.driver}:表示獲取 db.properties 配置文件中 mysql.driver 的值;
                -->
                <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>

        <!-- 連接環境信息:取一個任意唯一的名字 -->
        <environment id="oracle_developer">
            <!-- mybatis 使用 jdbc 事務管理方式 -->
            <transactionManager type="jdbc"/>
            <!-- mybatis 使用連接池方式來獲取連接 -->
            <dataSource type="pooled">
                <!-- 配置與數據庫交互的4個必要屬性 -->
                <property name="driver" value="${oracle.driver}"/>
                <property name="url" value="${oracle.url}"/>
                <property name="username" value="${oracle.username}"/>
                <property name="password" value="${oracle.password}"/>
            </dataSource>
        </environment>

    </environments>

    <!-- 加載映射文件 -->
    <mappers>
        <mapper resource="com/mybatis/many2many/StudentMapper.xml"/>
        <mapper resource="com/mybatis/many2many/CourseMapper.xml"/>
    </mappers>

</configuration>

工具類 MybatisUtils.java:

package com.mybatis.many2many;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.Reader;
import java.sql.Connection;

/**
 * 工具類
 */
public class MybatisUtils {

    /**
     * 禁止外界通過 new 方法創建 工具類對象:構造方法私有化;
     */
    private MybatisUtils(){}

    /**
     * 創建一個線程對象,目的是將 SqlSession 和當前線程綁定到一起,線程結束,SqlSession 銷燬;
     */
    private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<>();
    /**
     * SqlSession 工廠
     */
    private static SqlSessionFactory sqlSessionFactory;

    /**
     * 類加載的時候 自動加載 src/mybatis.xml 配置文件
     */
    static {
        try {
            // 加載配置文件
            Reader reader = Resources.getResourceAsReader("mybatis.xml");
            // 根據配置文件構造 SqlSession 工廠
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 獲取 SqlSession
     */
    public static SqlSession getSession() {
        // 從當前線程中獲取 SqlSession
        SqlSession sqlSession = threadLocal.get();
        // 如果線程中沒有 SqlSession 的話
        if (sqlSession == null) {
            // 找 SessionFactory 創建一個 SqlSession
            sqlSession = sqlSessionFactory.openSession();
            // 將當前線程與 SqlSession 綁定到一起
            threadLocal.set(sqlSession);
        }
        // 返回 SqlSession 對象
        return sqlSession;
    }

    /**
     * 關閉 SqlSession,並與當前線程分離
     */
    public static void closeSqlSession() {
        // 從當前線程中獲取 SqlSession
        SqlSession sqlSession = getSession();
        // 如果有的話就關閉
        if (sqlSession != null) {
            // 關閉
            sqlSession.close();
            // 分離當前線程與 SqlSession,目的是讓 GC 儘早回收
            threadLocal.remove();
        }
    }

    /**
     * 測試是否連接成功
     */
    public static void main(String[] args){
        Connection connection = MybatisUtils.getSession().getConnection();
        System.out.println(connection);
    }
}

測試類 StudentCourseDao.java:

package com.mybatis.many2many;

import org.apache.ibatis.session.SqlSession;

import java.util.List;

/**
 * 持久層:測試多對多映射
 */
public class StudentCourseDao {

    /**
     * 根據 課程名稱 查詢該課程下有哪些學生
     */
    public List<Student> findStudentsByCourse(String name) throws Exception{
        // 獲取 SqlSession 對象
        SqlSession sqlSession = MybatisUtils.getSession();
        try {
            return sqlSession.selectList("studentNamespace.findStudentsByCourse", name);
        }catch (Exception e){
            e.printStackTrace();
            throw e;
        }finally {
            MybatisUtils.closeSqlSession(); // 關閉
        }
    }

    /**
     * 根據 學生名 查詢該學生學習了哪些課程
     */
    public List<Course> findCoursesByStudent(String name) throws Exception{
        // 獲取 SqlSession 對象
        SqlSession sqlSession = MybatisUtils.getSession();
        try {
            return sqlSession.selectList("courseNamespace.findCoursesByStudent", name);
        }catch (Exception e){
            e.printStackTrace();
            throw e;
        }finally {
            MybatisUtils.closeSqlSession(); // 關閉
        }
    }

    /**
     * 根據 id 查詢課程信息(包括課程下的學生信息)
     */
    public List<Course> findCoursesById(int id) throws Exception{
        // 獲取 SqlSession 對象
        SqlSession sqlSession = MybatisUtils.getSession();
        try {
            return sqlSession.selectList("courseNamespace.findCoursesById", id);
        }catch (Exception e){
            e.printStackTrace();
            throw e;
        }finally {
            MybatisUtils.closeSqlSession(); // 關閉
        }
    }

    public static void main(String[] args) throws Exception{
        StudentCourseDao dao = new StudentCourseDao();

        // 根據 課程名稱 查詢該課程下有哪些學生
        System.out.println("*********** 根據 課程名稱 查詢該課程下有哪些學生 *************");
        List<Student> studentList = dao.findStudentsByCourse("java");
        for (Student student : studentList){
            System.out.println(student);
        }

        // 根據 學生名 查詢該學生學習了哪些課程
        System.out.println("*********** 根據 學生名 查詢該學生學習了哪些課程 *************");
        List<Course> courseList1 = dao.findCoursesByStudent("哈哈");
        for (Course course : courseList1){
            System.out.println(course);
        }

        // 根據 id 查詢課程信息(包括課程下的學生信息)
        System.out.println("*********** 根據 id 查詢課程信息(包括課程下的學生信息) *************");
        List<Course> courseList2 = dao.findCoursesById(1);
        for(Course course : courseList2){
            System.out.println(course); // 課程信息

            // 根據 課程信息 查詢 學生信息
            List<Student> studentList1 = course.getStudentList();
            for(Student student : studentList1){
                System.out.println(student); // 學生信息
            }
        }
    }
}

測試結果:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章