1. 程式人生 > >Hibernate(四)多對多

Hibernate(四)多對多

一個人可以買多種商品,一種商品可以被多個人所購買。

一個學生可以選多門課程,一個課程可以被多個學生選擇。

一個老師可以帶多個班級,一個班級可以被多個老師帶。這些都是多對多的關係。

以老師和班級為例。要建立兩者之間的關係需要三張表。一張老師表,一張班級表,還需要一張用來維護關係的中間表。

知道三張表之間的關係後就可以著手寫程式碼了。

1、先建實體類。建一個教師的實體類和一個班級的實體類。給定各自所有的屬性,並在教師實體類中給定一個set集合用來存放班級資訊。在班級實體類中給定一個set集合用來存放教師資訊。並給定set、get方法。

package cn.otote.entity;

import java.util.Set;

public class Teacher {

	private Integer id;
	
	private String name;
	
	//用於存放班級資訊的set
	private Set<Classes> classesSet;

	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 Set<Classes> getClassesSet() {
		return classesSet;
	}

	public void setClassesSet(Set<Classes> classesSet) {
		this.classesSet = classesSet;
	}
	
}
package cn.otote.e
ntity;

import java.util.Set;

public class Classes {

	private Integer id;
	
	//班級名稱
	private String  className;
	//用於存放教師資訊的set
	private Set<Teacher> teacherSet;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getClassName() {
		return className;
	}

	public void setClassName(String className) {
		this.className = className;
	}

	public Set<Teacher> getTeacherSet() {
		return teacherSet;
	}

	public void setTeacherSet(Set<Teacher> teacherSet) {
		this.teacherSet = teacherSet;
	}
	
	
}

2、配置Teacher的對映檔案。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- package為實體類所在的包名 -->        
<hibernate-mapping package="cn.otote.entity">
	
    <class name="Teacher" table="t_teacher" >
    
        <id name="id" column="id">
        	<!-- class="native"將主鍵id設為自增 -->
            <generator class="native"/>
        </id>

        <property name="name" ></property>
        
        <!-- name為存放另一方的set名稱 table為中間表的表名 -->
        <set name="classesSet" table="t_teacher_classes">
        
        	<!-- key為當前表在中間表的外來鍵 當前表是t_teacher 所以中間表的外來鍵是t_id -->
        	<key column="t_id"></key>
        	<!-- 配置多對多 class為另一方的型別 column為另一方在中間表的外來鍵 另一方為班級classes所以外來鍵為c_id -->
        	<many-to-many class="Classes" column="c_id"></many-to-many>
        </set>
    </class>

</hibernate-mapping>

3、配置Classes的對映檔案,兩者恰好相反。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- package為實體類所在的包名 -->        
<hibernate-mapping package="cn.otote.entity">
	
    <class name="Classes" table="t_classes" >
    
        <id name="id" column="id">
        	<!-- class="native"將主鍵id設為自增 -->
            <generator class="native"/>
        </id>

        <property name="className" column="class_name" ></property>
        
        <!-- name為存放另一方的set名稱 table為中間表的表名 -->
        <set name="teacherSet" table="t_teacher_classes">
        
        	<!-- key為當前表在中間表的外來鍵 當前表是t_classes 所以中間表的外來鍵是c_id -->
        	<key column="c_id"></key>
        	<!-- 配置多對多 class為另一方的型別 column為另一方在中間表的外來鍵 另一方為班級teacher所以外來鍵為t_id -->
        	<many-to-many class="Teacher" column="t_id"></many-to-many>
        </set>
    </class>

</hibernate-mapping>

4、在hibernate.cfg.xml將兩個對映檔案加進去。

5、測試

@Test
	void test() {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		Transaction transaction = session.beginTransaction();
		
		//建立兩個班級
		Classes classes1=new Classes();
		classes1.setClassName("初一一班");
		
		Classes classes2=new Classes();
		classes2.setClassName("初一三班");
		
		
		//建立兩個老師
		Teacher teacher1=new Teacher();
		teacher1.setName("張老師");
		
		Teacher teacher2=new Teacher();
		teacher2.setName("李老師");
		
		
		//預設是雙方都維護關係  但是隻要一方維護關係就可以了 這裡通過教師這一方來維護關係
		teacher1.setClassesSet(new HashSet<>());
		Set<Classes> classesSet1 = teacher1.getClassesSet();
		//將兩個班級都放到第一個老師的set集合中
		classesSet1.add(classes1);
		classesSet1.add(classes2);
		
		
		teacher2.setClassesSet(new HashSet<>());
		Set<Classes> classesSet2 = teacher2.getClassesSet();
		//將兩個班級都放到第二個老師的set集合中
		classesSet2.add(classes1);
		classesSet2.add(classes2);
		
		//儲存資料
		session.save(classes1);
		session.save(classes2);
		session.save(teacher1);
		session.save(teacher2);
		
		//提交事務
		transaction.commit();
		
	}

執行完開啟資料庫可以發現三張表都已經建立好了,中間表的外來鍵也都設定好了。再看資料,教師表和班級表的資料都已經插入,中間表的資料也維護好了。

中間表的外來鍵:

教師表:

班級表:

中間表資料:

需要注意的是多對多預設是雙方都維護關係的,所以我們只需要維護一方的關係就行了,如果操作時雙方都維護的話會報錯。當然也可以通過設定反轉來讓一方維護。