日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Hibernate 4 持久化類

 Joselyn_cui 2014-09-30
4.1 簡單的POJO例子
我們將會(huì)在下面的章節(jié)中詳細(xì)的描述持久化類的四個(gè)重要規(guī)則

4.1.1實(shí)現(xiàn)一個(gè)無參構(gòu)造方法
Cat 類有一個(gè)無參的構(gòu)造方法。所以的持久化類必須有一個(gè)默認(rèn)的構(gòu)造器(可以不是public的)因此,Hibernate可以通過反射(java.lang.reflect.Constructor.newInstance())來實(shí)例化他們。 推薦定義這個(gè)構(gòu)造器的可見性至少為package  以便讓運(yùn)行時(shí)代理能夠正常的工作。

4.1.2 提供一個(gè)唯一標(biāo)示屬性
注意:這個(gè)是推薦的,但是到現(xiàn)在都沒有強(qiáng)制要求。這一條將會(huì)棄用,因?yàn)樵趯淼陌姹局袑?huì)強(qiáng)制要求提供一個(gè)唯一標(biāo)示屬性。

Cat 有一個(gè)id屬性。 這個(gè)屬性對(duì)應(yīng)底層數(shù)據(jù)庫重的主鍵列。 唯一標(biāo)示的數(shù)據(jù)類型可以是任意的“基本”數(shù)據(jù)類型。 更多的復(fù)合主鍵參照9.4 聯(lián)合標(biāo)示主鍵。

注意:不需要在數(shù)據(jù)表中單獨(dú)為主鍵創(chuàng)建一個(gè)列, 他們只要是可以唯一的標(biāo)示這行數(shù)據(jù)在基本表中的唯一性即可。

我們推薦在持久化類中使用命名一致的標(biāo)示屬性, 可以把它定義為一個(gè)可以為Null的類型(例如, 非原始數(shù)據(jù)類型)

4.1.3推薦使用非final的類(可選)
Hibernate的一個(gè)重要的特性 ,代理(懶加載),依賴于非final的或者是一些實(shí)現(xiàn)了最只定義了public方法的接口的持久化類。你可以使用hibernate持久化一個(gè)沒有繼承任何借口的類,但是這就導(dǎo)致你不能使用延遲關(guān)聯(lián)抓取的代理,這最終會(huì)限制了你在性能調(diào)優(yōu)方面的選擇。如果要持久化一個(gè)只實(shí)現(xiàn)了一個(gè)接口部分方法的類, 你必須禁用代理生成。參考示例4.2, 4.3

Example 4.2 通過hbm.xml 禁用代理應(yīng)該避免聲明public final 方法, 否則將會(huì)限制你使用該類來產(chǎn)生代理。如果你想要使用一個(gè)帶有public final方法的類, 你必須明確的禁止使用代理。 參考示例4.2 和4.3。

4.1.4 為持久化字段聲明函數(shù)(可選)
Cat 類為他的每一個(gè)持久化字段都聲明了存取方法。 許多其他的ORM工具直接持久化實(shí)例變量。 比較好的做法是在關(guān)系模式和類的內(nèi)部數(shù)據(jù)結(jié)構(gòu)之間提供一個(gè)橋梁。默認(rèn)情況下, Hibernate 持久化JavaBean 識(shí)別格式為getFoo, isFoo和setFoo 的方法和屬性。 如果有需要, 一些特別的屬性你可以直接訪問字段。
屬性字段不需要一定是public的。Hibernate可以一樣持久化可見性為package,protected, 或者private的字段。

4.2 實(shí)現(xiàn)繼承
一個(gè)子類也必須遵守第一和第二規(guī)則。它從父類繼承唯一標(biāo)示屬性。 如Cat.你必須復(fù)寫equals() 和hashCode() 方法如果你想:
意圖把持久化類的實(shí)例存放在Set中(描述多值關(guān)聯(lián)的推薦的方式); 并且
意圖使用游離的實(shí)例。

Hibernate只在特定的session范圍保證持久化身份和Java身份的一致性。當(dāng)你在不同的session中混合檢索實(shí)例,如果你希望保證Sets是有意義的,那么你必須實(shí)現(xiàn)equals()和hashCode()方法。

最簡單的方法是實(shí)現(xiàn)equals()和hashCode()方法來比較來比較兩個(gè)對(duì)象間的標(biāo)示符的值。如果值相同,那么這兩個(gè)對(duì)象在一定在數(shù)據(jù)庫中對(duì)應(yīng)相同的數(shù)據(jù)行, 因?yàn)樗麄兪窍嗤摹?如果兩個(gè)都加入了Set集合,那么set集合中只會(huì)包含一個(gè)實(shí)例。不幸的是,對(duì)于自動(dòng)生成的標(biāo)示符不可以使用這種方法,因?yàn)镠ibernate只會(huì)為持久化的對(duì)象分配標(biāo)示符, 對(duì)于一個(gè)新產(chǎn)生的實(shí)例不會(huì)包含標(biāo)示符值。如果equals()和hashCode()基于標(biāo)示符,哈希碼將會(huì)改變, 打破了Set集合的約束??梢栽贖ibernate的網(wǎng)站中查看針對(duì)該問題的更多的討論內(nèi)容, 這不是Hibernate的問題, 而是普通的對(duì)象的一致性與相等行的Java語義問題。

