單向多對一關聯關係:
eg:多個學生屬於一個班級。在一對多的例子上,我們進行一些改變來建立單向多對一映射:
在student類中增加一個grade班級屬性,建立其get/set方法:
private int sid; //學生編號
private String sname; //學生姓名
private String sex; //學生性別
//在多方定義一個一方的引用->學生屬於某個班級
private Grade grade;
修改映射文件Student.hbm.xml(注意使用many-to-one配置多對一關聯關係):
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.entity.Student" table="student">
<id name="sid" column="sid" type="java.lang.Integer">
<generator class="increment"></generator>
</id>
<property name="sname" type="java.lang.String">
<column name="sname" length="20" not-null="true"></column>
</property>
<property name="sex" type="java.lang.String">
<column name="sex"></column>
</property>
<!-- 配置多對一關聯關係 :many-to-one-->
<many-to-one name="grade" class="com.entity.Grade" column="gid"></many-to-one>
</class>
</hibernate-mapping>
Grade.hbm.xml(因爲是單向的多對一關係,要將Grade.hbm.xml中原配置的一對多的關聯關係註釋掉):
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.entity.Grade" table="grade">
<id name="gid" column="gid" type="java.lang.Integer">
<generator class="increment"></generator>
</id>
<property name="gname" type="java.lang.String">
<column name="gname" length="20" not-null="true"></column>
</property>
<property name="gdesc" type="java.lang.String">
<column name="gdesc"></column>
</property>
<!-- 配置單向的一對多關聯關係
<set name="students" table="student">
<key column="gid"></key> 指定關聯的外鍵列
<one-to-many class="com.entity.Student"></one-to-many>
</set>
-->
</class>
</hibernate-mapping>
測試類Test02(先清空數據庫中表的數據):
package com.entity;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.util.HibernateUtil;
/**
* 單向多對一(學生->班級)
* */
public class Test02 {
public static void main(String[] args) {
save();
}
//保存學生信息
public static void save(){
Grade g=new Grade("Java","Java軟件開發一班"); //創建一個班級
Student stu1=new Student("穆女神","女"); //創建學生
Student stu2=new Student("小木木","男"); //創建學生
//設置關聯關係,指定學生同班級的關係
stu1.setGrade(g);
stu2.setGrade(g);
Session session=HibernateUtil.getSession();
Transaction tx=session.beginTransaction(); //開啓事務
//保存
session.save(g);
session.save(stu1);
session.save(stu2);
tx.commit(); //提交事務
HibernateUtil.closeSession(session); //關閉session
}
}
grade表:
student表:
雙向多對一關聯關係:
雙向關聯關係的建立需要在雙方配置關聯關係
注意:在本例中,student類裏面定義了grade班級屬性,已經進行了關係的維護。而inverse屬性用來指定關係的維護,其默認值爲false,表示由‘一方’(班級)來進行維護。雙方都進行了維護會使性能降低。
所以:當需要只由多方(學生)進行維護時,可將其inverse的值設置爲true,由多方維護關聯關係,一方不維護。
配置一對多的關聯關係,Grade.hbm.xml(要設置inverse屬性和cascade屬性):
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.entity.Grade" table="grade">
<id name="gid" column="gid" type="java.lang.Integer">
<generator class="increment"></generator>
</id>
<property name="gname" type="java.lang.String">
<column name="gname" length="20" not-null="true"></column>
</property>
<property name="gdesc" type="java.lang.String">
<column name="gdesc"></column>
</property>
<!-- 配置一對多關聯關係 ,設置inverse屬性爲true,由多方維護關聯關係,一方不維護(inverse用來指定關聯關係的維護)-->
<!-- cascade=save-update:在保存更新班級時自動級聯操作所關聯的對象(學生)的信息 -->
<set name="students" table="student" inverse="true" cascade="save-update">
<!-- 指定關聯的外鍵列 -->
<key column="gid"></key>
<one-to-many class="com.entity.Student"></one-to-many>
</set>
</class>
</hibernate-mapping>
配置多對一的關聯關係,Student.hbm.xml:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.entity.Student" table="student">
<id name="sid" column="sid" type="java.lang.Integer">
<generator class="increment"></generator>
</id>
<property name="sname" type="java.lang.String">
<column name="sname" length="20" not-null="true"></column>
</property>
<property name="sex" type="java.lang.String">
<column name="sex"></column>
</property>
<!-- 配置多對一關聯關係 :many-to-one-->
<many-to-one name="grade" class="com.entity.Grade" column="gid"></many-to-one>
</class>
</hibernate-mapping>
測試類Test02(增加一方對多方的關聯關係):
package com.entity;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.util.HibernateUtil;
//建立雙向關係
//可以由學生查找班級信息,也可由班級查找所包含的學生
public class Test02 {
public static void main(String[] args) {
// save();
findGradeByStudent();
}
//保存學生信息
public static void save(){
Grade g=new Grade("Java","Java軟件開發一班"); //創建一個班級
Student stu1=new Student("穆女神","女"); //創建學生
Student stu2=new Student("小木木","男"); //創建學生
//增加班級對學生的一對多的關聯關係
//此時一方(班級)維護這種關係會產生兩條update語句,但是這兩條語句實則是多餘的,可以通過inverse屬性來去掉這兩句話
g.getStudents().add(stu1);
g.getStudents().add(stu2);
//設置關聯關係,指定學生同班級的關係(多對一的關聯關係)
stu1.setGrade(g);
stu2.setGrade(g);
Session session=HibernateUtil.getSession();
Transaction tx=session.beginTransaction(); //開啓事務
//保存
session.save(g);//級聯操作,當保存班級時,將班級的包含的學生(這些學生當前未存儲在數據庫中)也存儲在數據庫中,而不必再手寫代碼進行學生存儲。
//設置cascade=save-update,在保存班級時自動級聯操作所關聯的學生
// session.save(stu1);
// session.save(stu2);
tx.commit(); //提交事務
HibernateUtil.closeSession(session); //關閉session
}
//查詢學生所在班級信息
public static void findGradeByStudent(){
Session session=HibernateUtil.getSession(); //獲得session
Student stu=(Student) session.get(Student.class, 2);//獲取id爲2的學生信息
System.out.println(stu.getSid()+","+stu.getSname()+","+stu.getSex());
//獲取學生所在班級信息
Grade g=stu.getGrade();
System.out.println(g.getGid()+","+g.getGname()+","+g.getGdesc());
HibernateUtil.closeSession(session);
}
}
執行save,數據庫(先要清空數據庫的表):
grade表:
student表:
執行find,控制檯: