`
longdick
  • 浏览: 580239 次
  • 性别: Icon_minigender_1
  • 来自: 0
社区版块
存档分类
最新评论

[转]Hibernate 3中的formula

阅读更多

时间:2006-01-09
作者:Dai Yifan

 

HibernateSpring 是两个杰出的开源框架,它们在越来越多的J2EE应用中得到采用。尽管它们致力于解决的问题有很大区别,它们却都有一个重要特性:依赖注入 。Spring有助于在将对象返回给客户端之前整理出对象之间的依赖关系,从而大大减少客户端的编码。而Hibernate则擅长于在将整个对象模型 返回给客户端之前整理出数据模型所表现的依赖关系。当直接使用JDBC将数据模型映射为对象模型时,我们通常需要编写大量的代码以构建对象模型。而Hibernate消除了其中的大部分编码工作。

  Hibernate 2.x提供了基本的表格到对象的映射、常见的关联映射(包括一对一、一对多和多对多关联)、多态映射等等。Hibernate 3.x则通过使用formula、filter、subselect等提高映射灵活性,提供细粒度的解释特性,从而将其推进到一个新的级别。

  在本文中,我们将展示有助于模型转换的各种formula特性。在Hibernate 3.x之前,formula属性只能够出现在property元素中。现在仍然可以这样做,但是Hibernate 3.x提供了一个formula属性或元素(两者在formula的用法方面实质上是等效的),可以在许多元素中使用,包括discriminator、 many-to-one、one-to-one、element、many-to-many、map-key、map-key-many-to-many 和property。这样就大大提高了对象关系映射的灵活性,从而支持对复杂数据 模型的更为细粒度的解释。

  基本上,有两种情况必须使用formula:

  • 需要formula的计算结果时 。与元素discriminator、element、map-key、map-key-many-to-many和property一起使用formula属于这类情况。
  • 为了连接的目的需要使用formula 时。与元素many-to-one、one-to-one和many-to-many一起使用formula属于这类情况。

第一类:从formula获取计算结果 Discriminator(识别器)
  在现实数据模式中,经常出现使用一个表来描述另一个表的情况。在对象关系映射中,Formula有助于提供灵活的多态性。

  在图1展示的例子中,有两个表:Product和ProductRelease。每个产品记录有一个ProductReleaseID来引用它对应的产品版本记录,包括产品版本名称、类型、版本日期等。

Product and Product Release Data Model
图1. 产品和产品版本数据模型

  在ProductRelease表中有一个值得注意的属性是SubProductAllowable,它的值可以是0或1。值为1意味着允许该 产品版本中的任何产品有子产品,而值为0则意味着不允许有子产品。例如,有些产品由多个子产品组成,而有些产品只有该产品本身。

  图2展示了一个对该数据模型解释而成的对象模型。Nested接口定义了getSubProducts和setSubProducts方法。 NestedProduct类扩展了基类Product并实现了Nested接口。一个产品数据记录应该是Product还是NestedProduct 取决于相应产品版本记录的SubProductAllowable值。

Product and Product Release Object Domain Model
图2. 产品和产品版本对象的域模型

  为了完成这个模型转换,我们使用了Hibernate 3.x映射,如下:

<hibernate-mapping>  <class name="Product"         discriminator-value="0"  lazy="false">    <id name="id" type="long"/>           <discriminator         formula="(select pr.SubProductAllowable                 from ProductRelease pr                 where pr.productReleaseID=                        productReleaseID)"        type="integer" />    <subclass  name="NestedProduct"          discriminator-value="1"/>  </class></hibernate-mapping>

  如果formula表达式计算结果为0,也就是不支持子产品,则对象将属于Product类。如果结果是1,对象将是一个 NestedProduct。在表1和表2中,对Product表中的第一个记录(ProductID=10000001)来说,初始化的类将是 NestedProduct,因为它引用一个SubProductAllowable=1的ProductRelease记录。对Product表中的第 二个记录(ProductID=20000001)来说,初始化的类将是Product,因为它引用一个SubProductAllowable=0的 ProductRelease记录。

S/N ProductReleaseID SubProductAllowable ...
1 11 1 i
2 601 0 i
. ProductRelease表中的记录

 

S/N ProductID ProductReleaseID ...
1 10000001 11 i
2 20000001 601 ...
表 2. Product表中的记录

Property
  Property元素中的formula允许对象属性包含导出值,比如sum、average、max等的结果。如:

<property name="averagePrice" formula="(select avg(pc.price) from PriceCatalogue pc, SelectedItems si where si.priceRefID=pc.priceID)"/>

  此外,formula还可以基于当前记录的特定属性值从另一个表检索值。例如:

<property name="currencyName" formula="(select cur.name from currency cur where cur.id= currencyID)"/>

  它从currency表检索货币名称。如您所见,这些直接的映射可以消除大量的转换编码。

map-key
  
formula允许map-key取任何可能的值。在下面的例子中(图3),我们希望Role_roleID成为对象模型的map-key (图4)。

User Role Data Schema
图3. 用户角色数据 模式

User Role Object Model
图4. 用户角色对象模型

  在上面的数据模式中 ,User和Role被通过一个称为User_has_Role的多对多的关系表连接起来。为了获取一个User以及分配给它的所有角色,我们使用下面的映射:

<hibernate-mapping>  <class name="User">    <id name="userID"/>    <map name="roles"          table="UserRole"/>      <key column="User_userID"/>      <map-key         formula="Role_RoleID"         type="string"/>      <many-to-many         column="Role_RoleID"        class="Role"/>    </map>  </class>  <class name="Role">    <id name="roleID"/>  </class></hibernate-mapping>

  Role_RoleID用作many-to-many元素的连接列值。然而,Hibernate不允许map-key和many-to-many的 column属性同时使用Role_RoleID。但是使用一个formula,Role_RoleID还是可以用于map-key。

  Formula和map-key-many-to-many的用法与map-key类似。然而,map-key-many-to-many通常用于三重关联,其中map键是被引用的对象自身,而不是一个被引用的属性。

  然而,有些地方不支持formula。有些数据库(如Oracle 7)不支持嵌入的select语句(即,嵌入一个SQL 语句的select部分中的selectSQL ),也不支持用于计算结果的formula。因此,需要首先检查是否支持嵌入式的selectSQL语句。

  因为由Hibernate映射生成的SQL将formula表达式作为其select目标的一部分,所以对所使用的数据库的非标准语言将有助于充分使用formula,尽管这可能会降低代码的可移植性。

第二类:将formula用于连接 many-to-one
  
现实世界数据模型中的另一个常见场景是私有关系映射,它是指除基本的一对一、一对多和多对多关系之 外的映射。formula是针对这种私有关系管理所提供的元素之一。图5展示了一个例子,其中一个公司可以有多个联系人,但是他们之中只能有一个是默认的 联系人。一个公司有多个联系人是典型的一对多关系。但是,为了标识默认联系人,ContactPerson表使用了一个defaultFlag属性(1为 是,0为否)。


图5. 用户角色数据模式


图6. 用户角色对象模型

  为了将默认联系人关系解释为对象模型(图6),我们使用下面的映射:

<hibernate-mapping>  <class name="Company" table="Company">    <id name="id" />    <many-to-one       name="defaultContactPerson"       property-ref="defaultContactPerson">        <column name="id"/>        <formula>1</formula>        </many-to-one>  </class>  <class name="Person" >    <id name="id" />    <properties name="defaultContactPerson">        <property name="companyID" />        <property name="defaultFlag" />    </properties>  </class></hibernate-mapping>

  我们将companyID和defaultFlag聚合到一个名为defaultContactPerson的properties元素中,形 成Person表的一个独有的键。将Company类中的many-to-one元素与Person类中的 defaultContactPersonproperties元素连接。产成的SQL将类似于:

select c.id, p.id from Company c, Person p where p.companyID=c.id and p.defaultFlag=1

one-to-one
  在Hibernate中,one-to-one主要用于两个表共用相同的主键 。而对于外键关联,通常使用many-to-one。但是,使用formula,one-to-one可以通过外键连接多个表。上面的many-to-one例子可以使用one-to-one映射为:

<hibernate-mapping>  <class name="Company" table="Company" >    <id name="id" />    <one-to-one name="defaultContactPerson"         property-ref="defaultContactPerson" >    <formula>id</formula>    <formula>1</formula>    </many-to-one>  </class>  <class name="Person" >    <id name="id" />    <properties name="defaultContactPerson">      <property name="companyID" />      <property name="defaultFlag" />    </properties>   </class></hibernate-mapping>

其他:many-to-many
  formula可以与many-to-many元素一起用于从关系表到实体表的特殊连接,尽管通常不需要这样做。

结束语
  本文中的例子展示了大部分的formula使用场景。当需要formula的计算值时,formula表达式将出现在产生的SQL语句 的select部分。而当formula用于连接时,它出现在产生的SQL 语句的where部分。此外,formula表达式可以使用任意的SQL非标准语言,只要目标数据库支持。因此,formula有助于无需编码地实现从数据模型到对象模型的细粒度映射。

分享到:
评论

相关推荐

    Hibernate+中文文档

    5.1.20. 字段和规则元素(column and formula elements) 5.1.21. 引用(import) 5.1.22. any 5.2. Hibernate 的类型 5.2.1. 实体(Entities)和值(values) 5.2.2. 基本值类型 5.2.3. 自定义值类型 5.3. 多次...

    hibernate3.2中文文档(chm格式)

    5.1.20. 字段和规则元素(column and formula elements) 5.1.21. 引用(import) 5.1.22. any 5.2. Hibernate 的类型 5.2.1. 实体(Entities)和值(values) 5.2.2. 基本值类型 5.2.3. 自定义值类型 5.3. 多次...

    Hibernate中文详细学习文档

    5.1.20. 字段和规则元素(column and formula elements) 5.1.21. 引用(import) 5.1.22. any 5.2. Hibernate 的类型 5.2.1. 实体(Entities)和值(values) 5.2.2. 基本值类型 5.2.3. 自定义值类型 5.3. 多次...

    Hibernate 中文 html 帮助文档

    5.1.20. 字段和规则元素(column and formula elements) 5.1.21. 引用(import) 5.1.22. any 5.2. Hibernate 的类型 5.2.1. 实体(Entities)和值(values) 5.2.2. 基本值类型 5.2.3. 自定义值类型 5.3. 多次映射同一个...

    Hibernate3+中文参考文档

    5.1.19. 字段和规则元素(column and formula elements) 5.1.20. 引用(import) 5.1.21. any 5.2. Hibernate 的类型 5.2.1. 实体(Entities)和值(values) 5.2.2. 基本值类型 5.2.3. 自定义值类型 5.3. SQL中引号包围...

    HibernateAPI中文版.chm

    5.1.20. 字段和规则元素(column and formula elements) 5.1.21. 引用(import) 5.1.22. any 5.2. Hibernate 的类型 5.2.1. 实体(Entities)和值(values) 5.2.2. 基本值类型 5.2.3. 自定义值类型 5.3. 多次...

    最全Hibernate 参考文档

    5.1.19. 字段和规则元素(column and formula elements) 5.1.20. 引用(import) 5.1.21. any 5.2. Hibernate 的类型 5.2.1. 实体(Entities)和值(values) 5.2.2. 基本值类型 5.2.3. 自定义值类型 5.3. SQL中引号包围...

    Hibernate3的帮助文档

    详细的Hibernate3的帮助文档 前言 1. 翻译说明 2. 版权声明 1. 在Tomcat中快速上手 1.1. 开始Hibernate之旅 1.2. 第一个持久化类 1.3. 映射cat 1.4. 与Cat同乐 1.5. 结语 2. Hibernate入门 2.1. 前言 2.2. ...

    hibernate3.04中文文档.chm

    字段和规则元素(column and formula elements) 6.1.20. 引用(import) 6.1.21. any 6.2. Hibernate 的类型 6.2.1. 实体(Entities)和值(values) 6.2.2. 基本值类型 6.2.3. 自定义值类型 6.3. SQL中引号包围...

    Hibernate注释大全收藏

    Hibernate注释大全收藏 声明实体Bean @Entity public class Flight implements Serializable { Long id; @Id public Long getId() { return id; } public void setId(Long id) { this.id = id; } } @Entity ...

    Hibernate教程

    字段和规则元素(column and formula elements) 6.1.20. 引用(import) 6.1.21. any 6.2. Hibernate 的类型 6.2.1. 实体(Entities)和值(values) 6.2.2. 基本值类型 6.2.3. 自定义值类型 6.3. SQL中引号包围的...

    hibernate 体系结构与配置 参考文档(html)

    3. 配置 3.1. 可编程的配置方式 3.2. 获得SessionFactory 3.3. JDBC连接 3.4. 可选的配置属性 3.4.1. SQL方言 3.4.2. 外连接抓取(Outer Join Fetching) 3.4.3. 二进制流 (Binary Streams) 3.4.4. 二级缓存与...

    Hibernate_3.2.0_符合Java习惯的关系数据库持久化

    5.1.20. 字段和规则元素(column and formula elements) 5.1.21. 引用(import) 5.1.22. any 5.2. Hibernate 的类型 5.2.1. 实体(Entities)和值(values) 5.2.2. 基本值类型 5.2.3. 自定义值类型 5.3. 多次...

    Hibernate Reference Documentation3.1

    5.1.20. column and formula elements 5.1.21. import 5.1.22. any 5.2. Hibernate Types 5.2.1. Entities and values 5.2.2. Basic value types 5.2.3. Custom value types 5.3. Mapping a class more than once ...

    hibernate_reference中文文档.pdf

    3.4.5. 查询语言中的替换 ............................................... 43 3.4.6. Hibernate 的统计(statistics)机制 ............................. 43 3.5. 日志 ...........................................

    hibernate 框架详解

    3. 体系结构(Architecture) 3.1. 概况(Overview) 3.2. 实例状态 3.3. JMX整合 3.4. 对JCA的支持 4. 配置 4.1. 可编程的配置方式 4.2. 获得SessionFactory 4.3. JDBC连接 4.4. 可选的配置属性 4.4.1. ...

    Hibernate参考文档

    5.1.20. 字段和规则元素(column and formula elements) 5.1.21. 引用(import) 5.1.22. any 5.2. Hibernate 的类型 5.2.1. 实体(Entities)和值(values) 5.2.2. 基本值类型 5.2.3. 自定义值类型 5.3. 多次映射同一个...

    基于SSH模拟当当网项目(电子商务平台)

    数量统计可以采用Hibernate中formula映射实现. 3.购物车业务组件利用Spring中scope="session" a.购买处理流程 buy.action--&gt;BuyAction--&gt;CartFactory--&gt;ShoppingCart --&gt;ProductDAO 将ShoppingCart组件交给容器...

    habernate文档

    hibernate最新文档,可以供初学者快速了解并使用hibernate。

    jdbc基础和参考

    3.hibernate的配置文件(hibernate.cfg.xml)得存在 4.POJO.hbm.xml文件存在 5.hibernate的jar包以及数据库的驱动包存在 Hibernate的编程: 1.构建Configuration对象读取配置文件 2.读取映射文件 3.构建SessionFactory...

Global site tag (gtag.js) - Google Analytics