选择显示字体大小

hibernate 3 的formulas

hibernate 3 的formulas

作者:dai yifan

08/03/2005

翻译:dannytan


版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明
原文地址:
http://www.onjava.com/pub/a/onjava/2005/08/03/hibernate.html
中文地址:
http://www.matrix.org.cn/resource/article/43/43813_hibernate_formulas.html
关键词: formulas hibernate


hibernatespring是越来越来的j2ee应用程序使用的两个突出的开源框架。虽然他们面向的是不同问题,但是他们都有共同的关键特征:依赖注射。在返回对象给客户之前,spring建立对象之间的依赖关系,这样减少了在使用这些对象的客户中的大量代码。hibernate专门在返回一个完整的对象模型给客户之前挑选出数据模型和对象模型之间的依赖关系。当直接使用jdbc来映射数据模型到对象模型的时候,我们通常需要写大量的代码来建立对象模型。hibernate减少了这部分这样的编码工作。

hibernate2.x 提供了基本的表到表的映射,正常的关联映射(包括一对一,一对多,多对多关系),多态映射,等等。hibernate3.x通过formula, filter, subselect来增强映射的灵活性,把这些映射提个到另一高度。

在本文中,我们将要向你展现formula的各种特征是如何辅助模式转换的。在hibernate3.x之前,formula的属性仅仅出现在一个property元素中。hibernate3.x在保持原来用法的同时,还提供了一个formula的属性或元素(两者在formula的使用方面都是等价的),能够用于任何元素中,包括discriminator, many-to-one, one-to-one, element, many-to-many, map-key, map-key-many-to-many, 和 property。这将给对象关系映射(o-r)增加非常大的灵活性,并且可以对复杂的数据模型进行更加精致的解释。

两种必须使用formula的主要情景是:

1.需要使用formula计算结果的情形。带有元素discriminator, element, map-key, map-key-many-to-many, 和 property的formula归为这一类。

2.需要使用formula来进行连接操作的情形。在元素many-to-one, one-to-one, 和 many-to-many中使用的formula归为这一类。

第一类:通过公式计算结果

识别器

在实际的数据模式中,常常存在使用一个表来描述另一个表的情况。formula能够有助于在o-r映射中提供灵活的多态。

在图1例子中,有两个表product和productrelease。每一个product的记录都在productrelease有一个productreleaseid的引用,包括产品发布名称,类型,发行日期等。


图1.产品和产品发布数据模型

在表productrelease中有一个让人感兴趣的属性是subproductallowable,它的值要么是0,要么是1。值1就意味着这个产品发布下的任意产品允许有子产品,而值0则意味着不允许这样的子产品。例如,一些产品是从多个子产品装配而来的,而另一些产品,他们单独地成为独立的单元。
图2展现了一个解释这种数据模式的对象模型。nested的接口定义了getsubproducts和setsubproducts方法。类nestedproduct扩展了基类product,也实现了接口nested。产品数据记录是一个product还是一个nestedproduct,依赖于产品相应的产品发布记录的域subproductallowable的值。


图2.产品和产品发布对象领域模型

为了实现这个模型转换,使用下面的hibernate3.x的映射:

<hibernate-mapping>
  <class name=&quot;product&quot;
        discriminator-value=&quot;0&quot;  lazy=&quot;false&quot;>
    <id name=&quot;id&quot; type=&quot;long&quot;/>      
    <discriminator
        formula=&quot;(select pr.subproductallowable
                from productrelease pr
                where pr.productreleaseid=
                        productreleaseid)&quot;
        type=&quot;integer&quot; />
    <subclass  name=&quot;nestedproduct&quot;  
        discriminator-value=&quot;1&quot;/>
  </class>
</hibernate-mapping>


如果formula表达式计算的结果是0,也就是说,该产品不存在子产品,那么,该对象就是类product的实例。如果结果是1,那么对象就是类nestedproduct的实例。 在表1和2中,对于表product中的第一个记录(productid=10000001),因为它引用了一个有着subproductallowable=1的productrelease产品记录,所以,初始化的类将是nestedproduct。而在产品product表中的第二个记录(productid=20000001),因为它引用了有着subproductallowable=0的表productrelease的记录,所以,初始化类将会是product。


表1.表productrelease中的记录


表2表product中的记录

property

property元素中的formula允许对象属性包含某些衍生值,像sum, average, max,等计算的结果,

例如:
<property name=&quot;averageprice&quot; formula=&quot;(select avg(pc.price) from pricecatalogue pc, selecteditems si where si.pricerefid=pc.priceid)&quot;/>

而且,formula也有助于从另一表中通过当前记录的某个属性值来获取数据。例如:
<property name=&quot;currencyname&quot; formula=&quot;(select cur.name from currency cur where cur.id= currencyid)&quot;/>

这有助于从表currency中检索currency名称。正如你看到的那样,这些直接映射能够省下许多转换的代码。

map-key
formula允许map-key拥有任何可能的值。在下面的例子(图3)中,我们将role_roleid作为对象模型(图4)的map-key。


图3.user role数据模式


图4.user role对象模型

在上面的数据模型中,user和role通过一个叫做user_has_role的关系表连接成多对多(many-to-many)关系。为了获得一个user及其所有与之关联的roles,我们可以使用下面的映射:

