關聯映射
一對多雙向關聯
- 實體
package com.xingxue.day4.hibernate.demo1.domain;
import java.util.HashSet;
import java.util.Set;
// 一個班級對應多個老師,一個老師屬于一個班級
public class ClassModel {
//標識字段
private Long id;
//業務字段
private String cname;
private String description;
//關聯字段
private Set<TeacherModel> teacherModels = new HashSet<TeacherModel>();
public Set<TeacherModel> getTeacherModels() {
return teacherModels;
}
public void setTeacherModels(Set<TeacherModel> teacherModels) {
this.teacherModels = teacherModels;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
===============================================================================
package com.xingxue.day4.hibernate.demo1.domain;
public class TeacherModel {
private Long id;
private String tname;
private ClassModel classModel;
public ClassModel getClassModel() {
return classModel;
}
public void setClassModel(ClassModel classModel) {
this.classModel = classModel;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTname() {
return tname;
}
public void setTname(String tname) {
this.tname = tname;
}
}
- 映射文件
<?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.xingxue.day4.hibernate.demo1.domain.TeacherModel" table="t_teacher">
<id name="id" column="id">
<generator class="sequence">
<param name="sequence_name">
teacher_seq
</param>
</generator>
</id>
<property name="tname" column="tname"></property>
<!--通過 many2one 描述 關系:多對一的關系
name 屬性: 設置關聯的字段名稱
class 屬性: 關聯的類型
column 子標簽:設置多方的外鍵名稱
-->
<many-to-one name="classModel" class="com.xingxue.day4.hibernate.demo1.domain.ClassModel" column="cid"/>
</class>
</hibernate-mapping>
===============================================================================
<?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.xingxue.day4.hibernate.demo1.domain.ClassModel" table="t_class">
<id name="id" column="id">
<generator class="sequence">
<param name="sequence_name">
class_seq
</param>
</generator>
</id>
<property name="cname" column="cname"></property>
<property name="description"></property>
<!-- set 標簽 描述 關聯字段的 類型
name 屬性: 關聯字段的名稱
inverse 屬性:就是描述是否當前實體是否放棄外鍵的維護,默認就是false,表示不放棄
設置為 true 表示 當前實體放棄外鍵的維護。
-->
<set name="teacherModels" inverse="false">
<!-- 配置多方表中的外鍵,使用 key 標簽
column 屬性:指定外鍵的名稱
-->
<key>
<column name="cid"></column>
</key>
<!-- one2many 標簽 描述 關系
class 屬性:設置關聯的類型
-->
<one-to-many class="com.xingxue.day4.hibernate.demo1.domain.TeacherModel"></one-to-many>
</set>
</class>
</hibernate-mapping>
- 關系維護(inverse):默認情況下,一方也可以維護外鍵的關系,多方必須維護外鍵的關系(也就是說,多方法不能設置 inverse屬性),往往 一方應該放棄外鍵的維護,因為采用一方外鍵維護,會單獨的發 update 語句去更新外鍵的值,造成多發sql 的情況。所以可以在一方的 set 標簽上設置 inverse屬性為 true 表示放棄外鍵的維護。
<set name="teacherModels" inverse="true">
- 關聯對象導航圖查詢以及優化(fetch)
一方 可以配置 fetch:
select(默認的):先查主表,同過主表的記錄中的id 去分別發sql 查詢關聯表數據。
join: 采用 left outter join 進行主從連接查詢,如果采用 lazy 屬性 失效。
subselect:只有在一方配置文件中才有該選項,在多方配置文件中沒有該選項,在 hql 中 查詢主表有多個記錄的時候,在查詢關聯的數據的時候,就會采用 子查詢。
多方 可以配置 fetch:
select(默認的):先查主表,同過主表的記錄中的id 去分別發sql 查詢關聯表數據。
join: 采用 left outter join 進行主從連接查詢,如果采用 lazy 屬性 失效。
級聯操作 (cascade)
cascade 屬性: 一般 delete 不要去配。
save-update:保存當前實體,就會級聯保存關聯的實體
delete : 刪除當前實體,級聯刪除關聯的實體
all : save-update 和 delete
delete-orphan:孤兒刪除,只能在 一對多關聯中使用.主表是一方,從表多方,如果從表的記錄沒有關聯主表的外鍵值,從表的該記錄可以視為是孤兒,就會刪除。
all-delete-orphan : all delete-orphan-
hql 關聯查詢
迫切左外連接
select c from ClassModel c left join fetch c.teacherModels ,發一條sql
左外連接
select c from ClassModel c left join c.teacherModels ,發兩條from ClassModel c left join c.teacherModels:返回的類型是 Object[] 類型
多對多雙向關聯
詳見代碼,注意一般來說應該放棄一方的外鍵維護