Mybatis多表聯查簡簡單單

Mybatis中實現了對數據庫中的數據進行封裝,那麼進行多表查詢時就會遇到查詢結果不只是一個對象的數據,有可能是多個對象的混合,可以使用<resultMap> 標籤進行映射

resultMap 標籤

<select>標籤中使用resultMap可以完成與查詢結果進行映射

1.一對一關係association

一對一關係是指關係數據庫中兩個表之間的一種關係,該關係中第一個表中的單個行只可以與第二個表中的一個行相關,且第二個表中的一個行也只可以與第一個表中的一個行相關。
使用 resultMap 實現關聯單個對象,假設一位學生對應一個老師
在這裏插入圖片描述
在這裏插入圖片描述
多表聯查sql語句
在這裏插入圖片描述
實體類entity

Student.java

public class Student {
	private String sname;
	private String sid;
	private Teacher teacher;
	
	/*無參構造,有參構造,get/set方法,toString方法*/
}

Tips:在Student 類中有teacher屬性,實現一對一關係

Teacher.java

public class Teacher {
	private String tname;
	private String id;

	/*無參構造,有參構造,get/set方法,toString方法*/
}

Mapper映射

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="Students">
	<!-- 設計時儘量把屬性字段和數據庫字段設爲相同 -->

	<!-- 查詢一條數據 -->
	<select id="selectStudentById" parameterType="java.lang.String" resultMap="studentMap" >
			SELECT
				sid,
				sname,
				id,
				tname
			FROM
				teacher t,
				student s
			WHERE
				s.tid = t.id
			AND s.sid = #{id}
	</select>
	
	<!-- 查詢多條數據   -->
	<select id="selectStudents"  resultMap="studentMap" >
		SELECT
			sid,
			sname,
			id,
			tname
		FROM
			teacher t
		INNER JOIN student s ON s.tid = t.id;
	</select>
	
	<resultMap type="Student" id="studentMap">
	<!-- id           表示主鍵列 -->
	<!-- property     對應java實體類中屬性名稱 -->
	<!-- column       對應數據庫中列名 -->
	<!-- association  表示一對一 -->
	<id property="sid" column="sid" />
	<result property="sname" column="sname" />
	
	<!-- Teacher對象 -->
	<association property="teacher" javaType="Teacher">
		<id property="id" column="id" />
		<result property="tname" column="tname" />
	</association>
	
</resultMap>
</mapper>   

測試

StudentTest.java

package com.zy.entity;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.List;

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

public class StudentTest {
	public static void main(String[] args) throws FileNotFoundException {
		// 讀取配置文件
		InputStream in = new FileInputStream("src/main/resources/mybatis.xml");
		// 解析配置文件
		SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(in);
		SqlSession session = sf.openSession();
		
		Student s = session.selectOne("Students.selectStudentById", "1");
		System.out.println("多表聯查返回一條數據:");
		System.out.println(s);
		
		List<Student> list = session.selectList("Students.selectStudents");
		System.out.println("多表聯查返回多條數據-----list:");
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}
	}
}

在這裏插入圖片描述

2.一對多關係collection

一對多關係是關係數據庫中兩個表之間的一種關係,該關係中第一個表中的單個行可以與第二個表中的一個或多個行相關,但第二個表中的一個行只可以與第一個表中的一個行相關。
例如一個老師教授多個學生,那麼老師與學生的關係就是一對多

數據庫表還是teacher表與student表,數據不變

實體類entity

Teacher.java

public class Teacher {
	private String tname;
	private String id;
	private List<Student> students;
	
		/*無參構造,有參構造,get/set方法,toString方法*/
}

Tips:在Teacher實體類中多了一個List<Student>學生集合屬性,來表示一個老師教授多個學生

Student.java

public class Student {
	private String sname;
	private String sid;
	
	/*無參構造,有參構造,get/set方法,toString方法*/
}

Mapper映射

TeacherMapper.xml
這裏提供了兩種sql查詢方式,多表聯查和子查詢,查詢結果相同

