使用Hibernate的问题:多个产品表使用一个订单表的问题

03-09-10 dkhz
多个产品表使用一个订单表在Hibernate中的设计问题

由于产品内容的很大差异,使用了多个表保存不同的产品

产品表1:

product_1

--- product_id (pk)

--- product_name

--- other_info

....

产品表2:

product_2

--- product_id (pk)

--- product_name

--- other_info

...

等等其它产品表

使用同一个表来保存所有产品的订单

order

--- order_id (pk)

--- product_table

--- product_id (FK)

--- other_column

...

order.product_id和product_1 , product_2的product_id是多对一的关系

在order.hbm.xml中定义

<many-to-one name="product1" class="test.hibernate.Product1">

<many-to-one name="product2" class="test.hibernate.Product2">

可以实现操作,但使用起来很别扭,必需显式的指定产品类型

newOrder.addProduct1Order(),newOrder.addProduct2Order(),....

读订单时:

aOrder.getProduct1Order(), aOrder.getProduct2Order(),....

请教各位道友:有没有一个优雅的解决方法?

谢谢了!

feiyuwen
2003-09-10 15:36
能实现就可以的啊,就是麻烦点。

不过如果设计一个product接口,让所有的product类实现它,这样就可以直接aOrder.getProductOrder(),aOrder.setProductOrder()去做,但是product的mapping文件我就不太清楚怎么写了

robbin
2003-09-10 15:46
这不是Hibernate的问题,是数据库设计的问题,既然都是产品这种对象,在系统设计看来,就是一个对象。你可以加一个“类型”属性,来区分不同种的产品。

--- product_id (pk)

--- product_name

--- product_type

--- other_info

....

yehs220
2003-09-10 15:51
<any>可以做到,要两列,一列保存关联实体的类型,另一列保存标识

dkhz
2003-09-10 15:55
谢谢robbin这么快回复

数据库使用的是MySQL,

1. 由于性能和其它方面的考虑,不可以把所有记录放到一个表中,mysql对超过千万记录的表操作很慢

2. 产品类型区别很大,有很多字段不相同,这么多字段放在一个表里也不合理

除了更改数据库设计的方法外,Hibernate可不可以解决这个问题呢?

yehs220
2003-09-10 15:57
<any>
<p>

可以做到,要两列,一列保存关联实体的类型,另一列保存标识

dkhz
2003-09-10 16:08
> 可以做到,要两列,一列保存关联实体的类型,另一列保存标

> ?>

那在Hibernate中如何写hbm呢?

<many-to-one name="写那个表呢?" class="这里那个类呢?">
<p>

robbin
2003-09-10 16:09
我也一下子想不出来好办法,其实你的需求是进行动态映射。也就是说Order对象可以根据运行时刻的不同条件,选择映射不同的Product表。本来实现动态映射也不难,自己实现一个ClassPersister接口就行了。但问题是你不同Product表有不同的字段,那就意味着不同的Product肯定是不同的对象,有不同的属性。你写代码的时候是不知道在运行时刻有哪些属性可以存取的,因此连getter/setter方法有没有都不确定,怎么写的来程序呢?

我想不出来好办法,大家开动脑筋吧。

dkhz
2003-09-10 16:19
简化一下:

产品类的属性不相同,但在购买时可提供一组基本的getter/setter方法如:set/getProductId, set/getProductName, set/getPrice等

dkhz
2003-09-10 17:45
banq老大有没有好办法?

robbin
2003-09-10 18:08
那你可以试试这样来做,自己实现ClassPersister,映射到一个接口上去,就像上面帖子提到的那样,接口里面定义getter/setter方法,然后在ClassPersiter实现类里面根据条件返回不同的接口实现类,也就是不同的Product类对象。

曹晓钢
2003-09-10 22:56
subclass此处是否能够使用?

根据不同的property,映射到不同的表。

(不是很有把握得说)

http://www.hibernate.org/44.html

Hibernate 2.2

introduction of <join> element, for mappings like

<class name="A" table="A" discriminator-value="A">

<id name="id" column="id">

<generator class="uuid.hex"/>

</id>

<discriminator column="discr" type="character"/>

<property name="a"/>

<join table="A1">

<key column="id"/>

<property name="a1"/>

<property name="a2"/>

</join>

<subclass name="B" discriminator-value="B">

<property name="b"/>

<join table="B1">

<key column="id"/>

<property name="b1"/>

</join>

<join table="B2">

<key column="id"/>

<property name="b2"/

</join>

</subclass>

<subclass name="C" discriminator-value="C">

<join table="C">

<key column="id"/>

<property name="c1"/>

<property name="c2"/>

</join>

</subclass>

</class>

曹晓钢
2003-09-10 22:57
faint,贴出来的<和&rt;之间的被吃掉了。....

<class name="A" table="A" discriminator-value="A">
    <id name="id" column="id">
        <generator class="uuid.hex"/>
    </id>
    <discriminator column="discr" type="character"/>
    <property name="a"/>
    <join table="A1">
        <key column="id"/>
        <property name="a1"/>
        <property name="a2"/>
    </join>
    <subclass name="B" discriminator-value="B">
        <property name="b"/>
        <join table="B1">
            <key column="id"/>
            <property name="b1"/>
        </join>
        <join table="B2">
            <key column="id"/>
            <property name="b2"/
        </join>
    </subclass>
    <subclass name="C" discriminator-value="C">
        <join table="C">
            <key column="id"/>
            <property name="c1"/>
            <property name="c2"/>
        </join>
    </subclass>
</class>

<p>

dkhz
2003-09-10 23:03
用ClassPersister实现一个接口对把Product添加到订单的操作确实简化了,可是如何在这些hbm中定义product和order表之间的映射关系呢?尤其是order表中如何设置many-to-one的属性?

dkhz
2003-09-10 23:18
根据曹晓钢的建议参考了hibernate_reference.pdf 第26页:

4.1.13. subclass
Finally, polymorphic persistence requires the declaration of each subclass of the root persistent class. For the
(recommended) table-per-class-hierarchy mapping strategy, the <subclass> declaration is used.
<subclass
    name="ClassName" (1)
    discriminator-value="discriminator_value" (2)
    proxy="ProxyInterface" (3)
    dynamic-update="true|false"
    dynamic-insert="true|false">
    <property .... />
    .....
</subclass>
(1)name: The fully qualified class name of the subclass.
(2)discriminator-value (optional - defaults to the class name): A value that distiguishes individual subclasses.
(3)proxy (optional): Specifies a class or interface to use for lazy initializing proxies.
Each subclass should declare its own persistent properties and subclasses. <version> and <id> properties are
assumed to be inherited from the root class. Each subclass in a heirarchy must define a unique discriminatorvalue.
If none is specified, the fully qualified Java class name is used.
<p>

看来subclass应该是正确的方向,还在试验中。

猜你喜欢
2Go 1 2 下一页