下面是我在读<深入浅出Hibernate>时做的笔记,LZ的问题完全可以通过第3种设计来达到,我也是这样处理的.
A。Table per concret class表与子类之间独立的一对一关系,父类不独立设表。因此子类表的父类字段必须保持一致,如果父类发生变动,相应子类也要发现更改。在某些应用中,如果要对父类进行查询,必须对所有子表进行查询并汇总,性能低下。那么,我们是否可以把父类独立成表?B。Table per subclass父类独立成表,子表中只保存所扩展属性,通过外键关联。如此可不必为子类编写映射文件,在父类映射文件中通过<joined-subclass>配置,注意必须配置<key>属性。本质上是运行中通过SQL的case子句进行判断。3个表?是不是太多了,一般情况下我们都是通过一个表的冗余数据来处理。C。Table per class hierarchy把所有父类和子类扩展属性全放在一个表中,通过一个Discriminator(辨别标记)来对子类进行区分。在映射文件中先声明辨别标记:<discriminator colunm="category" type="String">在subclass元素中指定标记值,如:<subclass name="TBook" discriminator-value="1">

解决方案 »

  1.   

    谢谢killme2008(zane dennis),似乎有些感觉。但是继续深入一下:
    1.在使用时,业务对象还是被拆开了,只是被表达成parent-subclass的模式;
    2.如果我有多个属性组,各属性组单独对应一个属性表呢?
      

  2.   

    分割对象是必然的,把复杂对象分为更为细粒度的对象.
    表达成parent-subclass模式我也觉的不够恰当,可以通过comopnent来处理更为合理
    如User对象有个Contract(联系方法)属性,把此方法独立成类,做为User的一个属性
    public class Contract implements Serializable {
    private String address;
    private String tel;
    private String zipcode;
    public Contract(){} public String getAddress() {
    return address;
    }
    public void setAddress(String address) {
    this.address = address;
    }
    public String getTel() {
    return tel;
    }
    public void setTel(String tel) {
    this.tel = tel;
    }
    public String getZipcode() {
    return zipcode;
    }
    public void setZipcode(String zipcode) {
    this.zipcode = zipcode;
    }
    }
    在User对象中有此对象的getter,setter,在User.hbm.xml中设置:
    <component name="contract" class="Contract">
         <property name="address" column="address"  type="java.lang.String"></property>
         <property name="tel" column="tel" type="java.lang.String"></property>
         <property name="zipcode" column="zipcode" type="java.lang.String"></property>
     </component>
    这样更为符合现实模型,至于多属性要单独列表,这就是我上面提到的第2种设计,只不过如此一来又要回到parent-subclass的模式上来.还是采用单张表,冗余处理更为合理
      

  3.   

    嗯,感觉上的确是component更加合理。但是如果用component,如何进行历史纪录呢?
    比如这个user和contact的例子,对contact进行修改后,要求在contact表里面insert一个新的纪录而不是update一个纪录(当然加上时间戳),而user里面的信息并不改...
    要是用了component,后台就update,也就无法保留历史信息了...其实历史信息对于真正的应用,比如:企业的/电子政务的,都是非常重要的...
      

  4.   

    谢谢killme2008。
    觉得这个问题的业务场景应该非常常见的,不知道大家有什么好的模式没有。
      

  5.   

    Hibernate 是数据库层的东西,与数据库一一对应是最正常的设计。不要硬把 Hibernate 对象和业务对象变成一样,如果业务层对象与数据库层对象不一致,Hibernate 应该参照数据库设计。
      

  6.   

    to jacklondon:
    可否就问题中的业务场景详细说明一下?
    我的理解和你有些不一致,ORM应该是作为业务对象到数据库的桥梁,应该是业务对象为主考虑...