在Object-Relational Database mapping中,hibernate是一個相當受到重視的
函式庫,在即將release的EJB 3.0裡面,persistence的技術會在相當程度中參考hibernate
的設計。這一期我們來看看hibernate的簡單介紹。
hibernate最主要的精神在於將一般的JavaBean和Database進行連結,不同於JDO
( Java Data Object )需要在compile之後對原始的JavaBean進行修改(enhance),hibernate
允許我們直接將一般的JavaBean跟資料庫做連結。在以往的O-R Mapping中,有兩個常見的
作法:
1. 在每個getter/setter函式自行撰寫SQL指令
2. 實作特定的介面,由中繼軟體來呼叫這些介面完成persistence
這兩者都有明顯的缺點,首先,自行撰寫SQL指令就難以避免SQL語法不相容的問題,而且不同Database
對於Transaction和locking的作法不盡相同,使得使用這種作法的程式可攜性很低。第二種作法
往往中繼程式能處理的部份有限,使用者如果要達到足夠的彈性,還是要在實作介面的函式中撰寫
SQL指令。
hibernate比較接近第一種作法,不同的是,在getter/setter中所使用的SQL指令由
hibernate的函式庫在動態產生,由於hibernate的設定檔可以設定對應的SQL語言種類,所以
相容性的問題大大的改善了,在效能上其實難以避免會有一些損失,但是透過reflection和SQL
語法的最佳化,其實效能往往會比 "不小心" 寫得不好的SQL指令要強得多。更令人讚賞的是,
hibernate對於資料庫操作的實作相當完整,transaction/large binary/isolation......
這些比較容易不相容的feature都做了相當夠用的處理。最重要的是,這個函式庫的成熟度相當
高,可以放心的在商業級的專案中使用,這點跟一般opensource的函式庫有相當的不同。
接著我們看一些hibernate相關的設定:
設定檔案分成兩大類:主要設定檔、物件設定檔,前者定義和database相關的設定,後者則用來
定義物件和table的對應。主要設定檔 (hibernate.cfg.xml) 的寫法舉例如下:
============================================================================
org.hsqldb.jdbcDriver
jdbc:hsqldb:./defaultdb
sa
net.sf.hibernate.dialect.HSQLDialect
true
update
=============================================================================
一開始是一連串有關資料庫連線的設定,請特別注意 "dialect" 這個屬性,這裡我們將SQL指令
的種類設定成依照HyperSonicSQL的語法來動態產生SQL指令,在使用不同的database的時候,
這裡要做對應的修改。
則是指向設定物件的設定檔,如果有多個設定檔,
可以接在後面繼續寫。
接著我們來看物件設定檔的寫法:
=============================================================================
=============================================================================
首先,每各物件都要有id,這有點類似database的primary key,這裡我們使用
讓hibernate自動以遞增的方式來產生id,我們也可以用來自行填入id,
當然,id不能重複,所以筆者會建議採用第一種方式。
id之後就是JavaBean的屬性和table欄位的對應了,後面我們列出這個JavaBean本身,讓大家對照著看看:
=============================================================================
public class DataObject
{
private long key_1=-1;
private String id=null;
private String name=null;
public long getKey_1(){return this.key_1;}
public void setKey_1(long key_1){this.key_1=key_1;}
public String getId(){return this.id;}
public void setId(String id){this.id=id;}
public String getName(){return this.name;}
public void setName(String name){this.name=name;}
}
=============================================================================
編譯之後,不需要做任何額外的處理,只要把需要的函式庫和設定檔擺在classpath裡面,就大功告成了!!