<?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="Teachers">
	<!-- 設計時儘量把屬性字段和數據庫字段設爲相同 -->

	<!-- 多表聯查 -->
	<select id="selectTeacherById" parameterType="java.lang.String"
		resultMap="TeacherMap">
		SELECT
			id,
			tname,
			sid,
			sname
		FROM
			teacher,
			student
		WHERE
			teacher.id = student.tid and id = #{id}
	</select>
	<resultMap type="Teacher" id="TeacherMap">
		<id property="id" column="id" />
		<result property="tname" column="tname" />
		<!-- ofType   關聯類型 -->
		<!-- collection 一對多 -->
		<collection property="students" ofType="Student">
			<id property="sid" column="sid" />
			<result property="sname" column="sname" />
		</collection>
	</resultMap>

	<!-- 子查詢 -->
	<select id="selectTeacherById1" parameterType="java.lang.String"
		resultMap="TeacherMap1">
		select * from teacher where id = #{id}
	</select>
	<resultMap type="Teacher" id="TeacherMap1">
		<id property="id" column="id" />
		<result property="tname" column="tname" />
		<!-- ofType 關聯類型 -->
		<!-- collection 一對多 -->
		<collection property="students" ofType="Student"
			column="id" select="selectStudent">
		</collection>
	</resultMap>

	<select id="selectStudent" parameterType="java.lang.String"
		resultType="Student">
		select * from student where tid = #{id}
	</select>

</mapper>   

Tips:javaType顧名思義就是表示這個屬性在java中所對應的類型,使用ofType的原因是並沒有創建一個可以明確表示這個List<Student>集合的類,也可以理解List<Student>不能單純是一個Student類型,使用ofType表示屬性List<Student>所關聯的java類是Student

測試

TeacherTest.java

package com.zy.entity;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

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

public class TeacherTest {
	public static void main(String[] args) throws FileNotFoundException {
		// 讀取配置文件
		InputStream in = new FileInputStream("src/main/resources/mybatis.xml");
		// 解析配置文件
		SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(in);
		SqlSession session = sf.openSession();
		
		System.out.println("多表聯查:");
		Teacher t = session.selectOne("Teachers.selectTeacherById","1003");
		System.out.println(t);
		
		System.out.println("子查詢:");
		Teacher t1 = session.selectOne("Teachers.selectTeacherById1","1003");
		System.out.println(t1);
		session.close();
	}
}

在這裏插入圖片描述

3.多對多關係

多對多關係是關係數據庫中兩個表之間的一種關係, 該關係中第一個表中的一個行可以與第二個表中的一個或多個行相關。第二個表中的一個行也可以與第一個表中的一個或多個行相關。

Tips:要表示多對多關係,必須創建第三個表,該表通常稱爲聯接表,它將多對多關係劃分爲兩個一對多關係。將這兩個表的主鍵都插入到第三個表中,通過中間表將多對多拆分成兩個一對多

例如一個學生有多個老師,一個老師教授多個學生,那麼學生與老師的關係就是多對多

數據庫表在之前的基礎上稍作修改,加入第三張表stu_tea
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
實體類entity

Teacher.java

public class Teacher {
	private String tname;
	private String id;
	private List<Student> students;
	
		/*無參構造,有參構造,get/set方法,toString方法*/
}

Student.java

public class Student {
	private String sname;
	private String sid;
	private String List<Teacher> teachers;
	
	/*無參構造,有參構造,get/set方法,toString方法*/
}

Tips:爲表示多對多關係,在Student類與Teacher類中都加入了對應的List集合

