Hibernate的多表設計以及加載策略

多對多配置

實體類

public class Course {
    private Integer id;
	private String name;
	private Set<Student> studentSet = new HashSet<Student>();
	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<Student> getStudentSet() {
		return studentSet;
	}
	public void setStudentSet(Set<Student> studentSet) {
		this.studentSet = studentSet;
	}
	
}
public class Student {

 private Integer id;
 private String name;
 private Set<Course> courseSet = new HashSet<Course>();
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<Course> getCourseSet() {
	return courseSet;
}
public void setCourseSet(Set<Course> courseSet) {
	this.courseSet = courseSet;
}
 
}

hbm.xml配置

<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.study.hibernate" >
<!-- 實體類與數據庫的對應關係 -->
<class   name="Student" table="t_student" dynamic-insert="false" select-before-update="true">
<id name="id" column="id" unsaved-value="1">
<!--主鍵生成策略  -->
<generator class="native"></generator>
</id>
<property name="name">
<column name="name"></column>
</property>

<!--
多對多配置:
set中的table:多對多關聯的中間表
<key 中column:中間表中對應的列
<many-to-many表示是多對多關係,column表示與之對應的另一個表中的列
  -->
<set name="courseSet" table="t_student_course" inverse="false" cascade="save-update">
<key column="cno"></key>
<many-to-many class="Course" column="sno"/>
</set>
</class>
</hibernate-mapping>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.study.hibernate" >
<!-- 實體類與數據庫的對應關係 -->
<class   name="Course" table="t_course" dynamic-insert="false" select-before-update="true">
<id name="id" column="id" unsaved-value="1">
<!--主鍵生成策略  -->
<generator class="native"></generator>
</id>
<property name="name">
<column name="name"></column>
</property>
<!--通過學生來維護表之間的關係  -->
<set name="studentSet" table="t_student_course" inverse="true">
<key column="sno"></key>
<many-to-many class="Student" column="cno"/>
</set>
</class>
</hibernate-mapping>


加載策略:

按照其檢索方式分爲:

1.立即檢索:立即查詢,在執行查詢語句時,立即查詢所有的數據

2.延遲檢索:延遲查詢,在執行查詢語句之後,在需要時查詢

按照其檢查策略的種類分爲:

1.類級別檢索:當前類的屬性獲取是否需要需要延遲

2.關聯級別的檢索:當前類關聯另一個類是否需要延遲

 

類級別檢索:

1.get方法:立即查詢數據庫,將數據初始化

2.load方法:hbm文件中,class元素的lazy屬性決定是否需要延遲加載,true表示使用延遲加載。false表示不使用延遲加載,與get一樣,立即加載數據,不配置則使用延遲加載

關聯級別的加載策略:

在查詢有關聯關係的數據時,加載一方的數據是否需要將另一方立即查詢出數據。默認情況下,關聯的數據,在使用時才查詢出數據。

關聯級別的檢索在set元素中有兩個屬性決定採用什麼樣的組合方式加載數據:

1.lazy: 是否對set數據使用懶加載
                    true:(默認值) 對集合使用時才加載
                    false: 集合將會被立即加載
                    extra: 極其懶惰,如果使用集合時,調用size方法查詢數量, Hibernate會發送count語句,只查詢數量.不加載集合內數據.

2.fetch : 決定加載集合使用的sql語句種類
                    select: (默認值) 普通select查詢
                    join: 錶鏈接語句查詢集合數據
                    subselect: 使用子查詢

 

一對多:

fetch="join"

lazy無效。底層使用迫切左外連接,使用一條select將所有內容全部查詢

fetch="select"

 

當前對象 和 關聯對象 使用多條select語句查詢。

lazy="false" , 立即,先查詢客戶select,立即查詢訂單select

lazy="true",延遲,先查詢客戶select,需要訂單時,再查詢訂單select

 lazy="extra",極其懶惰(延遲),先查詢客戶select, 如果只需要訂單數,使用聚合函數(不查詢詳情)

<set name="orderSet" inverse="true" cascade="save-update" lazy="extra" fetch="select">


fetch="subselect"

 

使用子查詢,注意一點:必須使用query查詢纔可以看到此現象

 

lazy:同上

 

多對一:

多對一:
        lazy
             false        加載數據時,會立即加載關聯對象的數據
             proxy        看關聯對象的類加載策略(lazy="true" 延遲加載,lazy="false" 立即加載)來決定
             no-proxy :
         fetch=
            select  : (默認值)使用普通select加載
            join    : 使用錶鏈接加載數據,lazy無效
    
    fetch            lazy            結果
---------------------------------------------------
    select            false            加載對象時,立即加載關聯對象數據.普通select語句加載關聯對象.
    select            proxy            類加載策略爲:lazy=false 同上
                                                 lazy=true    加載對象時,先不加載關聯對象數據.使用關聯對象數據時才加載
    join            false            使用錶鏈接加載數據.lazy屬性無效
    join            proxy            使用錶鏈接加載數據.lazy屬性無效

 

批量加載:

使用<set batch-size="5"> 表示每次加載關聯對象時,加載幾個.

 

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