推薦使用業(yè)務(wù)鍵值的相等性來實(shí)現(xiàn)equals()和hashCode()方法。業(yè)務(wù)鍵值相等意思是在equals方法中之比較有關(guān)業(yè)務(wù)的屬性值。 這個(gè)關(guān)鍵值可以在現(xiàn)實(shí)世界中唯一標(biāo)示一個(gè)實(shí)例(一個(gè)自然的候選關(guān)鍵字):

public class Cat {

    ...
    public boolean equals(Object other) {
        if (this == other) return true;
        if ( !(other instanceof Cat) ) return false;

        final Cat cat = (Cat) other;

        if ( !cat.getLitterId().equals( getLitterId() ) ) return false;
        if ( !cat.getMother().equals( getMother() ) ) return false;

        return true;
    }

    public int hashCode() {
        int result;
        result = getMother().hashCode();
        result = 29 * result + getLitterId();
        return result;
    }

}
一個(gè)業(yè)務(wù)關(guān)鍵字不一定是固定的候選主鍵(參考13.1.3章節(jié))。不變的或者獨(dú)一無二的屬性都是很好的業(yè)務(wù)關(guān)鍵字的候選。

 4.4 動(dòng)態(tài)模型
注意: 下面的特性是實(shí)驗(yàn)性的,在將來會(huì)有所改變。

在運(yùn)行時(shí)持久化實(shí)體不是必須要被表示為一個(gè)POJO類或者JavaBean對(duì)象。Hibernate也支持動(dòng)態(tài)模型。 使用這種方法,你不需要寫持久化類,只需要映射文件。

默認(rèn)情況下, Hibernate在普通的POJO模式下工作。你可以使用default_entity_mode配置選項(xiàng),為特定的SessionFactory設(shè)置 默認(rèn)的實(shí)體表示模型(參考3.3 “Hibernate 配置屬性”, default_entity_mode選項(xiàng)可以不用配置,session可以自己判斷 )。

下面的示例演示了使用MapS表示模型。首先, 在映射文件中需要聲明entity-name來替換類名, 或者除了類名之外還要聲明entity-name:
<hibernate-mapping>

    <class entity-name="Customer">

        <id name="id"
            type="long"
            column="ID">
            <generator class="sequence"/>
        </id>

        <property name="name"
            column="NAME"
            type="string"/>

        <property name="address"
            column="ADDRESS"
            type="string"/>

        <many-to-one name="organization"
            column="ORGANIZATION_ID"
            class="Organization"/>

        <bag name="orders"
            inverse="true"
            lazy="false"
            cascade="all">
            <key column="CUSTOMER_ID"/>
            <one-to-many class="Order"/>
        </bag>

    </class>
    
</hibernate-mapping>
雖然是用目標(biāo)類名來聲明冠梁的,但是關(guān)聯(lián)的目標(biāo)類型除了是POJO之外,也可以是一個(gè)動(dòng)態(tài)的實(shí)體。

在你給SessionFactory設(shè)置默認(rèn)的實(shí)體模型為dynamic-map之后, 在運(yùn)行時(shí)你可以使用Maps:
Session s = openSession();
Transaction tx = s.beginTransaction();

// Create a customer
Map david = new HashMap();
david.put("name", "David");

// Create an organization
Map foobar = new HashMap();
foobar.put("name", "Foobar Inc.");

// Link both
david.put("organization", foobar);

// Save both
s.save("Customer", david);
s.save("Organization", foobar);

tx.commit();
s.close();
動(dòng)態(tài)映射的好處是,變化所需要的時(shí)間少了, 因?yàn)閳A形不需要實(shí)現(xiàn)實(shí)體類, 然而, 你無法進(jìn)行編譯期的類型檢查, 并可能由此會(huì)處理很多的運(yùn)行期異常。 幸虧有了Hibernate映射, 他使得數(shù)據(jù)庫的schema可以容易的規(guī)格化和合理化, 并允許稍后再此之上添加合適的領(lǐng)域模型實(shí)現(xiàn)。
 
實(shí)體表示模式也能在每個(gè)Session的基礎(chǔ)上設(shè)置:
Session dynamicSession = pojoSession.getSession(EntityMode.MAP);//getSession(EntityMode mode)方法沒找到。

// Create a customer
Map david = new HashMap();
david.put("name", "David");
dynamicSession.save("Customer", david);
...
dynamicSession.flush();
dynamicSession.close()
...
// Continue on pojoSession
注意:使用的EntityModel調(diào)用getSession()是在Session的API中,而不是SessionFactory。 這樣新的額Session共享底層的JDBC鏈接, 事務(wù),和其他的上下文信息。這意味著你不需要再第二個(gè)Session中調(diào)用flush()和close(),同樣的, 把事務(wù)和鏈接的處理交給原來的工作單元。

4.5 元組片段映射













    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多