舉例說明Hibernate持久化技術(shù)
Hibernate持久化技術(shù)讓我們能夠工作得更好,我們通過一個例子來簡單說明Hibernate持久化技術(shù)的應(yīng)用。
在一般應(yīng)用程序中,用來實現(xiàn)業(yè)務(wù)問題實體的(如,在電子商務(wù)應(yīng)用程序中的Customer和Order) 類就是持久化類。不能認(rèn)為所有的持久化類的實例都是持久的狀態(tài)——一個實例的狀態(tài)也可能 是瞬時的或脫管的。
如果這些Hibernat持久化類遵循一些簡單的規(guī)則,Hibernate能夠工作得更好,這些規(guī)則也被稱作 簡單傳統(tǒng)Java對象(POJO:Plain Old Java Object)編程模型。但是這些規(guī)則并不是必需的。 實際上,Hibernate3對于你的持久化類幾乎不做任何設(shè)想。你可以用其他的方法來表達(dá)領(lǐng)域模型: 比如,使用Map實例的樹型結(jié)構(gòu)。
一個簡單的POJO例子說明Hibernate持久化
大多數(shù)Java程序需要用一個持久化類來表示貓科動物。
- package eg;
- import java.util.Set;
- import java.util.Date;
- public class Cat {
- private Long id; // identifier
- private Date birthdate;
- private Color color;
- private char sex;
- private float weight;
- private int litterId;
- private Cat mother;
- private Set kittens = new HashSet();
- private void setId(Long id) {
- this.id=id;
- }
- public Long getId() {
- return id;
- }
- void setBirthdate(Date date) {
- birthdate = date;
- }
- public Date getBirthdate() {
- return birthdate;
- }
- void setWeight(float weight) {
- this.weight = weight;
- }
- public float getWeight() {
- return weight;
- }
- public Color getColor() {
- return color;
- }
- void setColor(Color color) {
- this.color = color;
- }
- void setSex(char sex) {
- this.sex=sex;
- }
- public char getSex() {
- return sex;
- }
- void setLitterId(int id) {
- this.litterId = id;
- }
- public int getLitterId() {
- return litterId;
- }
- void setMother(Cat mother) {
- this.mother = mother;
- }
- public Cat getMother() {
- return mother;
- }
- void setKittens(Set kittens) {
- this.kittens = kittens;
- }
- public Set getKittens() {
- return kittens;
- }
- // addKitten not needed by Hibernate
- public void addKitten(Cat kitten) {
- kitten.setMother(this);
- kitten.setLitterId( kittens.size() );
- kittens.add(kitten);
- }
- }
這里要遵循四條主要的規(guī)則:
1. 實現(xiàn)一個默認(rèn)的(即無參數(shù)的)構(gòu)造方法(constructor)
Cat有一個無參數(shù)的構(gòu)造方法。所有的持久化類都必須有一個 默認(rèn)的構(gòu)造方法(可以不是public的),這樣的話Hibernate就可以使用 Constructor.newInstance()來實例化它們。 我們強(qiáng)烈建議,在Hibernate中,為了運(yùn)行期代理的生成,構(gòu)造方法至少是 包(package)內(nèi)可見的。
2. 提供一個標(biāo)識屬性(identifier property)(可選)
Cat有一個屬性叫做id。這個屬性映射數(shù)據(jù)庫表的主 鍵字段。這個屬性可以叫任何名字,其類型可以是任何的原始類型、原始類型的包裝類型、 java.lang.String 或者是 java.util.Date。 (如果你的遺留數(shù)據(jù)庫表有聯(lián)合主鍵,你甚至可以用一個用戶自定義的類,該類擁有這些類型 的屬性。參見后面的關(guān)于聯(lián)合標(biāo)識符的章節(jié)。)
標(biāo)識符屬性是可選的。可以不用管它,讓Hibernate內(nèi)部來追蹤對象的識別。 但是我們并不推薦這樣做。
實際上,一些功能只對那些聲明了標(biāo)識符屬性的類起作用:
托管對象的傳播性再連接(級聯(lián)更新或級聯(lián)合并) ——參閱 第 10.11 節(jié) “傳播性持久化(transitive persistence)”
◆Session.saveOrUpdate()
◆Session.merge()
我們建議你對持久化類聲明命名一致的標(biāo)識屬性。我們還建議你使用一 個可以為空(也就是說,不是原始類型)的類型。
3. 使用非final的類 (可選)
代理(proxies)是Hibernate的一個重要的功能,它依賴的條件是,持久 化類或者是非final的,或者是實現(xiàn)了一個所有方法都聲明為public的接口。
你可以用Hibernate持久化一個沒有實現(xiàn)任何接口的final類,但是你 不能使用代理來延遲關(guān)聯(lián)加載,這會限制你進(jìn)行性能優(yōu)化的選擇。
你也應(yīng)該避免在非final類中聲明 public final的方法。如果你想使用一 個有public final方法的類,你必須通過設(shè)置lazy="false" 來明確地禁用代理。
4. 為持久化字段聲明訪問器(accessors)和是否可變的標(biāo)志(mutators)(可選)
Cat為它的所有持久化字段聲明了訪問方法。很多其他ORM工具直接對 實例變量進(jìn)行持久化。我們相信,在關(guān)系數(shù)據(jù)庫schema和類的內(nèi)部數(shù)據(jù)結(jié)構(gòu)之間引入間接層(原文為"非直接",indirection)會好一些。默認(rèn)情況下Hibernate持久化JavaBeans風(fēng)格的屬性,認(rèn)可 getFoo,isFoo 和 setFoo這種形式的方法名。 如果需要,你可以對某些特定屬性實行直接字段訪問。
屬性不需要要聲明為public的。Hibernate可以持久化一個有 default、protected或private的get/set方法對的屬性進(jìn)行Hibernate持久化。
TODO:property和proxy包里的用戶擴(kuò)展框架文檔。
【編輯推薦】