一)Hibernate意義
在一個真正的OOAD中,我們的設計首先是做UML建摸,最終將一個系統涉及所有對象(這個東西不是東西那麼簡單)用類圖來體現一個完整的設計,我們最後可能得到這幾種類:控制商務邏輯的類,儲存業務資料的類module(bean類),輔助類或者更多(具體問題具體分析,但是將業務所需資料歸結為一個類module更適合分層)。到資料庫低層實現的時候,
為了擷取資料或者儲存資料,你不得不為此加上一個操作資料庫的控制邏輯,到此,你完美的設計估計會為此付出巨大的努力,因為你看到的業務資料層是一個複雜的模組,即使從物件導向觀點來看,我們UML類圖中的,業務資料層只是一個資料模組。Hibernate已經幫我們解決了業務資料層這個本來十分複雜的模組的底層實現,現在,我們只要在外層裹上我們的代表資料的類即可。
二)物件模型與關聯式資料庫模型差異
在寫出我初探Hibernate的感受之前,我覺得寫下這一節還是很有必要的。帶著問題研究遠遠比帶著好奇研究要意義深遠得多。
問題領域:
關係型資料庫是儲存資料的最好選擇,但是隨著OO技術日益發展,在persisitent層上關係型資料庫的設計體系與OO體系格格不入,可以想象,當滿腦子充斥著OOAD的你想到怎麼隔離滿天飛的SQL語句時,那是多麼痛苦的表情。無論你的業務層設計多麼完美,在真正儲存資料或者載入資料時,你面對的無非是一大堆封裝好的資料,這些資料在JDBC中已經完全失去對象(這裡的對象稱之為業務對象或許更為確切)的意義,你整體的OOAD到此為止。為什麼會造成這種情況呢?原因是物件模型與關聯式資料庫模型根本設計體系之間的差別。
物件模型與關聯式資料庫模型各自理論出發點是不同的:物件模型的理論體系可以簡單歸結為這兩點:
1) 以對象看待世界。
2) 對象間關係(繼承,關聯,彙總,組合)維繫著整體構成。
而關聯式資料庫模型唯一出發點是有效儲存資料,KEY是資料庫的關鍵技術,關係在這裡只是各個資料表的KEY之間的關聯,這種關聯我覺得應該稱之為資料的關聯,其表達的意義遠遠沒有對象之間的關聯那麼深廣。
那麼,我現在最關心的問題是hibernate是怎麼利用關聯式資料庫的資料表KEY關聯來表達對象之間的關係呢?
在進入正式研究Hbernate之前,我們可以思索一下問題的似乎簡單與似乎十分複雜的矛盾。
我們設計的代表資料層的所有類必須完美的體現在資料表之中。可以這樣總結:
class-àtable
class1—(關係)---class2------〉table1---(關係)-----table2
問題的解決似乎很簡單,特別是對於javabean構架,更是簡單(看起來簡單而已!!!)。
想象一個簡單的javabean類:
public class SimpleBean{ protected int id; protected String name; public int getId(){ return id; } public void setId(int id){ this.id=id; } public String getName(){ return name; } public void setName(String name){ this,name=name; } } |
我們完全可以這樣進行name映射:
className-àtableName propertyNameàcolumnName |
一個類執行個體就是table的一行。這個問題很簡單的得到解決。
再進一步,考慮如下簡單的一對一類關聯:
public class Class1{ public Class2 class2; public Class2 getclass2()… public void setClass2(Class2 class2)… } public class Class2{ public Class1 class1; public Class1 getClass1()... ... } |
這種關係很顯然是雙向的,可以從class1中得到class2,反過來,也可以從class2中得到class1,那麼體現到資料表中呢?首先可以肯定class1àtable1,class2àtable2;很顯然,table1和table2都要互相增加多一列來儲存對方的key。
這些簡單的關係在資料庫表的關聯中得到了很好的支援,但是稍微複雜一點的呢?
諸如以下一個類:
public class S { ArrayList datas; Public List getDatas().. Public void setDatas(List datas).. …. } |
這裡如果簡單用上面所分析的propertyname-àColumnName顯然不可以,這種集合作為bean屬性我們該怎麼在資料表中得到很好體現呢?如果這些集合只是簡單的String 集合,它在資料庫表裡面是怎麼表述的呢?如果這些集合是儲存某些類執行個體的,似乎可以轉換為資料庫表的一對多的關係?
另外一方面,繼承體系是怎麼在資料區塊表裡面得到體現的呢?繼承的關係怎麼用資料庫的關聯關係表達呢?繼承所涉及的動態類識別怎麼在資料庫中得到體現呢?
再往深處想一想,對於一個操作:
public class BookStore{ Set books; Public Set getBoos().. Public void setBooks(Set boos)… Public void addBook(Book book)… public class Book{ public BookStore bookStore; public Parent getBookStore().. .. } |
在商務邏輯中,我們會這樣寫代碼:
Book book=new Book(); .bookStore.addBooks(book); |
上面兩行代碼便已經清楚地建立了child與parent之間的關係,相對來說,資料庫中的資料也應該根據這幾行代碼建立產生資料並建立這種關聯。此時記憶體中的資料怎麼跟資料庫中的資料一致呢?