Mapper映射

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="Students">
	<!-- 設計時儘量把屬性字段和數據庫字段設爲相同 -->

	<!-- 多表聯查 -->
	<select id="selectStudentsById" parameterType="java.lang.String" resultMap="StudentMap">
		SELECT
			s.sid,
			s.sname,
			t.id,
			t.tname
		FROM
			student_copy s,
			teacher_copy t,
			stu_tea st
		WHERE
			s.sid = st.sid
		AND t.id = st.id
		AND s.sid = #{id}
	</select>
	<resultMap type="Student" id="StudentMap">
		<id property="sid" column="sid"/>
		<result property="sname" column="sname"/>
		<collection property="teachers" ofType="Teacher">
			<id property="id" column="id"/>
			<result property="tname" column="tname"/>
		</collection>
	</resultMap>
	
	
	<!-- 子查詢 -->
	<select id="selectStudentsById1" parameterType="java.lang.String" resultMap="StudentMap1">
		select * from student_copy where sid = #{sid}
	</select>
	
	<resultMap type="Student" id="StudentMap1">
		<id property="sid" column="sid"/>
		<result property="sname" column="sname"/>
		<collection property="teachers" column="sid" ofType="Teacher" select="selectTeachers"></collection>
	</resultMap>
	
	<select id="selectTeachers" parameterType="java.lang.String" resultType="Teacher">
		SELECT
			teacher_copy.id,
			teacher_copy.tname
		FROM
			teacher_copy,
			stu_tea
		WHERE
			stu_tea.id = teacher_copy.id
		AND stu_tea.sid = #{sid}
	</select>
	
</mapper>   

TeacherMapper.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="Teachers">
	<!-- 設計時儘量把屬性字段和數據庫字段設爲相同 -->
	
	<!-- 多表聯查 -->
	<select id="selectTeachersById" parameterType="java.lang.String" resultMap="TeacherMap">
		SELECT
			s.sid,
			s.sname,
			t.id,
			t.tname
		FROM
			student_copy s,
			teacher_copy t,
			stu_tea st
		WHERE
			s.sid = st.sid
		AND t.id = st.id
		AND t.id = #{id}
	</select>
	<resultMap type="Teacher" id="TeacherMap">
		<id property="id" column="id"/>
		<result property="tname" column="tname"/>
		<collection property="students" ofType="Student">
			<id property="sid" column="sid"/>
			<result property="sname" column="sname"/>
		</collection>
	</resultMap>
	
	<!-- 子查詢 -->
	<select id="selectTeachersById1" parameterType="java.lang.String" resultMap="TeacherMap1">
		select * from teacher_copy where id = #{id}
	</select>
	
	<resultMap type="Teacher" id="TeacherMap1">
		<id property="id" column="id"/>
		<result property="tname" column="tname"/>
		<collection property="students" ofType="Student" column="id" select="selectStudents"></collection>
	</resultMap>
	
		<select id="selectStudents" resultType="Student" parameterType="java.lang.String">
			SELECT
				student_copy.sid,
				student_copy.sname
			FROM
				student_copy,
				stu_tea
			WHERE
				stu_tea.sid = student_copy.sid
			AND stu_tea.id = #{id}
		</select>
		
</mapper>   

Tips:將多對多拆分成兩個一對多,即有兩個mapper映射,通過Student查詢Teacher ,通過Teacher查詢Student,雙向的一對多查詢實現多對多關係

測試

StudentTest.java

package com.zy.entity;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

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

public class StudentTest {
	public static void main(String[] args) throws FileNotFoundException {
		// 讀取配置文件
		InputStream in = new FileInputStream("src/main/resources/mybatis.xml");
		// 解析配置文件
		SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(in);
		SqlSession session = sf.openSession();
		
		Student s = session.selectOne("Students.selectStudentsById","1");
		System.out.println("多表聯查:");
		System.out.println(s);
		
		Student s1 = session.selectOne("Students.selectStudentsById1","1");
		System.out.println("子查詢:");
		System.out.println(s1);
		session.close();
	}
}

在這裏插入圖片描述
TeacherTest.java

package com.zy.entity;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

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

public class TeacherTest {
	public static void main(String[] args) throws FileNotFoundException {
		// 讀取配置文件
		InputStream in = new FileInputStream("src/main/resources/mybatis.xml");
		// 解析配置文件
		SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(in);
		SqlSession session = sf.openSession();
		
		Teacher  t = session.selectOne("Teachers.selectTeachersById","1003");
		System.out.println("多表聯查:");
		System.out.println(t);
		
		Teacher  t1 = session.selectOne("Teachers.selectTeachersById1","1003");
		System.out.println("子查詢:");
		System.out.println(t1);
		session.close();
	}
}

在這裏插入圖片描述

Tips:爲了實現多對多關係,在Student類與Teacher類中都加入了對應的List類型,導致查詢結果中出現null

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