Hibernate代码生成工具 设计全攻略
Hibernate是一個(gè)開(kāi)放源代碼的對(duì)象關(guān)系映射框架,它對(duì)JDBC進(jìn)行了輕量級(jí)的對(duì)象封裝,提供HQL查詢語(yǔ)言,使得Java程序員可以隨心所欲的使用對(duì)象編程思維來(lái)操縱數(shù)據(jù)庫(kù)。使用Hibernate,必須為配置映射文件—ClassMapping File和Configuration File,現(xiàn)在市場(chǎng)上提供了諸多Hibernate代碼生成工具,比如:XDoclet,以及Hibernate官方自帶的sechmaExport工具。然而它們都有如下的缺點(diǎn):僅提供一些基本的輸入模版,用戶仍需要時(shí)間進(jìn)行配置和修改;沒(méi)有提供自動(dòng)的持久類以及InvokeBean的代碼生成;不支持圖形界面;不支持對(duì)HibernateTestCase的代碼生成。
Hibernate工具具備以下特點(diǎn):
1. 根據(jù)UML生成的數(shù)據(jù)庫(kù)模型,自動(dòng)生成映射文件。
2. 根據(jù)UML產(chǎn)生Hibernate持久類。
3. Hibernate模型檢驗(yàn)。
4. 生成自動(dòng)測(cè)試代碼。
5. 與Eclipse集成
Hibernate代碼生成工具采用基于PowerDeigner的模型擴(kuò)展功能來(lái)實(shí)現(xiàn)Hibernate的代碼生成。 PowerDesigner(以下簡(jiǎn)稱PD)是一款一流的數(shù)據(jù)庫(kù)建模工具(E-R模型設(shè)計(jì)、物理模型設(shè)計(jì)),同時(shí)它對(duì)UML、報(bào)表、XML、團(tuán)隊(duì)開(kāi)發(fā)(知識(shí)庫(kù)Repository)都支持的相當(dāng)好,所有模型都可以正向、逆向的相互轉(zhuǎn)換。PD的模型是由它的元模型組成。簡(jiǎn)單的說(shuō),元模型就是組成模型的模型。基于這些元模型,PD提供了一套GTL開(kāi)發(fā)語(yǔ)言,可以輕易地?cái)U(kuò)展出自己的代碼模版和流程,也可以對(duì)現(xiàn)有的語(yǔ)言模型進(jìn)行修改以適應(yīng)需求;PD支持利用VBScript來(lái)擴(kuò)展語(yǔ)言、改變PD模型、模型檢測(cè)。對(duì)于Eclipse,PD也能做到快速的集成并可以利用JAVA語(yǔ)言來(lái)修改PD模型。
注:GTL可以說(shuō)是一種面向?qū)ο蟮哪_本語(yǔ)言,它可以在不同的元模型上加以擴(kuò)展,增加諸如:添加生成文件、原型、菜單、代碼模版、擴(kuò)展屬性等等功能,如圖1所示,將在后續(xù)部分詳細(xì)的闡述。由于元模型是面向?qū)ο蟮?#xff08;比如所有的類、接口等的元模型都繼承于Classifier元模型),即如果在Classifier中擴(kuò)展了一個(gè)功能,那么繼承它的模型均擁有這樣的功能和腳本,也可以覆蓋重寫(xiě)這樣的功能,以實(shí)現(xiàn)多態(tài)概念。
打開(kāi)擴(kuò)展模型編輯窗口:選擇Model?Extended Model Definition,在彈出的窗口的Toolbar上選擇Import Extended Model Definition(倒數(shù)第二個(gè)按鈕)來(lái)加載已有的模型,也可以新建擴(kuò)展模型(選擇Add Row按鈕,然后在表格中雙擊要編輯的模型的第一列即可彈出如圖1所示的界面)
為了讓讀者更好的了解PD的元模型概念,截取了Hibernate代碼生成工具所用到的元模型架構(gòu)圖,如圖2所示。 讀者可以在PD的安裝目錄下找到:<PD安裝路徑>\Examples\MetaModel.oom,圖表存放在PdOOM下,名字為Class Objects。
由于篇幅原因,會(huì)摘取典型的代碼和模型來(lái)講解如何設(shè)計(jì)Hibernate代碼生成工具。
Hibernate代碼生成的總體架構(gòu)流程(活動(dòng)圖)
Hibernate自動(dòng)生成文件的原則是:
1) 子類的映射信息掛在根類的映射文件下(Root Class),即子類將不獨(dú)立生成代碼
2) Value-Type類以及沒(méi)有持久化的類,將不生成代碼。
3) 不為非類對(duì)象生成代碼(比如接口等)
其中:
Check Models in Diagram: Hibernate模型檢測(cè),判斷DomainModel是否符合Hibernate語(yǔ)法。如果出錯(cuò),PD將拋出錯(cuò)誤提示信息(提供自動(dòng)糾錯(cuò)的功能)
Generate Configuration File:選擇模型屬性(Model->Model Properties),用戶可以在Extended Attribute下設(shè)置配置信息,PD會(huì)根據(jù)配置信息生成Configuration File。
Get each class in Diagram:這是PD的機(jī)制,它會(huì)自動(dòng)獲取UML內(nèi)的所有模型元素,并根據(jù)每個(gè)模型的擴(kuò)展屬性(Profile\Generated File)的流程來(lái)生成代碼文件。
Generate Basic Mapping:類的基本映射,它包含id,composite-id,propery等。
Get SubClass Style:子類的映射,遞歸獲取。
Generate Join:當(dāng)持久類對(duì)應(yīng)于多張表的映射時(shí),需要用Join來(lái)指明。
Generate Association Mapping:根據(jù)類之間Association的類型來(lái)判斷是哪種關(guān)連映射,本工具支持one-to-one,one-to-many,many-to-one,many-to-many(根據(jù)Association Properties的Detail標(biāo)簽下的Multiplicity來(lái)設(shè)置),支持集合Array,Set,List,bag,idbag(根據(jù)ContainType來(lái)設(shè)置)。
Get Java Code Information:擴(kuò)展模型是基于現(xiàn)有的語(yǔ)言模型,即擴(kuò)展模型能夠獲取語(yǔ)言模型的模版和各種設(shè)置,對(duì)于Hibernate的Java持久類,我們只須在Java代碼下增加對(duì)應(yīng)Attribute的Getter和Setter即可。%source%
Generate Invoke Bean: 生成Hibernate的CRUD函數(shù)。
Generate Test Case: Hibernate測(cè)試用例代碼,將生成的隨機(jī)數(shù)據(jù)來(lái)驗(yàn)證Hibernate的正確性。
Generate Log4J: 生成Log4J的配置文件
Generate ANT build.xml: 當(dāng)用戶在Generation Files下的Options中設(shè)置Ant為True,并配置了Ant的Lib的路徑,則Hibernate Tools會(huì)生成build.xml, 然后將會(huì)自動(dòng)運(yùn)行Ant來(lái)測(cè)試Hibernate, 生成結(jié)果將會(huì)被Log4J存入日志。
2.技術(shù)要點(diǎn)
O/R Mapping
PD從8.0開(kāi)始,就不斷加強(qiáng)O/R Mapping,除了代碼模型的生成以外,PD也生成O/R Mapping的定義,諸如生成EJB CMP組件。用戶可以定義O/R Mapping來(lái)建立OOM與PDM之間的關(guān)系。
PD支持3種方式的O/R Mapping:
第一種是從類圖轉(zhuǎn)換成數(shù)據(jù)模型之后由PD自動(dòng)建立連接(適用于自頂向下的設(shè)計(jì)過(guò)程);
第二種是從數(shù)據(jù)模型轉(zhuǎn)換成類圖之后由PD自動(dòng)建立連接(適用于自下向上的設(shè)計(jì)過(guò)程);
第三種是建立類圖和數(shù)據(jù)模型之后由用戶手動(dòng)建立(適用于同步設(shè)計(jì)或者是后期的修改)
建立過(guò)程:
第一種:選擇類圖,然后設(shè)計(jì)持久類(POJO),完畢之后,選擇Tools->Generate Physical Data Model。在彈出的窗口中,選擇Detail標(biāo)簽,選中O/R Mapping選項(xiàng),即可。讀者可以選擇是更新現(xiàn)有的數(shù)據(jù)庫(kù)還是新建數(shù)據(jù)庫(kù)。
第二種:與第一種建立過(guò)程相似,只是換成在數(shù)據(jù)庫(kù)模型中選擇Generate Object-Oriented Model
第三種:用戶必須首先建立DataSource,在左邊WorkSpace樹(shù)形目錄下找到類文件,然后右擊選擇New\Data Source,在彈出的窗口的Models標(biāo)簽中選擇 ,并選擇想與之關(guān)聯(lián)的數(shù)據(jù)庫(kù)模型。在類模型中打開(kāi)類屬性(雙擊要建立O/R Mapping的類),選擇Mapping選項(xiàng)卡,點(diǎn)擊 按鈕添加剛才建立的DataSource。然后點(diǎn)擊 添加類映射的數(shù)據(jù)表,即建立完畢。
用戶可以添加多張表,它表示一個(gè)類可能對(duì)應(yīng)多張表的映射,Hibernate的映射則應(yīng)該用Join屬性來(lái)指明。
注:當(dāng)用戶建立了ClassSource,PD會(huì)根據(jù)類的屬性和表的字段自動(dòng)建立AttributeMapping,當(dāng)然用戶也可以在AttributeMapping屬性頁(yè)下對(duì)其映射進(jìn)行修改。
大家知道,Hibernate的映射文件必須包含對(duì)表的表述(比如:column,property屬性等等),在PD中,通過(guò)元模型中的Mapping可以輕易地獲取對(duì)應(yīng)的表信息。圖4是GTL中用到的O/R Mapping元模型。
O/R Mapping架構(gòu)圖:
架構(gòu)說(shuō)明:
1) Association:
在Asoociation元模型中,可以通過(guò)Mappings來(lái)獲取AssociationMapping(即用戶在Mapping for下選擇的DataSource),每個(gè)AssociationMapping都會(huì)有SourceClassifiers,它是AsoociationSource標(biāo)簽內(nèi)的映射集合,如圖5所示。SourceClassifiers集合中的元素,也就是數(shù)據(jù)模型中的Reference元模型,如圖6所示。
由于PD可以在Association Mapping下添加數(shù)據(jù)模型中的其他Reference和Table,所以在做Hibernate代碼生成時(shí),采用了類型判斷,以避免因類型不匹配而造成的錯(cuò)誤。
?實(shí)現(xiàn)代碼(表映射):(注:附錄部分將介紹部分GTL語(yǔ)法)
.
?實(shí)現(xiàn)代碼(referenceColumnHelper模版):
2) Class和Attribute
獲取數(shù)據(jù)庫(kù)模型的方法與Association類似,在O/R Mapping中,ClassMapping的SourceFeature等價(jià)于數(shù)據(jù)表; AttributeMapping的SourceFeature等價(jià)于數(shù)據(jù)表中的列信息。圖7給出了在編寫(xiě)過(guò)程中使用到的數(shù)據(jù)庫(kù)元模型的架構(gòu)圖。
?實(shí)現(xiàn)代碼(獲取類對(duì)應(yīng)的表信息)
說(shuō)明:Mappings.First.ClassSources表明當(dāng)前Data Source下的表集合
?實(shí)現(xiàn)代碼(獲取Attribute對(duì)應(yīng)的列信息)
例如:%AttributeMappings.First.SourceFeature.Code%
%AttributeMappings.First.SourceFeature%對(duì)應(yīng)于圖7的Column元模型。
Extended Attribute
Hibernate生成工具中對(duì)于映射文件,難免要遇到大量的選項(xiàng)讓用戶選擇或者輸入,這時(shí),我們就可以利用PD提供的Extended Attribute來(lái)擴(kuò)展模型的屬性。對(duì)于UML模型,除了Dependency和Generalization,其余模型均有Extended Attribute來(lái)擴(kuò)展。
設(shè)置Extended Attribute步驟:進(jìn)入擴(kuò)展模型編輯窗口,在Profile下選擇一個(gè)元模型,然后右鍵選擇Extended Attribute, PD已提供了多種默認(rèn)的選項(xiàng)(加括號(hào)的),當(dāng)然用戶增加自己的Extended Attribute Type(在Profile下的shared目錄上按右鍵選擇Extended Attribute Type,然后在右邊可以設(shè)置列項(xiàng)內(nèi)容以及默認(rèn)值等等。設(shè)置完之后讀者就可以在模型的擴(kuò)展屬性中引用到自定義的類型),如圖8所示。在GTL中,可以用%屬性名%引用到當(dāng)前用戶的選擇值,也可以用%模版名%引用到GTL模版(讀者可以選擇模版并按F12跳轉(zhuǎn))。
Check Model
考慮,由于基于UML建立的DomainModel,對(duì)于Hibernate語(yǔ)法來(lái)說(shuō),難免有一些語(yǔ)法上的錯(cuò)誤,比如:在兩個(gè)類之間建立Association,但對(duì)應(yīng)的表之間卻沒(méi)有Reference,或者是有Reference卻沒(méi)有Joins下的Column,這時(shí)我們應(yīng)該給出一個(gè)錯(cuò)誤警告,提示用戶檢查。
以剛才提到的AssociationCheck為例,將介紹如何實(shí)現(xiàn)用戶自定義的Check。
打開(kāi)Hibernate擴(kuò)展模型,選中Profile\Association,右擊選中New\Custom Check。在右邊,讀者可以看到有四個(gè)選項(xiàng)卡,如圖9所示。
Check Script: 用于檢測(cè)模型,%Check%=true, 將不出現(xiàn)錯(cuò)誤信息。
Autofix Script: 用于自動(dòng)修復(fù)模型錯(cuò)誤,%Fix%=false, 表示不修復(fù)該錯(cuò)誤。當(dāng)PD監(jiān)測(cè)到錯(cuò)誤時(shí),用戶可以在錯(cuò)誤上右鍵選擇Automatic Correction即可。對(duì)于自動(dòng)修復(fù)的錯(cuò)誤,會(huì)在圖標(biāo)右下角加上一個(gè)”+”號(hào),如 ,表示PD以根據(jù)Autofix Script修復(fù)完成。
Global Script: 用于存放全局函數(shù),在任何元模型的Check Model均可調(diào)用。
實(shí)現(xiàn)代碼
Check Script: 用于檢測(cè)Refence的建立正確與否。
注:PD會(huì)對(duì)每個(gè)模型進(jìn)行檢測(cè)(包括Package),所以如果讀者希望通過(guò)程序來(lái)控制該模型是否被檢測(cè),只須在滿足條件的語(yǔ)法段內(nèi)加上%Check% = True (表示驗(yàn)證正確并跳過(guò))即可。
Persistent Class持久類
對(duì)于POJO的持久類,必須為其每個(gè)類的屬性增加Getter和Setter函數(shù)。擴(kuò)展模型是基于語(yǔ)言模型之上的,也就是說(shuō),語(yǔ)言模型中的模板等內(nèi)容均可在擴(kuò)展模型中覆蓋和重寫(xiě)。所以,在Hibernate擴(kuò)展模型中采用重載的方法,擴(kuò)展了Java語(yǔ)言模型的代碼生成,保留了原先Java那部分代碼,并在擴(kuò)展模型中加上自己的Getter和Setter模版。
在Java語(yǔ)言模型中,代碼生成是依靠%source%模版來(lái)完成Java代碼的,同時(shí)有一個(gè)%initializers%模版實(shí)現(xiàn)當(dāng)完成Attribute之后的一些初始化工作,所以在相同位置(Class元模型)的地方重寫(xiě)了%initializers%模版,代碼如下:
在Attribute元模型中增加getterFunction 、setterFunction模版,代碼如下:
然后在Class元模型中增加持久類的Generated Files,并在模版編輯框內(nèi)輸入%source%即可。
Generated Files
PD在每個(gè)元模型中提供了文件生成的功能。在Class元模型上右鍵選擇Generated Files。在右邊窗口中,在 File Name 下輸入生成后的文件名。由于Hibernate映射文件的文件名與類名相同,故輸入%mappingFilename%,同時(shí)建立mappingFilename 模版,并輸入%Code%.hbm.xml。
注:所有的元模型都繼承于NamedObject(NamedObject繼承于BaseObject),在NamedObject中存放了各種元模型的標(biāo)準(zhǔn)屬性,比如:模型名稱(Name)、代碼名稱(Code)、注釋、描述等等。所以,為了取到類的名稱,就在類元模型下輸入%Code%.hbm.xml,那么PD會(huì)根據(jù)代碼名稱為每個(gè)類建立相應(yīng)的文件(前提是該類可以被生成,即已持久化)。
Model
Model元模型中主要實(shí)現(xiàn)對(duì)Configuration Mapping的連接信息的配置,諸如,JDBC等。所用到的方法也就是Extended Attribute和Mapping代碼模版。由于篇幅原因,不一一列舉,讀者可以參考剛才所講,或者可以在PD安裝目錄下運(yùn)行pdvbs11.chm來(lái)獲取幫助。
Task
Task在代碼生成完畢之后被激活,然后PD會(huì)依次序執(zhí)行選中的任務(wù)。擴(kuò)展了Hibernate模型,增加了ANT的Lib路徑,生成的目錄名稱等等選項(xiàng)。在Generation\ Options下建立新的選項(xiàng)即可,類似于Extended Attribute。調(diào)用Options選項(xiàng)時(shí),輸入如下代碼:%GenOptions.選項(xiàng)名% 即可獲取。
對(duì)于Task,希望能夠借助ANT的build.xml配置進(jìn)行自動(dòng)測(cè)試。在PD中,JAVA語(yǔ)言模型已經(jīng)提供了ANT的build.xml的自動(dòng)生成并預(yù)留接口 (customExecuteTarget、customerProperties、customTaskDefs三個(gè)模版) ,目的為了能讓擴(kuò)展模型來(lái)重載,有興趣的讀者可以查看Java語(yǔ)言模型(Language?Edit Current Object Language,瀏覽Java::Profile\Model\Templates\Ant\antTemplate)。
建立Task:
在Generation\Tasks上右鍵,選擇New。輸入Task Name(就是真正執(zhí)行的顯示名),取名為Run Unit Test。在下面的表格中選擇已建立的Command,如果沒(méi)有建立,則可以在Commands上新建。
Run Unit Test Command代碼:
說(shuō)明:
.execute_command為宏命令,用于執(zhí)行外部的程序。
.execute_command '(' <cmd> [',' <args> [',' <mode>]] ')'
第一個(gè)參數(shù)為主命令,這里是CMD
第二個(gè)參數(shù)為主命令的參數(shù),這里是/K ANT.BAT JUNIT
第二個(gè)參數(shù)為管道類型,PD提供cmd_ShellExecute和cmd_PipeOutput兩種方式。前者采用獨(dú)立的進(jìn)程方式,后者將會(huì)阻塞PD直到任務(wù)完成,并且結(jié)果將顯示在PD的Output窗口內(nèi),如圖10所示。
3.結(jié)束語(yǔ)
PowerDesigner是一款靈活性非常強(qiáng)的軟件建模工具,基于它的元模型,讀者可以隨心所欲的用不同語(yǔ)言 (GTL, VBScript, Java, C#等) 來(lái)設(shè)計(jì)出自己的代碼生成工具,甚至是語(yǔ)言模型、報(bào)表等等。本篇僅僅起到了一個(gè)拋磚引玉的作用,我相信,憑借著領(lǐng)域中的經(jīng)驗(yàn),讀者一定也可以設(shè)計(jì)出更適合自己的代碼生成工具,簡(jiǎn)化流程、降低成本、加快開(kāi)發(fā)。
附錄:
列舉了GTL的部分語(yǔ)法,讀者也可以參閱PD安裝目錄下的pdvbs11.chm文件或者Sybase官方網(wǎng)站。
1. 資源文件
讀者可以參考PD11的現(xiàn)有模型:
您可以在安裝目錄下\ Resource Files\Extended Model Definitions找到現(xiàn)有的擴(kuò)展模型;在安裝目錄下\ VB Scripts找到VBScript代碼;Ole Automation目錄下找到如何用JAVA,C#等其他語(yǔ)言來(lái)獲取元模型來(lái)做自己的代碼生成工具;Library目錄下找到語(yǔ)言模型。在Printable Docs目錄下找到PDF文檔(建議參考Advanced User Documentation.PDF文檔)。
2. 語(yǔ)法
a. 設(shè)置變量
變量名必須用%來(lái)封裝,即%變量名%
全局變量
變量區(qū)域
簡(jiǎn)單的說(shuō),當(dāng)區(qū)域建立后(比如,循環(huán),另一個(gè)模版等),在區(qū)域中調(diào)用區(qū)域外的變量,則需要用Outer.變量名來(lái)指明。
b. 循環(huán)
c. 判斷條件
d. 集合
e. 特殊符號(hào)
總結(jié)
以上是生活随笔為你收集整理的Hibernate代码生成工具 设计全攻略的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: window 下内存泄漏检测
- 下一篇: SpringMVC +Hibernate