`
micc010
  • 浏览: 69500 次
  • 性别: Icon_minigender_1
  • 来自: 广西
社区版块
存档分类
最新评论

hibernate any

    博客分类:
  • java
阅读更多
Hibernate中any元素的应用体会


关联(Associations)是Hibernate核心概念之一,比较常用的有:

many-to-one, one-to-one, one-to-many, many-to-many

Hibernate还提供了另外一种关联——异类关联(Heterogeneous Associations)

在Hibernate Reference (cn) 2.1.6中是这样说明的:

引用
6.10. 异类关联(Heterogeneous Associations)
<many-to-any>和<index-many-to-any>元素提供真正的异类关联。这些元素和<any>元素工作方式是同样的,他们都应该很少用到。


下面针对<any>元素,谈一些自己的体会。

一、什么时候需要<any>元素

持久类中“一个属性”关联“另外一个指定的持久类”(几乎每个应用都有这种情况),多半会使用many-to-one, one-to-one这样的关联。映射到关系数据库中,也多半使用外键约束。

可能会遇到有这么一种特殊的情况,需要:持久类中“一个属性”关联“另外一些持久类”。

举个例子:Log类中使用logEntity属性关联一组业务持久类。(也就是说,在Log中记录不同业务类的实例对象)

如果使用many-to-one,则有很大的限制。首先,需要这些业务类都要继承一个超类,而且在数据库中必须有这个超类对应的表。在Hibernate提供的三种继承映射策略中,只能使用前两种:
1、“每棵类继承树使用一个表(table per class hierarchy) ”
2、“每个子类一个表(table per subclass)”

第1种通常不大合适:所有的业务类映射为一张表,冗余过多,限制也多,增加一个业务类就需要修改表结构,不易扩展。

第2种的情况是:表的数量=业务表数量 + 一个超类表,子类表通过主键和超类表关联(所以实际上关系模型是一对一关联)。业务表数量比较多的时候,这种结构的性能和灵活性都有问题。

这时<any>元素就派上用场啦。


二、<any>元素的应用

1、类:

业务类:
public class BizOne {   
    private Long    id;   
    private String  bizOneDescription;   
    //Getters and Setters 省略   
}   
public class BizTwo {   
    private Long    id;   
    private String  bizTwoDescription;   
    private Date    createDate;   
    //Getters and Setters 省略   
}  


日志类:
public class MyLog {   
    private Long    id;   
    private Date    logDate;   
    private Object  logEntity;  //这就是<any>元素对应的属性。   
    //Getters and Setter 省略   
}  



2、hbm.xml 和 表结构:
这里只给出MyLog的hbm.xml(BizOne, BizTwo很简单,不提了):

<hibernate-mapping>   
     <class name="com.test.entity.MyLog" table="MyLog">   
        <id name="id" column="id">   
            <generator class="native"/>   
        </id>   
        <property name="logDate"/>   
        <any name="logEntity" meta-type="string" id-type="long">   
            <meta-value value="One" class="com.test.entity.BizOne"/>   
            <meta-value value="Two" class="com.test.entity.BizTwo"/>   
            <column name="entityMetaValue" length="20" />   
            <column name="entityId"/>   
        </any>   
    </class>   
</hibernate-mapping>  


表结构(MySQL): 
create table MyLog (   
   id BIGINT NOT NULL AUTO_INCREMENT,   
   logDate datetime,   
   entityMetaValue VARCHAR(20);,   
   entityId BIGINT,   
   primary key (id);   
);  


对<any>元素中子元素和属性的理解,可以结合生成的表结构,及其表中的数据(见3):
name: 是持久类中属性名称。
meta-type: 是下面meta-value元素中value的类型,如"string","character"等。
id-type: 是引用类的主键类型。
meta-value元素中value: 该值将保存到数据库表中,用来标识其后的class,即引用的持久类。请参考下面的数据。
meta-value元素中class: 引用持久类的类全称。
第一个column: 保存上面value值的字段。
第二个column: 保存引用持久类的主键值的字段,它的类型是id-type对应到数据库中的字段类型。


3、记录日志的方法:
public MyLog recordLog(Object biz);{   
    MyLog log = new MyLog();;   
    log.setLogDate(new Date(););;   
    log.setLogEntity(biz);; //引用了传递过来的业务对象   
  
    return getLogService();.save(log);; //保存log。我习惯用Spring+Hibernate。   
} 



Hibernate所保存的数据是这样:

引用

--  ---------------------------------  ---------------   --------
id  logDate           entityMetaValue entityId
--  ---------------------------------  ---------------   --------
1  2004-11-15 20:48:52.211  One        1
2  2004-11-15 20:57:25.385  Two        2
3  2004-11-15 21:48:52.211  One        15
4  2004-11-15 22:51:15.185  Two        26
5  2004-11-15 23:27:55.123  Two        36


4、读取Log
public MyLog readLog(Long id);{   
    MyLog log = getLogService();.getLog(id);;   
  
    Object biz = log.getLogEntity();;   
    //...   
  
    return log;   
}  


用<any>所实现的关联,与<many-to-one>等关联的效果是相同的。例如,如果BizOne, BizTwo的lazy="true",则biz是个代理。

5、BizThree如果增加了一个业务类BizThree,在MyLog.hbm.xml中只需增加一行:

Java代码
<meta-value value="Three" class="com.test.entity.BizThree"/> 

          <meta-value value="Three" class="com.test.entity.BizThree"/>

6、限制
在<any>元素中需要指定id-type,这可能是<any>对所关联类的唯一限制了:所关联的类的主键类型必须相同。

三、再谈继承映射策略问题
上面提到了:如果为了让Log能够关联业务类,就要求业务类都要继承同一个超类,是不大合适的。不过,不合适的理由在于这个超类需要在数据库有相应的表。不能说,业务类不能继承一个超类。实际上,很多应用中的业务类都有超类,而且根据情况实现一些接口。此时的继承映射策略是Hibernate Reference中的第三种:每个具体类一个表(table per concrete class)。上面MyLog中的logEntity的类型可以是更有意义的超类,如Entity,当然也可以是接口,不必是Object。这样,即使超类在数据库中没有对应的表,照样可以实现关联。

四、彩票
Hibernate Reference中提到<any>元素的地方不是很多,但提到时,总不忘记说“应该很少用到”,“应该在非常特殊的情况下使用它”。可能从全世界的角度看,使用<any>是低概率事件,但是如果遇到了,就是100%的概率了。因此,当你应用<any>的时候,别忘了购买彩票。因为,与中奖同样的低概率事件——使用<any>——你已经碰到了,你的运气就来了,赶快买彩票吧,准能中奖!

五、感谢
感谢这个论坛!
感谢Hibernate相关资料的译作者,尤其是Hibernate Reference!

如果我所写的有不对的地方,请指出来。感谢!
分享到:
评论

相关推荐

    Beginning Hibernate: For Hibernate 5

    Experienced authors Joseph Ottinger with Dave Minter and Jeff Linwood provide more in-depth examples than any other book for Hibernate beginners. They present their material in a lively, example-...

    hibernate-shards.jar

    any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any ...

    Hibernate+中文文档

    5.1.22. any 5.2. Hibernate 的类型 5.2.1. 实体(Entities)和值(values) 5.2.2. 基本值类型 5.2.3. 自定义值类型 5.3. 多次映射同一个类 5.4. SQL中引号包围的标识符 5.5. 其他元数据(Metadata) 5.5.1. 使用...

    hibernate 教程

    映射到"任意"(any)类型 5.3. SQL中引号包围的标识符 5.4. 映射文件的模块化(Modular mapping files) 6. 集合类(Collections)映射 6.1. 持久化集合类(Persistent Collections) 6.2. 映射集合...

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

    5.1.22. any 5.2. Hibernate 的类型 5.2.1. 实体(Entities)和值(values) 5.2.2. 基本值类型 5.2.3. 自定义值类型 5.3. 多次映射同一个类 5.4. SQL中引号包围的标识符 5.5. 其他元数据(Metadata) 5.5.1. 使用...

    HibernateAPI中文版.chm

    5.1.22. any 5.2. Hibernate 的类型 5.2.1. 实体(Entities)和值(values) 5.2.2. 基本值类型 5.2.3. 自定义值类型 5.3. 多次映射同一个类 5.4. SQL中引号包围的标识符 5.5. 其他元数据(Metadata) 5.5.1. 使用...

    Beginning.Hibernate.For.Hibernate.5.4th.Edition

    Experienced authors Joseph Ottinger with Dave Minter and Jeff Linwood provide more in-depth examples than any other book for Hibernate beginners. They present their material in a lively, example-...

    Beginning Hibernate, 3rd Edition

    Experienced authors Joseph Ottinger with Dave Minter and Jeff Linwood provide more in-depth examples than any other book for Hibernate beginners. The authors also present material in a lively, ...

    Hibernate中文详细学习文档

    5.1.22. any 5.2. Hibernate 的类型 5.2.1. 实体(Entities)和值(values) 5.2.2. 基本值类型 5.2.3. 自定义值类型 5.3. 多次映射同一个类 5.4. SQL中引号包围的标识符 5.5. 其他元数据(Metadata) 5.5.1. 使用...

    Hibernate 中文 html 帮助文档

    5.1.22. any 5.2. Hibernate 的类型 5.2.1. 实体(Entities)和值(values) 5.2.2. 基本值类型 5.2.3. 自定义值类型 5.3. 多次映射同一个类 5.4. SQL中引号包围的标识符 5.5. 其他元数据(Metadata) 5.5.1. 使用 XDoclet...

    Spring.Persistence.with.Hibernate.2nd.Edition.1484202694

    Because the book covers several persistence frameworks, it is suitable for anyone interested in learning more about Spring or any of the frameworks covered. Lastly, this book covers advanced topics ...

    最全Hibernate 参考文档

    5.1.21. any 5.2. Hibernate 的类型 5.2.1. 实体(Entities)和值(values) 5.2.2. 基本值类型 5.2.3. 自定义值类型 5.3. SQL中引号包围的标识符 5.4. 其他元数据(Metadata) 5.4.1. 使用 XDoclet 标记 5.4.2. 使用 JDK ...

    hibernate-entitymanager-3.2.1.GA

    THIS RELEASE OF HIBERNATE ENTITYMANAGER REQUIRES HIBERNATE CORE 3.2.0.GA (and above) AND DOES NOT WORK WITH HIBERNATE 3.1.x OR ANY OLDER VERSION OF HIBERNAT

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

    any 5.2. Hibernate 的类型 5.2.1. 实体(Entities)和值(values) 5.2.2. 基本值类型 5.2.3. 自定义值类型 5.3. 多次映射同一个类 5.4. SQL中引号包围的标识符 5.5. 其他元数据(Metadata) 5.5.1. 使用 ...

    Hibernate教程

    6.1.21. any 6.2. Hibernate 的类型 6.2.1. 实体(Entities)和值(values) 6.2.2. 基本值类型 6.2.3. 自定义值类型 6.3. SQL中引号包围的标识符 6.4. 其他元数据(Metadata) 6.4.1. 使用 XDoclet 标记 6.4.2. ...

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

    5.1.22. any 5.2. Hibernate 的类型 5.2.1. 实体(Entities)和值(values) 5.2.2. 基本值类型 5.2.3. 自定义值类型 5.3. 多次映射同一个类 5.4. SQL中引号包围的标识符 5.5. 其他元数据(Metadata) 5.5.1. 使用...

    hibernate动态映射表处理oracle的clob类型

    hibernate动态映射表处理oralce10g的clob类型,压缩包为整个工程包. 真诚地希望能帮到你,同时真诚地希望你能和我交流, about any question^_^

    hibernate

    映射到"任意"(any)类型 5.3. SQL中引号包围的标识符 5.4. 映射文件的模块化(Modular mapping files) 6. 集合类(Collections)映射 6.1. 持久化集合类(Persistent Collections) 6.2. 映射集合...

    Hibernate Reference Documentation3.1

    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 5.4. SQL quoted identifiers 5.5. Metadata ...

    Hibernate3的帮助文档

    6.1.21. any 6.2. Hibernate 的类型 6.2.1. 实体(Entities)和值(values) 6.2.2. 基本值类型 6.2.3. 自定义值类型 6.3. SQL中引号包围的标识符 6.4. 其他元数据(Metadata) 6.4.1. 使用 XDoclet 标记 6.4.2. ...

Global site tag (gtag.js) - Google Analytics