在Eclipse中使用Hibernate

作者: James Elliott

譯者:qiaoyu
原文地址: http://www.onjava.com/pub/a/onjava/2005/01/05/hibernate.html
中文地址:http://www.matrix.org.cn/resource/article/43/43907_在Eclipse_Hibernate.html
關鍵詞: Eclipse Hibernate

編者注:我們的調查結果顯示Hibernate引起了廣泛興趣,因此我們決定這周再來談談這個話題。這次由O'Reilly出版的Hibernate一書的作者來介紹如何在Eclipse中使用Hibernate. Eclipse在這次調查中也得到了很高的票數。

譯者注:翻譯中的一些處理:涉及Eclipse時,提供了中英文兩種表述,如新建(New),對于涉及Hibernate Synchronizer的英文都沒有翻譯,以和實際軟件中的條目保持一致。

介紹
最近我開始使用Eclipse作為我的開發環境,部分原因是因為在我進行開發的許多平臺上都可以使用Eclipse來工作,還有部分原因是因為Eclipse是展示人人皆可作出貢獻的開放、可擴展環境的優勢的一個極好的例子。我開始研究其他人提供的對Eclipse的擴展。例如,當用到xml文件時,我使用XMLBuddy插件。該插件對于我的工作很有助益。因為最近一直在寫Developer's Notebook,所以我很想知道是不是已經有人寫了關于Hibernate的插件,事實上,有好幾個這樣的插件正在開發。在這篇文章中,我們將探索其中之一:Hibernate Synchronizer.

Hibernate Synchronizer
在我找的和Hibernate有關的插件中,Hibernate Synchronizer最令我感興趣,因為它為我在Developer's Notebook書中采用的以映射為中心的工作流(mapping-centric workflow)提供了最好的支持。(可以用多種方法使用Hibernate,你可能會試試其它一些插件,它們提供的方法可能正是你自己特定環境所要求的)。事實上,當使用Hibernate Synchronizer時,如果你改變了映射文件,你不需要為更新相應的java文件而勞心費神。當你編輯映射文件時,和Eclipse采取的方法類似,該插件自動更新你的java代碼。還不止于此,還提供了比Hibernate內建的代碼生成工具更多的功能:它為每個映射對象創建一對類( a pair of classes),其中一個是基礎類,當你改變映射內容時,它可以隨意重寫這個類;另一個類作為該基礎類的子類,在子類中,你可以添加具體的商業邏輯和另一些代碼。使用這個插件生成java代碼時,不用象使用Hibernate內置的代碼生成工具那樣,擔心其它代碼(如商業邏輯的代碼)會在你的眼皮底下消失。

對于以Hibernate影射文檔為基礎的方法,還有一些其它的好處,Hibernate Synchronizer有一個新編輯器,當編輯這類文件時,為Eclipse添加了智能輔助和自動完成功能。一個比較好的、以DTD驅動的XML編輯器,如以前提及的XMLBuddy,也可以完成部分功能。與此相比,Hibernate Synchronizer利用對影射文檔語義的了解,提供了更進一步的功能。例如,提供了對屬性和影射關系的可視化顯示,創建新元素的向導界面,象以上提及的一樣,缺省設置情況下,當你編輯影射文檔時,編輯器會自動生成數據訪問類(data-access class).

當然還有其它一些功能,在Eclipse的新建(New)菜單中,提供了一個向導,可以用來創建Hibernate配置文件和映射文件,在包資源瀏覽器(package explorer)和其它一些合適的地方增加了上下文菜單,方便調用和Hibernate相關的功能。

好了,在這些抽象的描述之后,到了開始做實事的時候,當然,這正是你興趣所在,不然你就不會讀這篇文章。怎么安裝和使用呢?下邊一一解釋。

