1. 程式人生 > >【Mybatis學習總結五】實現關聯表查詢----一對多關聯(collection)

【Mybatis學習總結五】實現關聯表查詢----一對多關聯(collection)

實現關聯表查詢----一對多關聯(collection)

一對多需求:即一張表class中又含有多張表(teacher,student)內容。現根據class_id 來獲取對應的班級資訊(包括學生和老師資訊)。

1 、建立表和資料:

CREATE TABLE student(
s_id INT PRIMARY KEY AUTO_INCREMENT,
s_name VARCHAR(20),
class_id INT
);
INSERT INTO student(s_name, class_id) VALUES('xs_A', 1);
INSERT INTO student(s_name, class_id) VALUES('xs_B', 1);
INSERT INTO student(s_name, class_id) VALUES('xs_C', 1);
INSERT INTO student(s_name, class_id) VALUES('xs_D', 2);
INSERT INTO student(s_name, class_id) VALUES('xs_E', 2);
INSERT INTO student(s_name, class_id) VALUES('xs_F', 2);

2、建立實體類:Student.java

package com.mybatis.entities;

public class Student {

	private int id;
	private String name;
	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 Student(int id, String name) {
		super();
		this.id = id;
		this.name = name;
	}
	public Student() {
		super();
	}
	@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + "]";
	}
	
}
Classes.java中新增屬性
private List<Student> students;

3、定義sql對映檔案:classesMapper2.xml

方式一:巢狀結果
使用巢狀結果對映來處理重複的聯合結果的子集

SELECT * FROM class c, teacher t,student s 
WHERE c.teacher_id=t.t_id AND c.C_id=s.class_id AND c.c_id=1

方式二:巢狀查詢
通過執行另外一個SQL對映語句來返回預期的複雜型別

SELECT * FROM class WHERE c_id =1 //查詢後獲取到teacher_id,c_id值,傳入下兩條語句
SELECT * FROM teacher WHERE t_id =1   //t_id=1 是上條查詢得到的teacher_id值
SELECT * FROM student WHERE class_id =1   //c_id = 1 是上條查詢得到的c_id值
即通過三條語句分別來查詢。
<?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">
<!-- 
	4、關聯表查詢:一對多關聯
	如何根據class_id查詢班級資訊(包括老師和學生資訊),學生資訊為集合List
	Class封裝了Teacher和學生屬性,即一張class表中包含teacher表和student表
 -->
<!--定義操作 classes 表的sql 對映檔案:classesMapper.xml   -->
<mapper namespace="com.mybatis.test5.classesMapper2">
	<!-- 
		方式一:巢狀結果
		使用巢狀結果對映來處理重複的聯合結果的子集
		SELECT * FROM class c, teacher t,student s 
		WHERE c.teacher_id=t.t_id AND c.C_id=s.class_id AND c.c_id=1
	-->
	<select id="getClassInfo3" parameterType="int"
			resultMap="getClassMap">
			SELECT * FROM class c, teacher t,student s 
			WHERE c.teacher_id=t.t_id AND c.C_id=s.class_id AND  c.c_id=#{id}
	</select>
	<!-- 解決欄位名和屬性不一致衝突 -->
	<resultMap type="Classes" id="getClassMap">
		<id property="id" column="c_id"/>
		<result property="name" column="c_name"/>
		
			<!-- 關聯的教師資訊 -->
		<association property="teacher" column="teacher_id" 
					 javaType="Teacher">
			<id property="id" column="t_id"/>
			<result property="name" column="t_name"/>
		</association>
			<!-- 關聯的學生資訊,是集合 -->
		<collection property="students" 
					ofType="Student">
			<id property="id" column="s_id"/>
			<result property="name" column="s_name"/>	
		</collection>
	</resultMap>
	
	<!-- 
		方式二:巢狀查詢
		通過執行另外一個SQL對映語句來返回預期的複雜型別
		SELECT * FROM class WHERE c_id =1 //查詢後獲取到teacher_id,c_id值,傳入下兩條語句
		SELECT * FROM teacher WHERE t_id =1   //t_id=1 是上條查詢得到的teacher_id值
		SELECT * FROM student WHERE class_id =1   //c_id = 1 是上條查詢得到的c_id值
	-->
	<select id="getClassInfo4" parameterType="int"  resultMap="getClassMap2">
			SELECT * FROM class WHERE c_id =#{id}	
	</select>
		
		<resultMap type="Classes" id="getClassMap2">
			<id property="id" column="c_id"/>
			<result property="name" column="c_name"/>
			<association property="teacher" column="teacher_id" javaType="Teacher"
						select="getTeacher"></association>
			<collection property="students" column="c_id" ofType="Student"
						select="getStudent"></collection>
		</resultMap>
	
	<select id="getTeacher"  resultType="Teacher">
			SELECT t_id id,t_name name FROM teacher WHERE t_id =#{id}
	</select>
	
	<select id="getStudent"  resultType="Student">
			SELECT s_id id,s_name name FROM student WHERE class_id =#{id}                                                                                   
	</select>
</mapper>

4 註冊:conf.xml

<mappers>
      <mapper resource="com/mybatis/test5/classesMapper2.xml"/>
</mappers>

5   測試類Test5.java

package com.mybatis.test5;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import com.mybatis.entities.Classes;

public class Test5 {

	@Test
	public void test() {

		SqlSession session= MybatisUtils.getSqlSessionFactory().openSession();
		//方式一測試
		String statement = "com.mybatis.test5.classesMapper2.getClassInfo3";
		Classes clazz=session.selectOne(statement , 1);
		
		//方式二測試
		statement = "com.mybatis.test5.classesMapper2.getClassInfo4";
		clazz=session.selectOne(statement , 1);
		System.out.println("*"+clazz);
		session.close();
	}

}