hibernate中load和get方法的區別
1)當數據庫不存在對應ID數據時,調用load()方法將會拋出ObjectNotFoundException異常,get()方法將返回null.
2)也就是延時加載的區別。load的方法默認要加載的對象是存在數據庫中的,返回的是一個代理對象而不是一個真正的類實例,
當用到具體與數據庫有關的數據時候才查詢數據庫,而get方法直接查詢數據庫,返回類的實例。
3)get方法首先查詢session緩存,沒有的話查詢二級緩存,最後查詢數據庫;反而load方法創建時首先查詢session緩存,沒有
就創建代理,實際使用數據時才查詢二級緩存和數據庫。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Hibernate的工作流程:
1. 讀取並解析配置文件
2. 讀取並解析映射信息,創建SessionFactory
3. 打開Sesssion
4. 創建事務Transation
5. 持久化操作
6. 提交事務
7. 關閉Session
8. 關閉SesstionFactory
Hibernate中bean 的三種狀態
Hibernate對象分爲三種狀態:瞬時態(new 出來的或者實例化時session無關的),持久態(session關聯)與託管態(曾經與session關聯)。
其中持久態的對象是PO,瞬時態、託管態的對象可作爲VO。(PO不應該直接用作v層)所以在使用中應該注意三態的轉化。
如:在進行數據操作的一系列過程中,save或者saveorupdate操作可以把順勢態或者託管態的對象轉換成持久態,而delete或者session的close、
flush等操作將會把session相關聯的持久態對象轉換成託管態。
Hibernate配置文件詳解
一、hibernate.cfg.xml文件:
<!--該文件的開頭信息,對Hibernate而言,該類文件基本都這麼開頭:)-->
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!-- 正文開始 -->
<hibernate-configuration>
<!--下面是數據庫的基本連接信息,對一個應用來說,設置一個session-factory節點就夠了,除非我們中間使用了多個數據庫-->
<session-factory>
<!--用戶名 -->
<property name="connection.username">root</property>
<!--url信息 -->
<property name="connection.url">jdbc:mysql://localhost:3306/webases</property>
<!--數據庫方言信息-->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!--密碼 -->
<property name="connection.password">274507</property>
<!--數據庫驅動信息 -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<!--指定Hibernate映射文件路徑 -->
<mapping resource="com/Hibernate/test_products.hbm.xml" />
</session-factory>
</hibernate-configuration>
二、.hbm.xml文件:
由於Hibernate的關聯關係包含了一對一、一對多、多對一和多對多等四種類型,因此,也就有分別與之對應的四種.hbm.xml文件。下面我們就以比較常用的雙向“一對多”型關聯關係爲例,介紹一下.hbm.xml文件的基本結構和內容。有關Hibernate更詳細的內容,請參考相關文資料。
該例中有兩張數據庫表:一張爲“省”表,另一張爲“市”表,所用的數據庫爲MySQL。二者的建表語句如下:
CREATE TABLE IF NOT EXISTS Province
(
Guid INT NOT NULL AUTO_INCREMENT,
Provincename VARCHAR(16) NOT NULL,
PRIMARY KEY (Guid)
) TYPE=InnoDB;
CREATE TABLE IF NOT EXISTS City
(
Guid INT NOT NULL AUTO_INCREMENT,
Cityname VARCHAR(32) NOT NULL,
ProvinceID INT NOT NULL,
PRIMARY KEY (Guid)
) TYPE=InnoDB;
ALTER TABLE City ADD CONSTRAINT CityRFProvince FOREIGN KEY (ProvinceID)
REFERENCES Province (Guid) ON DELETE CASCADE ON UPDATE RESTRICT;
Province表爲主控方,City表爲被控方,兩者之間存在雙向的一對多的關係。表City通過外鍵ProvinceID與表Province進行關聯:當表Province中有記錄被刪除時,表City中相關記錄亦被刪除;當表Province中有記錄被保存或者更新時,表City中相關記錄無任何變化。
將Hibernate自帶工具Middlegen生成的Province.hbm.xml文件進行修改,內容如下:
<!--該文件的開頭信息,對Hibernate而言,該類文件基本都這麼開頭:)-->
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"
>
<!-- 映射文件開始 -->
<hibernate-mapping>
<!-- 下面的class節點定義了Province類和對應數據庫表之間的關聯關係 -->
<class
name="com.xxx.hibernate.Province"
table="Province"
>
<!-- 下面的兩個節點定義了Province類中的屬性和該類對應數據庫表中的字段之間的關聯關係,其中Guid爲對應數據庫表的主鍵 -->
<id
name="guid"
type="int"
column="Guid"
>
<generator class="native" />
</id>
<property
name="provincename"
type="java.lang.String"
column="Provincename"
not-null="true"
length="16"
>
</property>
<!-- 下面的set節點定義了Province類和City類之間的”一對多“型關聯關係 -->
<set
name="cities"<!-- 集合屬性的名稱 -->
lazy="true"<!-- 是否允許延遲加載 -->
inverse="true"<!-- 定義這個集合是否爲雙向關聯關係中的方向一端 -->
cascade="delete"<!-- 定義有關操作是否關聯到子實體(此處指City類對象) -->
>
<key>
<column name="ProvinceID" /><!-- 定義集合所對應的數據庫表的外鍵 -->
</key>
<one-to-many
class="com.xxx.hibernate.City"<!-- 定義集合所屬的類-->
/>
</set>
</class>
</hibernate-mapping>
將Hibernate自帶工具Middlegen生成的City.hbm.xml文件進行修改,內容如下:
<!--該文件的開頭信息,對Hibernate而言,該類文件基本都這麼開頭:)-->
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"
>
<!-- 映射文件開始 -->
<hibernate-mapping>
<!-- 下面的class節點定義了City類和對應數據庫表之間的關聯關係 -->
<class
name="com.xxx.hibernate.City"
table="City"
>
<!-- 下面的兩個節點定義了City類中的屬性和該類對應數據庫表中的字段之間的關聯關係,其中Guid爲對應數據庫表的主鍵-->
<id
name="guid"
type="int"
column="Guid"
>
<generator class="native" />
</id>
<property
name="cityname"
type="java.lang.String"
column="Cityname"
not-null="true"
length="32"
>
</property>
<!-- 下面的many-to-one節點定義了Province類和City類之間的”一對多“型關聯關係 -->
<many-to-one
name="province"<!-- 屬性名稱 -->
class="com.xxx.hibernate.Province"<!-- 屬性所屬的類 -->
cascade="none"<!-- 指定哪些操作會從父對象(此處指City類對象)級聯到子對象(此處指Province類對象) -->
outer-join="auto"<!-- 設置父子對象之間是否存在外連接 -->
not-null="true"<!-- 指定該屬性是否一定爲非空 -->
>
<column name="ProvinceID" /><!-- 定義父對象(此處指City類對象)所對應的數據庫表的外鍵 -->
</many-to-one>
</class>
</hibernate-mapping>
多對多的雙向關聯關係(中間表)
在多對多的關聯關係中,可拆分爲兩個一對多的關聯關係,即在兩個表中間增加一個關聯表,記錄這兩個表之間的關聯關係。若拋開關聯表,則原2個表之間看不出任何的關係。 以爲考試類別和考試科目爲例,詳細講解在添加關聯表的情況下兩個表之間的hibernate設置。
<?xml version="1.0"?> <hibernate-mapping>
package model; import java.io.Serializable; public class ExamSortEnum implements Serializable{ public Set getSubject(){ public void setId(Integer id) { public String getName() { public void setName(String name) {
映射文件要設置set,name=subject 爲ExamSortEnum.java文件中定義的Set對象,存儲多個Subject類型的容器。
<?xml version="1.0"?> <hibernate-mapping> Subject.java package model; import java.io.Serializable; public class Subject implements Serializable{ public Integer getId() { public void setId(Integer id) { public String getName() { public void setName(String name) {
測試類: import org.hibernate.Session; public class ExamSortEnumTest { Subject sc = new Subject(); |