項目結構:
創建三個表:學生表,課程表,和中間表(多對多關係)
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); // 學生信息
}
}
}
}
測試結果: