7.3 实体元数据
为了使用MDA思想进行系统的设计开发,在案例系统中为在系统中处于核心的数据实体引入了元数据机制,系统建模、代码生成、系统开发、系统运行全部基于此元数据机制。
7.3.1 实体元数据格式
实体元数据中定义了实体的别名、对应的表名、实体的字段列表、字段的名称、字段的别名、字段类型等,基本包含了数据实体的公共特征,实体元数据文件的扩展名为“.emf”。下面是人员元数据的内容,各个标记的含义见注释:
<EnityModel>
<!--实体的名称为Person-->
<Name>Person</Name>
<!--实体的别名为Person-->
<Alias>人员</Alias>
<!--此实体定义在com.cownew.PIS.basedata包下-->
<PackageName>com.cownew.PIS.basedata</PackageName>
<!--实体对应的数据库表名为T_BD_Person-->
<DbTableName>T_BD_Person</DbTableName>
<!--实体的主键为id-->
<PrimaryKey>id</PrimaryKey>
<!--下面是字段定义列表-->
<FieldList>
<Field>
<Name>id</Name>
<Alias>id</Alias>
<DbFieldName>FId</DbFieldName>
<DataType>STRING</DataType>
<AllowNull>false</AllowNull>
<Length>50</Length>
<IsLinkProperty>false</IsLinkProperty>
</Field>
<Field>
<!--字段名为age-->
<Name>age</Name>
<!--字段别名为年龄-->
<Alias>年龄</Alias>
<!--字段对应的数据库字段名为FAge-->
<DbFieldName>FAge</DbFieldName>
<!--字段类型为INTEGER-->
<DataType>INTEGER</DataType>
<!--字段不允许为空-->
<AllowNull>false</AllowNull>
<!—字段不是关联属性(不关联其他实体)-->
<IsLinkProperty>false</IsLinkProperty>
</Field>
<Field>
<Name>name</Name>
<Alias>姓名</Alias>
<DbFieldName>FName</DbFieldName>
<DataType>STRING</DataType>
<AllowNull>false</AllowNull>
<Length>100</Length>
<IsLinkProperty>false</IsLinkProperty>
</Field>
<Field>
<Name>number</Name>
<Alias>编码</Alias>
<DbFieldName>FNumber</DbFieldName>
<DataType>STRING</DataType>
<AllowNull>false</AllowNull>
<Length>50</Length>
<IsLinkProperty>false</IsLinkProperty>
</Field>
</FieldList>
</EnityModel>
实体元数据不仅能定义简单的字段,而且能定义实体之间的关联关系,下面是一个定义了关联类型的系统操作员数据实体:
<EnityModel>
<Name>User</Name>
<Alias>系统用户</Alias>
<PackageName>com.cownew.PIS.base.permission</PackageName>
<DbTableName>T_BS_User</DbTableName>
<PrimaryKey>id</PrimaryKey>
<FieldList>
<Field>
<Name>id</Name>
<Alias>主键</Alias>
<DbFieldName>FId</DbFieldName>
<DataType>STRING</DataType>
<AllowNull>false</AllowNull>
<Length>50</Length>
<IsLinkProperty>false</IsLinkProperty>
</Field>
<Field>
<Name>number</Name>
<Alias>账号</Alias>
<DbFieldName>FNumber</DbFieldName>
<DataType>STRING</DataType>
<AllowNull>false</AllowNull>
<Length>50</Length>
<IsLinkProperty>false</IsLinkProperty>
</Field>
<Field>
<Name>password</Name>
<Alias>密码</Alias>
<DbFieldName>FPassword</DbFieldName>
<DataType>STRING</DataType>
<AllowNull>false</AllowNull>
<Length>50</Length>
<IsLinkProperty>false</IsLinkProperty>
</Field>
<Field>
<Name>person</Name>
<Alias>对应人</Alias>
<DbFieldName>FPersonId</DbFieldName>
<DataType>STRING</DataType>
<AllowNull>false</AllowNull>
<Length>50</Length>
<IsLinkProperty>true</IsLinkProperty>
<LinkType>MANYTOONE</LinkType>
<LinkEntity>/com/cownew/PIS/basedata/Person.emf</LinkEntity>
<CascadeType>none</CascadeType>
<Inverse>false</Inverse>
</Field>
<Field>
<Name>isFreezed</Name>
<Alias>是否被冻结</Alias>
<DbFieldName>FIsFreezed</DbFieldName>
<DataType>BOOLEAN</DataType>
<AllowNull>false</AllowNull>
</Field>
</FieldList>
</EnityModel>
这个元数据的定义和Person类似,唯一的区别在于这里定义了一个“person”字段关联到“Person”实体:
<Name>person</Name>
<Alias>对应人</Alias>
<DbFieldName>FPersonId</DbFieldName>
<DataType>STRING</DataType>
<AllowNull>false</AllowNull>
<Length>50</Length>
<!—此字段是关联字段-->
<IsLinkProperty>true</IsLinkProperty>
<!—与被关联实体是“多对一”的关系-->
<LinkType>MANYTOONE</LinkType>
<!—关联实体路径是/com/cownew/PIS/basedata/Person.emf-->
<LinkEntity>/com/cownew/PIS/basedata/Person.emf</LinkEntity>
<CascadeType>none</CascadeType>
<Inverse>false</Inverse>
对于关联字段只要设置IsLinkProperty为true,在LinkType标记内指定关联的类型,在LinkEntity中指定关联的实体路径(注意实体路径以“/”分割,并且全部是相对于根包的相对路径)即可。对于“一对多(ONETOMANY)”类型的字段还需要添加“<KeyColumn>***</KeyColumn>”标记表示被关联实体通过哪个字段反向关联本实体。
能够定义实体、定义字段、字段类型、实体关联、并定义了一些平台特有属性,这就是一个比较完备的实体元数据模型了。
7.3.2 元数据编辑器
虽然元数据模型是比较简单易懂的,但是手工编写这样的元数据文件仍然是低效且易出错的,直接查看元数据源文件也是非常烦琐的,为此我们开发了一个元数据文件的编辑器,使用此编辑器就可以通过可视化的界面编辑和查看实体元数据文件。编辑器还内置了代码生成功能,可以根据实体元数据文件生成JavaBean文件和ORM配置文件,目前仅支持Hibernate,不过由于设计时考虑到了可扩展问题,所以可以很轻松地支持其他ORM工具的代码和配置文件的生成。
这个元数据文件的编辑器是基于Eclipse的插件机制进行开发的。本书不假定也不强迫用户使用任何IDE,所以这里不介绍这个插件的实现原理。这里只简单介绍一下这个插件的使用,读者可以将此插件移植到当前使用的IDE上,当然也可以将其开发成一个独立的应用程序。
【例7.2】一个销售小票的建模过程(元数据编辑器的使用)。
下面以一个销售小票的建模过程来演示一下元数据编辑器的使用,图 7.1是销售小票的类图。
图7.1 销售小票类图
(1) 安装Eclipse,安装CowNewStudio插件。
在工程根目录下创建一个名字为“metadata”的文件夹,也可以直接打开案例工程,这个工程已经建立好了“metadata”文件夹以及常用的实体元数据。本例子中假定您使用的是案例工程。
(2) 在metadata/com/cownew/目录下创建文件夹demo。
在demo文件夹上右击,在弹出的快捷菜单中选择【新建】|【其他】命令,弹出向导对话框,如图7.2所示,选中CownewStudio节点下的Entity Model File creation wizard,单击【下一步】按钮。
(3) 进入如图7.3所示的新建界面,在【文件名】文本框中输入Goods.emf,然后单击【完成】按钮。
图7.2 选择向导
图7.3 选择所在文件夹
(4) 然后系统会自动用实体元数据编辑器打开此元数据文件,如图7.4所示。
编辑器的主要选项卡有两个,其中config选项卡为元数据文件的可视化编辑界面,而Goods.emf选项卡为元数据文件的源码编辑器,可以直接在此处编辑元数据文件的源码。
在可视化编辑选项卡中,Name、PackageName因为是系统预设的,所以是不可编辑的。在Alias中输入“商品”,在DBTableName中输入“T_Demo_Goods”。
编辑器左下方的空白区域是字段列表区,实体定义的字段在此展示,可以单击add按钮新增字段,单击remove按钮删除选定的字段。字段属性的编辑在eclipse的属性视图中进行,可以通过选择【窗口】|【显示视图】|【属性】命令打开此视图,可以通过单击编辑器中的快捷按钮open properties views来打开属性视图。
图7.4 元数据编辑器
(5) 单击add按钮增加id字段,在如图7.5所示的属性视图中编辑字段属性。
图7.5 属性视图
(6) 按照同样方式增加number、name字段。
在PrimaryKey下拉列表框中选择id作为主键。然后单击Eclipse的保存图标完成商品元数据的建模。
按照同样的步骤建立SaleBill实体元数据,增加id、number、saleDate属性。在增加saler属性的时候,此属性关联着系统中已经建立的Person元数据,因此设置isLinkProperty为true,设置完毕后属性视图中的属性比普通属性多了一些内容,主要是linkEntity、linkType、casadeType等。单击linkEntity属性右边的浏览按钮,如图7.6所示,选择系统中已经定义好的“Person元数据”。
选择linkType属性为MANYTOONE。SaleBillDetail元数据没有建立,所以暂时不增加details属性。
(7) 按照同样步骤增加“SaleBillDetail”实体元数据。
回到SaleBill实体元数据编辑界面,增加details属性,设置linkedEntity指向SaleBillDetail实体,设定linkType属性为OneToMany,从keycolumn属性的下拉列表框中选择FHeadId属性,表示SaleBillDetail实体通过FHeadId字段指向SaleBill实体。
图7.6 选择关联元数据
(8) 建模完毕,下面开始生成代码和配置文件。同时选中Goods.emf、SaleBill.emf、SaleBillDetail.emf三个文件,右击,在弹出的快捷菜单中选择CownewStudio∣Generate Code from Model File命令,弹出如图7.7所示的界面。
图7.7 代码生成选项
(9) Target ORM为生成的文件对应的ORM类型,目前支持Hibernate2和Hibernate3。按照图7.7进行设置,单击【完成】按钮,然后在Eclipse中就可以看到生成的文件了,如图7.8所示。hbm配置文件生成在bizLayer包下,JavaBean生成在common包下。
图7.8 生成的代码和配置文件
<!-- page -->