<hibernate-mapping>
  <class name=&quot;user&quot;>
    <id name=&quot;userid&quot;/>
    <map name=&quot;roles&quot;  
        table=&quot;userrole&quot;/>
      <key column=&quot;user_userid&quot;/>
      <map-key
        formula=&quot;role_roleid&quot;
        type=&quot;string&quot;/>
      <many-to-many
        column=&quot;role_roleid&quot;
        class=&quot;role&quot;/>
    </map>
  </class>
  <class name=&quot;role&quot;>
    <id name=&quot;roleid&quot;/>
  </class>
</hibernate-mapping>


role_roleid被用来作为many-to-many元素的连接域的值。然而,hibernate并不允许role_roleid同时出现在map-key和many-to-many中。但是,使用formula,role_roleidf却也能够用于map-key中。

另一种情景:element, map-key-many-to-many, 及其它
与property一样,element能够被赋给任何有效formula表达式的运算值。

带有map-key-many-to-many的formula的使用,类似于带有map-key的formula。然而,map-key-many-to-many常常使用在三重关系中。在三重关系中,一个映射的键本身是被参照的对象,而不是一个被参照的属性。

然而,有几种formula不支持的情形。一些数据库(例如oracle 7)不支持嵌入sql语句(这就是说,在sql语句的select部分嵌入sql语句),在这种情况下,不支持使用formula来计算结果。因此,你需要首先检查是否支持嵌入sql语句。

由于来自于hibernate映射的sql使用formula表达式作为它的select目标结果的表达式部分,所以,知道一些你所使用的数据库sql语句的知识,将有助于你使用formula,尽管这会减少代码的移植性。

第二种情形:使用formula来连接

多对一
另一个在实际中常见的数据模型是属性关系映射(proprietary relationship mapping),也就是除了基本的一对一,一对多,多对多关系而外的映射关系。formula是一个用于这种属性关系管理的元素之一。图5展现了一个例子,在这个例子中,一个公司可能有许多联系人,但是他们中仅仅只有一个是缺省的联系人。有许多联系人的公司是典型的一对多关系。然而,为了标识缺省联系人,表contactperson使用属性defaultflag来标识他们(1表示是,0表示不是)。



图5.用户角色数据模式


图6. 用户角色对象模型

为了解释在对象模型中(图6)缺省联系人关系,我们使用下面的映射:

<hibernate-mapping>
  <class name=&quot;company&quot; table=&quot;company&quot;>
    <id name=&quot;id&quot; />
    <many-to-one
      name=&quot;defaultcontactperson&quot;
      property-ref=&quot;defaultcontactperson&quot;>
        <column name=&quot;id&quot;/>
        <formula>1</formula>
        </many-to-one>
  </class>
  <class name=&quot;person&quot; >
    <id name=&quot;id&quot; />
    <properties name=&quot;defaultcontactperson&quot;>
        <property name=&quot;companyid&quot; />
        <property name=&quot;defaultflag&quot; />
    </properties>
  </class>
</hibernate-mapping>


上面,我们将companyid和defaultflag分组到名为defaultcontactperson的properties元素中,它构成了表person的唯一键值。在company类中的many-to-one元素与类person中的defaultcontactperson properties元素相连接。最后的sql语句如下:

select c.id, p.id from company c, person p where p.companyid=c.id and p.defaultflag=1


一对一
hibernate中,一对一关系主要用于有着相同主键的两个表连接。我们常常使用多对一关系来表示外部键关联。然而,通过使用formula,一对一关系就能通过外部键将表连接。上面的多对一的例子能够使用如下的一对一的关系映射:

<hibernate-mapping>
  <class name=&quot;company&quot; table=&quot;company&quot; >
    <id name=&quot;id&quot; />
    <one-to-one name=&quot;defaultcontactperson&quot;
        property-ref=&quot;defaultcontactperson&quot; >
    <formula>id</formula>
    <formula>1</formula>
    </many-to-one>
  </class>
  <class name=&quot;person&quot; >
    <id name=&quot;id&quot; />
    <properties name=&quot;defaultcontactperson&quot;>
      <property name=&quot;companyid&quot; />
      <property name=&quot;defaultflag&quot; />
    </properties>
   </class>
</hibernate-mapping>


其他关系:多对多
尽管不常常使用多对多元素的formula,但是,这种formula能够用于从关系表到一个实体表的特别联接。


结论
本文中的例子展现了大多数formula的使用场景。当需要计算一个formula的值的时候,formula表达式将会出现在最终的sql语句的select部分。并且当使用一个formula来进行连接的时候,它就出现在最终sql语句的where部分。而且,只要是目标数据库支持的任意sql语句,formula的表达式就能够使用。其结果是,不需要代码,formula就能有助于实现从数据模型到对象模型的精确的映射关系。

资源
这篇文章的例子代码:[下载文件]
hibernate提供了大多数的有关hibernate orm的信息。
在[url=]theserverside上的filter article,介绍了扩展过虑器。
spring一个非常友好的框架,并且提供了与hibernate和其他数据访问工具的集成。
&quot;dependency injection:&quot; 一个依赖注射的权威介绍
dependency injection basics: 一个易于理解的关于依赖注射的介绍。

dai yifan 是一个主要银行解决方案提供商的技术顾问


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons