3.hibernate继承关系的映射
- 一棵继承树映射到一张表的情况
<!--
Animal为父类
Dog与Pig为子类.
这种映射的不足是所有子类的属性不能为not-null="true",因为这样的话会在生成表的语句时设置对应列不能为空
那样在插入其它类型时会出现错误。也就是这种映射在建表时不能为子类的字段指定为非空
对于查询,显然用load在默认是不支持多态查询的,因为load默认查询时只是先加载相应的Id,而id不能反映它的具体的子类类型。所谓的默认情况就是当lazy="true"时。当lazy="false"时load也是跟get一样,查询所有的属性,所以支持多态查询
-->
<class name="Animal" table="tb_Animal">
<id name="id" column="id">
<generator class="increment"/>
</id>
<!-- 判别字段,这个字段实体类中不必要有,是各类区别的标志,所以子类要为这个标志指定一个唯一值
-->
<discriminator column="type" type="string"/>
<property name="name" column="name"/>
<property name="age" column="age"/>
<!-- discriminator-value为这个子类指定在数据库中的标识 -->
<subclass name="Dog" discriminator-value="D">
<property name="hight" column="hight"/>
</subclass>
<subclass name="Pig" discriminator-value="P">
<property name="weight" column="weight"/>
</subclass>
</class>
2. 每个类映射到一张表的情况(父类表保存共有信息,子类表保存自有信息,共享主键的方式)
<!-- 为每个类映射到一个表,
这样的好处是没有别的冗余字段,不好处是建表太多,插入查询都会发送多条sql语句,性能比较差
-->
<class name="Animal" table="tb_Animal">
<id name="id" column="id">
<generator class="increment"/>
</id>
<property name="name" column="name"/>
<property name="age" column="age"/>
<joined-subclass name="Pig" table="tb_Pig">
<!-- key只会在数据库中生成字段,对实体类没有任何,影响。
可见其是用共享主键的 -->
<key column="id"/>
<property name="weight" column="weight"/>
</joined-subclass>
<!-- 使用joined-subclass -->
<joined-subclass name="Dog" table="tb_Dog">
<key column="id"/>
<property name="hight" column="hight"/>
</joined-subclass>
</class>
3.为每个具体的子类生成一个表,即父类不再有表对应,所有的信息都放在相应的子表中
<!-- 这种方式不会为父类生成一个表,会为每个子类生成一个表,并保存其所有信息
不足的地方很多。主键的生成方式对于某些数据库不能为自增。为什么呢?当然有原因。
对于oracle可以,因为oracle的自增是假自增,这个很容易解决。
-->
<class name="Animal" abstract="true">
<id name="id" column="id">
<generator class="increment"/>
</id>
<property name="name" column="name"/>
<property name="age" column="age"/>
<union-subclass name="Pig" table="tb_Pig">
<property name="weight" column="weight"/>
</union-subclass>
<union-subclass name="Dog" table="tb_Dog">
<property name="hight" column="hight"/>
</union-subclass>
</class>
<!-- 对于继承关系,如果要用第一种显然好一些,当然如果能不用就不用会更好! -->