分享
 
 
 

Hibernate中any元素的应用体会

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

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、类:

业务类:

java代码:

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 省略

}

日志类:

java代码:

public class MyLog {

private Long

id;

private Date

logDate;

private Object

logEntity;

//这就是<any元素对应的属性。

//Getters and Setter 省略

}

2、hbm.xml 和 表结构:

这里只给出MyLog的hbm.xml(BizOne, BizTwo很简单,不提了):

java代码:

<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):

java代码:

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、记录日志的方法:

java代码:

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

java代码:

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"/

6、限制

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

三、再谈继承映射策略问题

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

四、彩票

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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有