安裝
Hibernate Synchronizer可以用Eclipse內置的更新管理器(Update Manager)來安裝。對Eclipse 2.1和即將發布的Eclipse 3的用戶提供了不同的更新站點。(因為用Eclipse作關鍵性的工作,我仍使用作為產品發行的2.1版。當我寫這篇文章的時候,Eclipse 3已經進入了“候選發布”階段。我希望當我今夏晚些時候從JavaOne回來時,我可以更新到版本3的產品發行版。提及這個的主要原因是因為我想強調一下,這些指南是以Eclipse 2的角度的來講解,毫無疑問,一些命令和窗口會在版本3中發生變化,因此,當你使用Eclipse 3時,你應當做一些相應的調整。我印象中Hibernate Synchronizer自己的install instructions是針對Eclipse 3,也許這對你有所幫助。

啟動Eclipse,順次單擊幫助(Help) ->軟件更新(Software Updates) -> 更新管理器(Update Manager)來打開更新管理器,當安裝/更新(Install/Update)透視圖打開之后,在功能更新視圖(Feature Updates)中用右鍵單擊(如果你用的單鍵,你需要control-click)。選擇新建(New) -> 站點書簽(Site Bookmark),如圖1中所示。

?????
圖 1 在更新管理器中添加Hibernate Synchronizer插件的更新地址

在彈出對話框中,輸入適合你的Eclipse版本的插件地址:
·Eclipse 2.1: http://www.binamics.com/hibernatesync/eclipse2.1
·Eclipse 3: http://www.binamics.com/hibernatesync

還需要為新建的書簽命名,"Hibernate Synchronizer"就是個很貼切的名字。圖2中顯示的是在Eclipse 2.1.2中填完所有需要的信息后的對話框。填完之后,你可單擊完成(Finish)按鈕來完成增加書簽。

?????
圖 2. Hibernate Synchronizer插件更新站點書簽

單擊完成(Finish)后,新建的書簽就會出現在功能更新(Feature Updates) 視圖中,如圖3中所示.

?????
圖 3. Hibernate Synchronizer站點已經可以使用

為了實際安裝該插件,單擊該書簽左邊的三角形符號,然后再次單擊在書簽下邊出現的條目左邊的三角形符號,繼續這個過程,一直到書簽下邊出現的條目中出現該插件的圖標。單擊該條目,就會出現一個可以讓你安裝的界面,如圖4所示。

image
圖 4. 準備開始安裝插件

單擊Install Now,讓Eclipse引導你完成安裝(如圖5-10).

?????
圖 5. 安裝Hibernate Synchronizer


?????
圖 6. 許可協議

你可以看看下邊Trade-Offs部分對許可協議的一些討論。當你打算在實際的項目中使用該插件時,想必你會仔細研究該協議。我認為也許好一點,不過該插件基于GPL協議,而不是開放源代碼,令人迷惑。

?????
圖 7. 選擇安裝位置,缺省的已經很好了

?????
圖 8. 安裝沒有簽名插件時的標準警告

?????
圖 9 正在進行安裝

image
圖 10. 完成安裝

現在已經完成安裝,你需要退出,然后重新啟動Eclipse以使所做的更改生效。看上邊的對話框好像說能夠自動重新啟動Eclipse。,以我的經驗,Eclipse只會退出,還是需要你自己手工重新啟動。這可能是Max OS X平臺上Eclipse 2.1的一個局限。Eclipse 3已經許諾把對OS X的支持列入第一級別。無論如何,這只是個小問題。如果你需要重新啟動Eclipse,現在就可以這樣做。安裝完之后,接著需要對其對其進行配置,以便在項目中使用。

配置
重新啟動Eclipse后,關閉安裝/更新透視圖。打開一個使用Hibernate的Java工程.如果你已經完成了Developer's Notebook,一書中的例子,那么就有幾個目錄可供你選擇,這里以書中第三章中的例子來說明。第三章是可以在線免費獲得的樣章,你還可以從該書的站點下載所有例子的源代碼。

如果你打算使用其中的一個例子來新建一個Eclipse工程,選擇文件(File) ->新建( New )-> 工程(Project),選定工程類型,然后單擊下一步(Next),填入該工程名(我填的是"Hibernate Ch3",如圖11所示),不要復選使用缺省檢查框(Use default),這樣你可以告訴Eclipse從哪里找到已經存在的工程目錄,單擊瀏覽按鈕(Browse)來定位目錄。選定工程目錄后可以單擊完成(Finish)來創建工程。不過,一般情況下我喜歡單擊下一步(Next)來復查Eclipse為此工程所作的設置(當然,如果發現有些配置不對,總是可以選擇回退來修改這些設置。不過,我總是發現,如果有一個庫文件丟失或是其它一些原因,會有非常多的錯誤和警告信息)。

?????
圖 11. 創建一個需要使用Hibernate的新工程

在當前情況下,我的謹慎有點多余。Eclipse準確的算出了目錄是如何組織以及是用來干什么的,找到我為使用Hibernate和 HSQLDB 數據庫而下載的第三方庫(下載和安裝的詳細過程可以參看書中第一章)。如此聰明的適應能力是Eclipse優點之一。圖12顯示新工程已經打開,準備好可以用來做實驗。從這個圖中也可以推斷Eclipse不喜歡調整窗口大小使其小到形成合適的屏幕布局。從現在開始,顯示的屏幕截圖只顯示窗口的一部分,而不是完整的窗口。

image
圖 12. 使用Chapter 3例子的工程

下一個需要做的工作是創建一個Hibernate配置文件,提供給Hibernate Synchronizer使用。在src目錄中已經有了一個hibernate.properties文件,這是書中例子使用的配置。這里有個問題,壞消息是Hibernate Synchronizer只能使用XML樣式的Hibernate配置文件。這樣,就需要把hibernate.properties中的內容移植到XML樣式的配置文件hibernate.cfg.xml中。好消息是,這正是Hibernate Synchronizer創建配置文件向導第一次大顯身手的時候。選擇文件(File) ->新建(New) -> 其它(Other),然后在彈出對話框選取剛可用的Hibernate類,選取 Hibernate Configuration File,然后單擊下一步(Next).

?????
圖13 打開Hibernate配置文件向導

打開向導時,保存文件的位置和在Eclipse中現在選擇的文件有關。請確保把該文件保存在src 目錄中。添加其余一些向導需要的信息,這些信息應該和配置文件的版本相一致,如圖14中所示。值得注意的是,和用Ant來控制Hibernate的運行(書中使用就是這種方法)不同,這里你無法控制Hibernate運行時的當前工作目錄,因此你需要在URL文件中使用路徑的全稱。我自己的添加的URL值(有點難看)為
jdbc:hsqldb:/Users/jim/Documents/Work/OReilly/Hibernate/Examples/ch03/data/music.

(如果有人知道怎么讓Eclipse或是Hibernate Synchronizer使用一個工程特定的目錄,你可以告訴我,我很想知道。因為我才開始使用Eclipse,是個新手。如果有人告訴我這是可能的,只是因為我不知道怎么做而已,我一點也不會感到吃驚)

?????
圖14 添加配置文件信息

添加Driver Class 的方法有點奇怪,你需要單擊Browse按鈕,然后開始輸入driver的類名(譯者注:你需要確定該driver類在該工程的類路徑中)。如果你輸入"jdbcD",窗口就會出現這個選擇,很容易就可以從中選取一個。具體如圖15所示。

?????
圖15 指定HSQLDB的driver類

只要添加如圖14中那些屬性值就可以。完成后單擊Finish來完成創建配置文件。Hibernate Synchronizer 現在已經可以開始使用了。完成創建文件后,配置文件會打開,這時候你就可以看看Hibernate XML格式的配置文件的結構和細節。

image
圖16 生成的配置文件

要想測試配置文件是否可用,有一個又快又簡單的方法:使用向導來創建一個影射文件。選擇文件(File) -> 新建(New) -> 其它(Other),選取Hibernate類別,然后再選Hibernate 影射文件,單擊下一步(Next)。向導出現的時候,其中有些屬性已經自動填入了在配置文件中相應屬性的值,單擊Refresh(確保可以通過這些信息和你的數據庫相連)。和數據庫連接后,會顯示庫中的表,這里只有一個TRACK表。第一次使用的時候,不知什么原因,需要你指定包含HSQLDB驅動的.jar文件的路徑。好在你只需要指定一次。只要你認為工作正常(譯者注:顯示了數據庫中有權限訪問的表),單擊Cancel。試驗中使用已有的影射文件,不需要實際創建一個。

生成代碼
這可能是你一直在等待的部分。我們能用這個插件來做什么?好,馬上就開始。為Hibernate影射文檔提供一個新的菜單條目。

右擊(如果是單鍵鼠標,在按住Control鍵的同時點鼠標鍵)一個影射文檔,菜單條目中會顯示幾個和Hibernate相關的選擇(如圖17所示),其中有一個和synchronize有關,這是一個手工方法,可以讓Hibernate Synchronizer產生和該影射文檔相對應的數據訪問對象。

image
圖17 Synchronizer插件為影射文檔提供的幾個菜單項

Add Mapping Reference 選項也很有用,當你單擊該項時,會把相應的影射文件增加到Hibernate配置文件中,表明該文件是影射文檔,因此你不需要在源代碼中增加任何信息要求相應的影射文件進行設置。現在讓我們看看選取Synchronize Files后的結果。

事情開始變得有趣,出現了兩個子包,一個是“base”的DAO,Hibernate Synchronizer所有,可以在任何時候重寫,一個是繼承那些DAO類的商業對象,不會被覆蓋,也就給了我們一個機會,可以在其中加入商業邏輯(具體如圖18中所示)。

image
圖18 同步后的DAO,圖中顯示的是我們可以編輯的子類

  和Hibernate的代碼生成工具相比,用該插件生成了更多的類。這是優點,也可能是一些潛在的缺點,將在Trade-Offs 部分進行討論。你可以在工程配置文件中選取要生成的類和它們所在的包的結構。我可以證明這點,但現在的發行版有個bug ,,無法訪問Mac OS X上的配置界面。針對該bug的一個補丁已經做好了,但仍沒有發布。

基于Hibernate Synchronizer網頁上的例子,和以下這個類一起,用那些新的數據訪問對象來試著把一些數據放入數據庫中。看起來和標準的Hibernate代碼生成工具生成的版本(在Hibernate: A Developer's Notebook一書的39-40頁)很相似,甚至更簡單一些。因為Hibernate Synchronizer生成的類為你的每個數據庫操作都創建和提交一個新事務,因此在與此類似的簡單情況下,你不需要自己來設置事務(當然,如果你需要把一組操作作為一個單獨事務,有很多方法可以做到這點)這里是新版本的代碼。

package com.oreilly.hh;

import java.sql.Time;
import java.util.Date;
import net.sf.hibernate.HibernateException;
import com.oreilly.hh.dao.TrackDAO;
import com.oreilly.hh.dao._RootDAO;

/**
* Try creating some data using the Hibernate Synchronizer approach.
*/
public class CreateTest2 {

    public static void main(String[] args) throws HibernateException {
        // Load the configuration file
        _RootDAO.initialize();
        
        // Create some sample data
        TrackDAO dao = new TrackDAO();
        Track track = new Track("Russian Trance", "vol2/album610/track02.mp3",
            Time.valueOf("00:03:30"), new Date(), (short)0);
        dao.save(track);
        
        track = new Track("Video Killed the Radio Star",
            "vol2/album611/track12.mp3", Time.valueOf("00:03:49"), new Date(),
            (short)0);
        dao.save(track);
        
        // We don't even need a track variable, of course:
        dao.save(new Track("Gravity's Angel", "/vol2/album175/track03.mp3",
            Time.valueOf("00:06:06"), new Date(), (short)0));
    }
}


當我寫這個的時候,有Eclipse在手邊真是太好了 ,我已經忘了當寫書中例子的時候多么想念智能代碼完成功能,有另外幾件事情JDT也發揮了作用。

  為了在Eclipse中運行這個簡單的程序,需要設置一個新的運行配置。用CreateTest2.java作為當前文件,選擇運行(Run )-> 運行...(Run...)。然后單擊新建(New),因為該類有一個main() 方法,Eclipse推斷出要運行該工程的當前類。Eclipse為新的運行配置取的名字,CreateTest2,很合適。屏幕窗口看起來如圖19中所示,單擊運行來在數據庫中創建一些數據。

image
圖19 準備在Eclipse中運行創建數據的測試程序

如果你確實按照上邊說的來做,你會發現第一次的嘗試運行失敗。Hibernate抱怨配置文件中連一個映射文件都沒有參考,為了運行程序,至少需要一個這樣的文件。這也是為什么XMLBuddy在圖16底部用黃色下劃線發出警告。可以很容易修改該錯誤,你只要在包資源瀏覽器(Package Explorer)中的Track.hbm.xml這個影射文檔上單擊右鍵,在Hibernate Synchronizer子菜單中選取Add Mapping Reference(如圖17中所示),這樣XMLBuddy就不會再抱怨XML文件有錯誤,程序也可以繼續向前。不幸的是,沒有向前推進我們所愿的那樣遠,下一個問題又出來了。Eclipse中顯示的下一個錯誤是“不能在JNDI中找到JTA UserTransaction initial context”。不止我一個人犯這種錯誤,因為在a forum thread中有這樣的討論,而且到目前為止仍然沒有找到一個解決方法。

既然我知道不需要使用JTA,我倒是很想知道為什么Hibernate竟然會使用JTA?打開Hibernate配置文件,如圖16所示,看看是不是Hibernate Synchronizer在其中加入了可疑的內容。看了配置文件后,可以確定,有一些行看起來是罪魁禍首:
 <property name="hibernate.transaction.factory_class"> 
       net.sf.hibernate.transaction.JTATransactionFactory
</property>
<property name="jta.UserTransaction">
       java:comp/UserTransaction
</property>


一旦把那些行變成注釋后,再次運行程序。這次,也就是第三次運行成功。我在自己計算機上運行沒有一點錯誤,數據已經保存到數據庫中。運行 ant db 這個target(在Developer's Notebook一書的第一章有相應的解釋)可以把表中所有的數據顯示出來(不可否認,這也許有點簡單),如圖20中所示。如果你跟著這篇文章中順序來做的,而不是跟著書中步驟一步一步來的,你需要先運行ant schema來創建數據庫中的表,或是刪除以前試驗留下的數據。

image
圖20 在Eclipse中運行Ant

你可以在Eclipse內運行Ant的target,方法是用右鍵單擊包資源瀏覽器(Package Explorer)中的build.xml 文件,選擇菜單中的運行Ant(Run Ant),然后在彈出對話框中選擇你要運行的target,如圖21所示。這個功能很cool。

image
圖21 在Eclipse中運行Ant

查詢數據相當簡單、直白,即使Hibernate Synchronizer產生了很多輔助方法來使用指定查詢,我認為這些沒有什么用處,都是運行查詢,然后返回包含結果的列表,而不是返回一個Query對象,讓你直接使用該對象。這使你不能使用任何Query提供的、方便的、類型安全(type-safe)的參數設置方法,因為這個,我打算讓_RootDAO對象提供一個Session對象,可以用“老式”的方法來使用Hibernate。公平來說,我認為如果編輯Hibernate Synchronizer 用來生成代碼所使用的模板,就可以生成想要的任何方法,如果有一個項目,要用到該插件,可以肯定我會試著這么做。

實際上,進一步考慮,當你得到一個活動的Session時,你只能使用Query,而這些DAO對象已經提供為相應功能最佳的實現。如果你和我在例子中使用查詢的方法一樣,那就需要你自己來實現session管理。你能夠把session管理內嵌于你自己所寫的那一半DAO中,這樣可以給你提供兩方面的好處。(譯者注:和有base的java POJO對象一樣,對于DAO,該插件也生成一對類,一個base DAO給該插件用,一個是繼承該base DAO的自定義DAO,你可以在其中添加商業邏輯)。這也是Hibernate Synchronizer把類分隔開來如此有用的另一個原因。對該插件的遠見在下邊做了一點研究

不管怎么說,下邊是我第一次使用的代碼,和書中48-49頁上的代碼功能基本一致:
package com.oreilly.hh;

import java.sql.Time;
import java.util.ListIterator;

import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Query;
import net.sf.hibernate.Session;

import com.oreilly.hh.dao.TrackDAO;
import com.oreilly.hh.dao._RootDAO;

/**
* Use Hibernate Synchronizer's DAOs to run a query
*/
public class QueryTest3 {

    public static void main(String[] args) throws HibernateException {
        // Load the configuration file and get a session
        _RootDAO.initialize();
        Session session = _RootDAO.createSession();

        try {
            // Print the tracks that will fit in five minutes
            Query query = session.getNamedQuery(
                TrackDAO.QUERY_COM_OREILLY_HH_TRACKS_NO_LONGER_THAN);
            query.setTime("length", Time.valueOf("00:05:00"));
            for (ListIterator iter = query.list().listIterator() ;
                 iter.hasNext() ; ) {
                Track aTrack = (Track)iter.next();
                System.out.println("Track: \"" + aTrack.getTitle() +
                                   "\", " + aTrack.getPlayTime());
            }
        } finally {
            // No matter what, close the session
            session.close();
        }
    }
}


TrackDAO為我們提供了一個很好的功能:靜態常數,使用這個功能,可以用來進行指定查詢(named query),這就消除了由于輸入問題而導致運行時錯誤的任何機會。我欣賞這個功能。為該測試類設定運行配置,然后運行,輸出結果正和我想的一樣,如圖22所示。

image
圖22 Eclipse控制臺窗口顯示的查詢結果

如上所述,這個類運行后,借助于Hibernate Synchronizer提供的模型,我想到有一個更好的方法可以實現這個功能。把查詢放到TrackDAO中去,這里才是查詢方法真正屬于的地方,指定查詢(named query)是和該DAO關聯的映射文件的一個功能。
package com.oreilly.hh.dao;

import java.sql.Time;
import java.util.List;

import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Query;
import net.sf.hibernate.Session;

import com.oreilly.hh.base.BaseTrackDAO;

/**
* This class has been automatically generated by Hibernate Synchronizer.
* For more information or documentation, visit The Hibernate Synchronizer page
* at http://www.binamics.com/hibernatesync or contact Joe Hudson at joe@binamics.com.
*
* This is the object class that relates to the TRACK table.
* Any customizations belong here.
*/
public class TrackDAO extends BaseTrackDAO {

    // Return the tracks that fit within a particular length of time
    public static List getTracksNoLongerThan(Time time)
        throws HibernateException
    {
        Session session = _RootDAO.createSession();
        try {
            // Print the tracks that will fit in five minutes
            Query query = session.getNamedQuery(
                QUERY_COM_OREILLY_HH_TRACKS_NO_LONGER_THAN);
            query.setTime("length", time);
            return query.list();
        } finally {
            // No matter what, close the session
            session.close();
        }
    }
}


以上代碼,看起來更好(nice)、更為清晰(clean),QueryTest3中的main()方法更是得到了大大簡化
    public static void main(String[] args) throws HibernateException {
        // Load the configuration file and get a session
        _RootDAO.initialize();

        // Print the tracks that fit in five minutes
        List tracks = TrackDAO.getTracksNoLongerThan(Time.valueOf("00:05:00"));
        for (ListIterator iter = tracks.listIterator() ;
             iter.hasNext() ; ) {
            Track aTrack = (Track)iter.next();
            System.out.println("Track: \"" + aTrack.getTitle() +
                               "\", " + aTrack.getPlayTime());
        }
    }


很清楚,這是在Hibernate Synchronizer中用到指定查詢(named query)時所應采取的方法。很快測試一下就可以證實以上的代碼輸出同樣的結果,而且這里的代碼更好。

編輯映射文件
Hibernate Synchronizer一個主要 引人之處是為映射文件提供的有專業水平的編輯器,你可以配置該編輯器,這樣當你保存文件的時候,可以自動重新生成相應的數據對象,.這只是你最后才會用到的功能。即使不使用該插件的代碼生成器,可能你還是會用這個編輯器。當你編輯影射文檔時,它可以為映射文檔中的元素提供智能完成功能,還有一個你可以操作的映射文檔的大綱視圖。

如果你從Developer's Notebook下載的源代碼,然后想用該插件的映射文檔編輯器來編輯該文件,需要耍一個小花招。在下載文件中,影射文檔的擴展名是".hbm.xml",而該插件僅僅對以"hbm"為擴展名的文件才調用影射文檔編輯器。理論上,你可以在Eclipse中配置擴展名映射,以便兩個擴展名都可以用該插件的編輯器,不過,我沒有成功過,我在支持論壇上看到別人有同樣的問題。因此,暫時來看,最好的辦法就是重命名文件(如果用Ant來生成代碼,確保修改build.xml文件的codegen這個target,使其也使用新擴展名)。

當我把Track.hbm.xml改名為Track.hbm時,包資源瀏覽器中該文件的圖標更新為象Hibernate的logo。該文件的默認編輯器變為該插件的影射文檔編輯器,如圖23中所示。不知道什么原因,對這兩個擴展名的文件,其它的Hibernate Synchronizer選項都可用,令人奇怪的是,只有“hbm”結尾的文件可以用其編輯器。

image
圖23 Hibernate影射文檔(擴展名為".hbm")的上下文菜單

編輯器對于你要在影射文檔中增加的所有元素提供了上下文敏感的自動完成功能,圖24舉了兩個例子。雖然如此,沒有一個屏幕抓圖能夠真正顯示如此功能的細節和有用之處。我鼓勵你自己安裝該插件,然后自己來試試這個編輯器.你很快就會發現當使用影射文檔的時候,這個編輯器是多么有幫助。

image
image
圖24,25 影射文檔編輯器中的自動完成功能

大綱視圖,象圖26中所示,可以用圖形的方式顯示類的結構,被影射的元素,指定查詢和其它一些出現在影射文檔中內容,同時也提供了幾個向導,幫助你創建新項

image
image
圖26,27 影射編輯器的大綱視圖以及“Add property”向導

編輯器內的上下文菜單中有一項是Format Source Code,你可以用來對文檔進行清潔和改變文檔結構。編輯器內也有很多靈巧和有用的功能,看看它如何“成長”是一件有趣的事情。對我來說,唯一的不滿是當你完成XML屬性的時候,該編輯器用非常不同于JDT在java代碼中使用的方法來幫助你管理引號,在它們之間切換有時令人迷失(JDT采用的方法可能只適于它自己,但一旦你信任它,這個方法看起來就有點魔力)

產生數據庫中的表
和我的第一印象-一切都可以通過影射文檔得到-不同,Hibernate Synchronizer現在沒有為創建或更新數據庫提供任何支持。支持論壇上已經張貼了一個這樣的功能要求,如果我們將來看到這些功能,我不會感到驚奇。這種功能應該不是很難。暫時,你不得不采用其他方法,如果你想從影射文檔生成數據庫,你可以象Hibernate: A Developer's Notebook 一書中使用Ant一樣來做到。下邊描述的Hibernator插件支持在Eclipse中更新數據庫。或許,我應該研究一下是否能夠同時安裝這兩個插件。

好了,我當然希望這個簡單介紹的指南能夠讓你對這個插件的功能有一個大致的了解,當然,我沒有提及它的所有功能。如果文中有些內容激起了你的興趣,那就下載,安裝,自己試試。

Trade-Offs
很清楚,你可以用Hibernate Synchronizer來做靈巧的事情。我會在我自己的Hibernate項目中使用該插件嗎?這個想法有其它一些優缺點需要考慮,可能現在還不是做決定的時候,直到需要用Hibernate來取代自家釀(當然非常簡單)的、已經在工作的輕量級O/R工具時才能做出決定。這是個足夠重要的改變,我們一直推遲做出決定,直到有其它原因出現。下邊的因素在我的決定中占有重要分量。

在安裝部分已經提及,有幾個涉及到許可證的問題,該插件的論壇對這個也有些討論。現在所采用的許可證是作了適合自己的修改后的GNU GPL,刪除了關于源代碼共享的規定,保留了"copyleft"保護的其它方面。關于這個的合法性有些問題,作者正在找另外一個可用來替代的許可證。它的確切意圖是保護該插件,不妨礙使用該插件生成代碼的其它一些項目。不過還是值得仔細讀一下現在的許可證,看看你是否相信該許可證已經達到其本來意圖。否則,對你來說,會有很多風險

同樣的討論顯示,作者本來想把該插件作為開源軟件,但臨時改變了主意,因為他覺得該插件還沒有“琢磨”到足夠給其他人以作為一個優秀的開源軟件的程度。此后,他通過電子郵件和一些性急的人進行了交流,這些人的電子郵件非常討厭,最終使他沒有興趣再分享整個源代碼,真是令人感到悲哀。當然,和我們分享什么是他的權力。對于世界來說,這個插件是個禮物,作者不欠我們什么。但我希望其它用戶的積極影響或許可以幫助說服他重新實行原來的計劃-分享源代碼。我真正重視可以得到源代碼的工具,不僅是因為這是個很好的學習機會,而且意味著有了源代碼,如果有需要,我(或其他人)可以馬上修改出現的一些小問題。到目前為止,該插件的作者一直非常積極的回應用戶的問題,但是沒有人能夠一個人做的象一個團隊一樣好,我們有些時候很忙,筋疲力盡,或是心情煩亂

Hibernate Synchronizer用它自己的模版和一套機制來生成你的數據訪問類,這個事情有好的一面,也有壞的一面。好的一面在于它為你提供了比標準的Hibernate代碼生成工具更多的功能。在自動產生的你所定義的數據對象的子類中嵌入商業邏輯,而不用害怕重新生成代碼的時候有關商業邏輯的代碼被覆蓋,這是一個很大的額外好處。該插件生成的、使許多簡單的類更簡單的類提供了其它一些優秀的功能。

另一方面,這并不意味著當這個平臺添加新功能或是有其它一些變化的時候,Hibernate Synchronizer生成的代碼會滯后。這個插件的代碼也很有可能在支持Hibernate很少用到的方式方面存在一些bug,因為使用該插件的用戶群很小,僅有一個人對其進行更新,你可以從論壇中看到這種現象的證據。

和許多事情一樣,由你決定是否潛在好處勝過風險。即使你沒有使用代碼生成器,或許你會發現影射文檔編輯器極端有用。如果你只是使用編輯器的自動完成和協助功能,你可以關閉automatic synchronization。

如果你真的采用了這個插件,而且發現它很有用,毫無疑問,我鼓勵你和作者聯系,表達你的謝意,如果可能,可以考慮捐些錢以支持該插件繼續開發。

其它一些插件
在我搜尋插件的過程中,我發現了其它兩個插件,可以為在Eclipse中使用Hibernate提供支持(如果你知道其它一些插件,或是在將來的某一天偶遇其它的插件,我很有興趣了解這些插件)。也許將來我會寫一些關于這些插件的文章。

HiberClipse
HiberClipse看起來是另一個非常有用的工具,該插件采取的是數據庫驅動的工作流方法:你已經有了數據庫,想用該插件構造Hibernate映射文件和Java類文件。這種事很常見,如果你面對這樣的任務,我肯定會推薦你使用該插件。該插件提供了一個很cool的功能 :在Eclipse中提供給你一個正在使用的數據庫的圖形化顯示的“關系視圖”(應該指出,當你從一個現存的數據庫開始工作時候,Hibernate Synchronizer也沒有使你處于孤立無援的境地,New Mapping File Wizard 可以連接數據庫,然后根據它找到的內容生成映射文件,如圖28所示)

image
圖28 Hibernate Synchronizer的創建映射文件向導

Hibernator
最后,Hibernator看起來向另一個方向傾斜,從你的Java代碼來產生簡單的Hibernate映射文檔,然后可以由此創建(或是更新)數據庫。另外,還提供了在Eclipse中進行數據庫查詢的能力。在這三個插件中,它處于開發的最早期,但是已經值得你時常關注,特別是該插件援引Hibernate開發小組的成員作為貢獻者。

了解更多
如果這篇文章激起了你的興趣,有很多資源可以讓你深入了解那些主題,除了文中所連接的站點以外,有一些也許你會感興趣。當然,包括我自己的書Hibernate: A Developer's Notebook。對于更有深度的參考資料,在線文檔非常有幫助,特別是其中的參考手冊,還有一本Hibernate開發人員自己寫的Hibernate in Action即將發行,我自己也很期待讀這本書。

對于Eclipse,我現在正在看Steve Holzner的Eclipse一書,正在盼望能夠閱讀本月末將發行的Eclipse Cookbook一書。如果你有好奇心(或是你自己正在邊緣蹣跚前行),你可以看看我的blog,在那里更詳細的討論了我向Eclipse的轉變。如果你只是剛開始使用Eclipse,請確保你研究過Eclipse自帶的工作臺和Java開發用戶指南(Workbench and Java Development user guides)的入門(Getting Started)部分。這些用戶指南講解了Eclipse應該怎么用,提供了一些好的建議,并且引領你使用你自己或許不能很快發現的過程和功能。可以選擇 幫助(Help) - > 幫助內容(Help Contents)找到該手冊。

資源:
·Eclipse討論區:http://www.matrix.org.cn/topic.shtml?forumId=25
·Hibernate討論區:http://www.matrix.org.cn/topic.shtml?forumId=23