Sybase 公司PowerDesigner上海研发中心汪晟杰
1.简述
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了轻量级的对象封装,提供HQL查询语言,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。使用Hibernate,必须为配置映射文件?ClassMapping File和Configuration File,现在市场上提供了诸多Hibernate代码生成工具,比如:XDoclet,以及Hibernate官方自带的sechmaExport工具。然而它们都有如下的缺点:仅提供一些基本的输入模版,用户仍需要时间进行配置和修改;没有提供自动的持久类以及InvokeBean的代码生成;不支持图形界面;不支持对HibernateTestCase的代码生成。
Hibernate工具具备以下特点:
?根据UML生成的数据库模型,自动生成映射文件。
?根据UML产生Hibernate持久类。
?Hibernate模型检验。
?生成自动测试代码。
?与Eclipse集成
Hibernate代码生成工具采用基于PowerDeigner的模型扩展功能来实现Hibernate的代码生成。 PowerDesigner(以下简称PD)是一款一流的数据库建模工具(E-R模型设计、物理模型设计),同时它对UML、报表、XML、团队开发(知识库Repository)都支持的相当好,所有模型都可以正向、逆向的相互转换。PD的模型是由它的元模型组成。简单的说,元模型就是组成模型的模型。基于这些元模型,PD提供了一套GTL开发语言,可以轻易地扩展出自己的代码模版和流程,也可以对现有的语言模型进行修改以适应需求;PD支持利用VBScript来扩展语言、改变PD模型、模型检测。对于Eclipse,PD也能做到快速的集成并可以利用JAVA语言来修改PD模型。
注:GTL可以说是一种面向对象的脚本语言,它可以在不同的元模型上加以扩展,增加诸如:添加生成文件、原型、菜单、代码模版、扩展属性等等功能,如图1所示,将在后续部分详细的阐述。由于元模型是面向对象的(比如所有的类、接口等的元模型都继承于Classifier元模型),即如果在Classifier中扩展了一个功能,那么继承它的模型均拥有这样的功能和脚本,也可以覆盖重写这样的功能,以实现多态概念。
打开扩展模型编辑窗口:选择ModelàExtended Model Definition,在弹出的窗口的Toolbar上选择Import Extended Model Definition(倒数第二个按钮)来加载已有的模型,也可以新建扩展模型(选择Add Row按钮,然后在表格中双击要编辑的模型的第一列即可弹出如图1所示的界面)
图1 Hibernate扩展模型编写界面
为了让读者更好的了解PD的元模型概念,截取了Hibernate代码生成工具所用到的元模型架构图,如图2所示。读者可以在PD的安装目录下找到:\Examples\MetaModel.oom,图表存放在PdOOM下,名字为Class Objects。
由于篇幅原因,会摘取典型的代码和模型来讲解如何设计Hibernate代码生成工具。
图2类图部分元模型架构
Hibernate代码生成的总体架构流程(活动图)
图3 HibernateTool总体架构流程
Hibernate自动生成文件的原则是:
?子类的映射信息挂在根类的映射文件下(Root Class),即子类将不独立生成代码
?Value-Type类以及没有持久化的类,将不生成代码。
?不为非类对象生成代码(比如接口等)
其中:
Check Models in Diagram: Hibernate模型检测,判断DomainModel是否符合Hibernate语法。如果出错,PD将抛出错误提示信息(提供自动纠错的功能)
Generate Configuration File:选择模型属性(Model->Model Properties),用户可以在Extended Attribute下设置配置信息,PD会根据配置信息生成Configuration File。
Get each class in Diagram:这是PD的机制,它会自动获取UML内的所有模型元素,并根据每个模型的扩展属性(Profile\Generated File)的流程来生成代码文件。
Generate Basic Mapping:类的基本映射,它包含id,composite-id,propery等。
Get SubClass Style:子类的映射,递归获取。
Generate Join:当持久类对应于多张表的映射时,需要用Join来指明。
Generate Association Mapping:根据类之间Association的类型来判断是哪种关连映射,本工具支持one-to-one,one-to-many,many-to-one,many-to-many(根据Association Properties的Detail标签下的Multiplicity来设置),支持集合Array,Set,List,bag,idbag(根据ContainType来设置)。
Get Java Code Information:扩展模型是基于现有的语言模型,即扩展模型能够获取语言模型的模版和各种设置,对于Hibernate的Java持久类,我们只须在Java代码下增加对应Attribute的Getter和Setter即可。%source%
Generate Invoke Bean:生成Hibernate的CRUD函数。
Generate Test Case: Hibernate测试用例代码,将生成的随机数据来验证Hibernate的正确性。
Generate Log4J:生成Log4J的配置文件
Generate ANT build.xml:当用户在Generation Files下的Options中设置Ant为True,并配置了Ant的Lib的路径,则Hibernate Tools会生成build.xml, 然后将会自动运行Ant来测试Hibernate, 生成结果将会被Log4J存入日志。
2.技术要点
O/R Mapping
PD从8.0开始,就不断加强O/R Mapping,除了代码模型的生成以外,PD也生成O/R Mapping的定义,诸如生成EJB CMP组件。用户可以定义O/R Mapping来建立OOM与PDM之间的关系。
PD支持3种方式的O/R Mapping:
第一种是从类图转换成数据模型之后由PD自动建立连接(适用于自顶向下的设计过程);
第二种是从数据模型转换成类图之后由PD自动建立连接(适用于自下向上的设计过程);
第三种是建立类图和数据模型之后由用户手动建立(适用于同步设计或者是后期的修改)
建立过程:
第一种:选择类图,然后设计持久类(POJO),完毕之后,选择Tools->Generate Physical Data Model。在弹出的窗口中,选择Detail标签,选中O/R Mapping选项,即可。读者可以选择是更新现有的数据库还是新建数据库。
第二种:与第一种建立过程相似,只是换成在数据库模型中选择Generate Object-Oriented Model
第三种:用户必须首先建立DataSource,在左边WorkSpace树形目录下找到类文件,然后右击选择New\Data Source,在弹出的窗口的Models标签中选择,并选择想与之关联的数据库模型。在类模型中打开类属性(双击要建立O/R Mapping的类),选择Mapping选项卡,点击按钮添加刚才建立的DataSource。然后点击添加类映射的数据表,即建立完毕。
用户可以添加多张表,它表示一个类可能对应多张表的映射,Hibernate的映射则应该用Join属性来指明。
注:当用户建立了ClassSource,PD会根据类的属性和表的字段自动建立AttributeMapping,当然用户也可以在AttributeMapping属性页下对其映射进行修改。
大家知道,Hibernate的映射文件必须包含对表的表述(比如:column,property属性等等),在PD中,通过元模型中的Mapping可以轻易地获取对应的表信息。图4是GTL中用到的O/R Mapping元模型。
O/R Mapping架构图:
图4 O/R Mapping元模型
架构说明:
?Association:
在Asoociation元模型中,可以通过Mappings来获取AssociationMapping(即用户在Mapping for下选择的DataSource),每个AssociationMapping都会有SourceClassifiers,它是AsoociationSource标签内的映射集合,如图5所示。SourceClassifiers集合中的元素,也就是数据模型中的Reference元模型,如图6所示。
由于PD可以在Association Mapping下添加数据模型中的其他Reference和Table,所以在做Hibernate代码生成时,采用了类型判断,以避免因类型不匹配而造成的错误。
图5 Association Mapping Properties
图6 Reference元模型
* 实现代码(表映射):(注:附录部分将介绍部分GTL语法)
.set_object(_reference,,new)?初始化变量
.foreach_item(Mappings.First.SourceClassifiers)?获取选中的DataSource下的所有集合
.if (%ObjectType% == "Reference")?判断对应于数据模型是否是Reference
.set_object(_reference,,)?赋值
.break?跳出循环
.endif
.next
.foreach_item(_reference.Joins,,,)
.if(%ChildTableColumn%==null)
<!---->
.else
.set_object(_column,%ChildTableColumn%,new)
%Outer.referenceColumnHelper(_column)%
?获取循环外部的%referenceColumnHelper%模版(_column为模版参数)
.endif
.next(\n)
.else
.foreach_item(_reference.Joins,,,%ParentTableColumn%)
.if(%ParentTableColumn%==null)
<!---->
.else
.set_object(_column,%ParentTableColumn%,new)
%Outer.referenceColumnHelper(_column)%
.endif
.next
|
* 实现代码(referenceColumnHelper模版):
.set_object(_column,%@1%,new)
?设置模版参数,%@1%、%@2%、... 该参数用来传递Column元模型对象。
<column font="" name="%_column.Code%"></column>
[ sql-type="%_column.DataType%"][ not-null="%.L:_column.Mandatory%"][ length="%_column.Length%"]/>?根据元模型的属性轻松获取
|
获取数据库模型的方法与Association类似,在O/R Mapping中,ClassMapping的SourceFeature等价于数据表; AttributeMapping的SourceFeature等价于数据表中的列信息。图7给出了在编写过程中使用到的数据库元模型的架构图。
* 实现代码(获取类对应的表信息)
.foreach_item(Mappings.First.ClassSources)
.//可以获取图6中的Table元模型的属性
.foreach_item(InReferences)
.// 可以获取图6中的Reference元模型的属性
.next
.next
|
说明:Mappings.First.ClassSources表明当前Data Source下的表集合
* 实现代码(获取Attribute对应的列信息)
例如:%AttributeMappings.First.SourceFeature.Code%
%AttributeMappings.First.SourceFeature%对应于图7的Column元模型。
图7常用的数据库元模型
Extended Attribute
Hibernate生成工具中对于映射文件,难免要遇到大量的选项让用户选择或者输入,这时,我们就可以利用PD提供的Extended Attribute来扩展模型的属性。对于UML模型,除了Dependency和Generalization,其余模型均有Extended Attribute来扩展。
设置Extended Attribute步骤:进入扩展模型编辑窗口,在Profile下选择一个元模型,然后右键选择Extended Attribute, PD已提供了多种默认的选项(加括号的),当然用户增加自己的Extended Attribute Type(在Profile下的shared目录上按右键选择Extended Attribute Type,然后在右边可以设置列项内容以及默认值等等。设置完之后读者就可以在模型的扩展属性中引用到自定义的类型),如图8所示。在GTL中,可以用%属性名%引用到当前用户的选择值,也可以用%模版名%引用到GTL模版(读者可以选择模版并按F12跳转)。
图8 Extended Attribute
Check Model
考虑,由于基于UML建立的DomainModel,对于Hibernate语法来说,难免有一些语法上的错误,比如:在两个类之间建立Association,但对应的表之间却没有Reference,或者是有Reference却没有Joins下的Column,这时我们应该给出一个错误警告,提示用户检查。
以刚才提到的AssociationCheck为例,将介绍如何实现用户自定义的Check。
打开Hibernate扩展模型,选中Profile\Association,右击选中New\Custom Check。在右边,读者可以看到有四个选项卡,如图9所示。
图9 Check Model
Check Script: 用于检测模型,%Check%=true, 将不出现错误信息。
Autofix Script:用于自动修复模型错误,%Fix%=false, 表示不修复该错误。当PD监测到错误时,用户可以在错误上右键选择Automatic Correction即可。对于自动修复的错误,会在图标右下角加上一个”+”号,如,表示PD以根据Autofix Script修复完成。
Global Script: 用于存放全局函数,在任何元模型的Check Model均可调用。
实现代码
Check Script:用于检测Refence的建立正确与否。
Function %Check%(obj)
%Check% = True
Dim source <-变量定义
Dim reference
Set reference = nothing
If obj.Mappings.Count > 0 Then <-判断用户是否建立了DataSource
For Each source In obj.Mappings.Item(0).SourceClassifiers <-循环获取Association Sources集合
if source.TargetObject is nothing then<-如果映射出错,即在数据库模型中没有对应的Reference,则报错。
%Check% = False
Exit Function
end if
If source.TargetObject.ObjectType = "Reference" Then<-如果映射正确,则跳出循环。
Set reference = source
Exit For
End If
Next
Dim join1
If not reference is nothing Then
For Each join1 In reference.TargetObject.Joins <-查找是否在Reference的Joins下正确建立了ParentTableColumn和ChildTableColumn,如图7所示。
If (join1.ChildTableColumn Is Nothing) Then<-如果其中有一个为空,均报错。
%Check% = False
End If
If (join1.ParentTableColumn Is Nothing) Then
%Check% = False
End If
Next
End If
Else
%Check% = False
End If
End Function
|
注:PD会对每个模型进行检测(包括Package),所以如果读者希望通过程序来控制该模型是否被检测,只须在满足条件的语法段内加上%Check% = True (表示验证正确并跳过)即可。
Persistent Class持久类
对于POJO的持久类,必须为其每个类的属性增加Getter和Setter函数。扩展模型是基于语言模型之上的,也就是说,语言模型中的模板等内容均可在扩展模型中覆盖和重写。所以,在Hibernate扩展模型中采用重载的方法,扩展了Java语言模型的代码生成,保留了原先Java那部分代码,并在扩展模型中加上自己的Getter和Setter模版。
在Java语言模型中,代码生成是依靠%source%模版来完成Java代码的,同时有一个%initializers%模版实现当完成Attribute之后的一些初始化工作,所以在相同位置(Class元模型)的地方重写了%initializers%模版,代码如下:
.foreach_item(Attributes,,,%Persistent%)
[%getterFunction%\n\n]\?Getter function
[%setterFunction%\n\n]\?Setter function
.next
|
在Attribute元模型中增加getterFunction 、setterFunction模版,代码如下:
public %DataType% get%.FU:Code%()?% DataType %表示类的Attribute 的类型(int,float..)
<- get%.FU:Code%()表示“get”和“()”不动,Attribute的名称首字母大写
{
return %Code%;
}
|
然后在Class元模型中增加持久类的Generated Files,并在模版编辑框内输入%source%即可。
Generated Files
PD在每个元模型中提供了文件生成的功能。在Class元模型上右键选择Generated Files。在右边窗口中,在 File Name 下输入生成后的文件名。由于Hibernate映射文件的文件名与类名相同,故输入%mappingFilename%,同时建立mappingFilename 模版,并输入%Code%.hbm.xml。
注:所有的元模型都继承于NamedObject(NamedObject继承于BaseObject),在NamedObject中存放了各种元模型的标准属性,比如:模型名称(Name)、代码名称(Code)、注释、描述等等。所以,为了取到类的名称,就在类元模型下输入%Code%.hbm.xml,那么PD会根据代码名称为每个类建立相应的文件(前提是该类可以被生成,即已持久化)。
Model
Model元模型中主要实现对Configuration Mapping的连接信息的配置,诸如,JDBC等。所用到的方法也就是Extended Attribute和Mapping代码模版。由于篇幅原因,不一一列举,读者可以参考刚才所讲,或者可以在PD安装目录下运行pdvbs11.chm来获取帮助。
Task
Task在代码生成完毕之后被激活,然后PD会依次序执行选中的任务。扩展了Hibernate模型,增加了ANT的Lib路径,生成的目录名称等等选项。在Generation\ Options下建立新的选项即可,类似于Extended Attribute。调用Options选项时,输入如下代码:%GenOptions.选项名%即可获取。
对于Task,希望能够借助ANT的build.xml配置进行自动测试。在PD中,JAVA语言模型已经提供了ANT的build.xml的自动生成并预留接口 (customExecuteTarget、customerProperties、customTaskDefs三个模版) ,目的为了能让扩展模型来重载,有兴趣的读者可以查看Java语言模型(LanguageàEdit Current Object Language,浏览Java::Profile\Model\Templates\Ant\antTemplate)。
建立Task:
在Generation\Tasks上右键,选择New。输入Task Name(就是真正执行的显示名),取名为Run Unit Test。在下面的表格中选择已建立的Command,如果没有建立,则可以在Commands上新建。
Run Unit Test Command代码:
.if (%GenOptions.GenerateTestSource%)?当需要测试时继续..
.ifnot (%$ANT_HOME%)?%$ANT_HOME%环境变量
.log Warning: Undefined Ant home directory variable: ANT_HOME.Use default command: ant.bat.
.log If ant.bat is not accessible from Path, please define a ANT_HOME variable in Tools>General Options>Variables.
.set_value(_ANT, "ant.bat")
.else
.set_value(_ANT, "%$ANT_HOME%\bin\ant.bat")
.set_value(_ANT, "ant.bat")
.endif
.ifnot (%$CMD%)
.set_value(_CMD, "cmd.exe")
.else
.set_value(_CMD, "%$CMD%")
.endif
.execute_command(%_CMD%, /K %_ANT% junit, cmd_PipeOutput)
.else
.log There is no test source to run?记录日志文件中,相应的宏命令还有.warning和.error
.endif
|
说明:
.execute_command为宏命令,用于执行外部的程序。
.execute_command '(' <cmd></cmd>[',' <args></args>[',' <mode></mode>]] ')'
第一个参数为主命令,这里是CMD
第二个参数为主命令的参数,这里是/K ANT.BAT JUNIT
第二个参数为管道类型,PD提供cmd_ShellExecute和cmd_PipeOutput两种方式。前者采用独立的进程方式,后者将会阻塞PD直到任务完成,并且结果将显示在PD的Output窗口内,如图10所示。
图10 PD Output
3.结束语
PowerDesigner是一款灵活性非常强的软件建模工具,基于它的元模型,读者可以随心所欲的用不同语言 (GTL, VBScript, Java, C#等) 来设计出自己的代码生成工具,甚至是语言模型、报表等等。本篇仅仅起到了一个抛砖引玉的作用,我相信,凭借着领域中的经验,读者一定也可以设计出更适合自己的代码生成工具,简化流程、降低成本、加快开发。
附录:
列举了GTL的部分语法,读者也可以参阅PD安装目录下的pdvbs11.chm文件或者Sybase官方网站。
?资源文件
读者可以参考PD11的现有模型:
您可以在安装目录下\ Resource Files\Extended Model Definitions找到现有的扩展模型;在安装目录下\ VB Scripts找到VBScript代码;Ole Automation目录下找到如何用JAVA,C#等其他语言来获取元模型来做自己的代码生成工具;Library目录下找到语言模型。在Printable Docs目录下找到PDF文档(建议参考Advanced User Documentation.PDF文档)。
2. 语法
?设置变量
.set_value '(' <本地变量> ')' <值>[',' <new></new>')'?设置值变量(new代表新建变量,当重新复值的时候,不需要new)
.set_object '(' <本地变量> [',' <对象引用>[',' <new></new>]] ')'?设置对象变量,如Table等
设置模版参数:
.set_object/set_value(<本地变量>,%@1%,new)
那么当调用该模版时,它的后面必须跟上参数,注意,该参数必须也是局部变量,不能是直接的对象。
|
变量名必须用%来封装,即%变量名%
全局变量
ActiveModel获取当前活动模型(VBScript常用)
GenOptions获取用户设置得generation options选项
PreviewMode允许预览与否
CurrentDate当前日期
CurrentUser 当前使用用户
|
变量区域
简单的说,当区域建立后(比如,循环,另一个模版等),在区域中调用区域外的变量,则需要用Outer.变量名来指明。
.foreach_item '(' <集合> [',' <头> [','<尾> [',' <条件> [','<比较> ]]]]')'
<复杂的模版>
.next ['(' <每次循环的分隔符> ')']
注:[]代表可选项
|
.if (条件)
…
.else/.elsif (条件)
…
.endif
|
First ? 集合的第一个元素
IsEmpty ? 判断集合是否为空,返回bool类型
Count ? 返回集合元素个数
|
|
相关推荐
【hibernate代码生成工具】是一种实用的开发辅助软件,主要用于简化Java开发中与Hibernate框架相关的对象关系映射(ORM)代码编写工作。通过自动化的方式,它可以自动生成基于Hibernate的实体类、DAO(数据访问对象...
在"tradingcloudCoreBuilder"这个文件中,很可能是某个特定的Hibernate代码生成工具或者一个项目的核心构建部分,它可能包含了配置文件、模板文件以及生成代码的相关脚本。通过使用或研究这个工具,开发者可以了解...
基于JCF的代码生成工具 博文链接:https://onecan.iteye.com/blog/83136
【标签】"hibernate spring struts2 生成器"进一步强调了这个工具的主要特性,即它专注于这三个流行的技术栈,并且是一个代码自动生成工具。这种工具通常能快速创建基本的CRUD(创建、读取、更新、删除)操作,为...
通过Hibernate生成工具,开发者可以快速地自动生成与数据库表对应的Java实体类、配置文件以及DAO层代码,极大地提高了开发效率。 安装该插件的过程非常简单。首先,你需要将压缩包解压,确保得到三个文件夹。这些...
《代码生成工具设计》 在软件开发过程中,代码生成是一个重要的环节,它可以极大地提高开发效率,减少重复劳动,使得开发者能够更加专注于业务逻辑的设计与实现。本文将探讨一种代码生成工具的设计草案,主要关注其...
总结起来,Hibernate DAO生成工具极大地简化了数据访问层的开发工作,它将数据库操作与业务逻辑分离,提升了代码的复用性和可维护性。通过熟练掌握这类工具的使用,开发者可以更加专注于业务逻辑的实现,从而提高...
为了提高开发效率并减少人为错误,许多开发者选择使用代码生成工具,如"Hibernate实体类生成器mysql版"。这款工具基于FreeMarker模板引擎,结合Java的Swing技术构建了可视化的用户界面,使得开发者能够快速地根据...
SSH代码生成器是一种工具,主要用于自动化生成基于SSH(Spring、Struts2和Hibernate)框架的Web应用程序的基础代码。SSH框架是Java开发中的一个经典组合,它极大地提高了开发效率,简化了项目的构建过程。SSH框架的...
**hibernate实体生成工具**是开发者在使用Hibernate框架时常用的一种辅助工具,它能够自动生成与数据库表对应的Java实体类,大大节省了手动编写代码的时间,提高了开发效率。Hibernate是一个强大的对象关系映射(ORM...
Hibernate的逆向工程工具,也被称为Hibernate Tools,能够从现有的数据库结构自动生成对应的Java持久化类(Entity)、Hibernate配置文件(hibernate.cfg.xml)以及映射文件(.hbm.xml)。这样,开发者可以快速地...
《代码自动生成工具 Hibernate配置文件工具 MagicalTools 深度解析》 在现代软件开发过程中,提高效率和减少重复劳动是至关重要的。为此,开发者们不断寻求自动化工具的帮助,以简化繁琐的任务,如代码编写、配置...
动软代码生成器是由国内开发者开发的一款完全免费的代码生成工具,它可以根据数据库表结构自动生成包括Nhibernate在内的各种代码,大大简化了开发流程。该工具支持多种数据库,可以灵活定制模板,满足不同项目的个性...
本文将深入探讨如何使用JPA和Spring Boot结合,实现代码自动生成工具,提高开发效率。 首先,让我们了解JPA。JPA通过提供一套标准API,使得开发者无需关注底层SQL语句,而是通过定义实体类、注解以及Repository接口...
标题中的“Java代码生成器”特指用于Java编程语言的代码自动生成工具。这类工具通常基于某种模板或者设计模式,根据开发者提供的数据库模型或者业务逻辑,自动生成符合规范的Java源代码。例如,如果你有一个数据库表...
NHibernateMappingGenerator是一款专为NHibernate框架设计的代码生成工具,极大地简化了开发人员在使用NHibernate时的数据映射层创建工作。NHibernate是.NET平台上的一款流行的对象关系映射(ORM)框架,它允许...
JavaEE代码生成器是一款强大的开发工具,主要用于提升JavaEE应用的开发效率。它通过自定义模板和元数据,能够快速生成符合项目规范的Java源代码、配置文件以及相关的Web资源,帮助开发者免去大量重复的手动编码工作...