Hibernte继承映射
继承映射分为三种:
- 继承结构共用一张表结构
- 每个类一张表结构
- 每个具体类一张表结构
下面使用Animal、Dog、Fish举例
Animal类如下:
package com.hml.domain.a; public abstract class Animal { private Integer id; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Dog类如下:
package com.hml.domain.a; public class Dog extends Animal { private float runSpeed; public float getRunSpeed() { return runSpeed; } public void setRunSpeed(float runSpeed) { this.runSpeed = runSpeed; } }
Fish类如下:
package com.hml.domain.a; public class Fish extends Animal { private float swimSpeed; public float getSwimSpeed() { return swimSpeed; } public void setSwimSpeed(float swimSpeed) { this.swimSpeed = swimSpeed; } }
1、继承结构共用一张表
Animal.hbm.xml映射文件如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.hml.domain.a"> <class name="Animal" table="t_animal" discriminator-value="0"> <id name="id"> <generator class="native"></generator> </id> <discriminator column="type" type="int"></discriminator> <property name="name"></property> <subclass name="Dog" discriminator-value="1"> <property name="runSpeed"></property> </subclass> <subclass name="Fish" discriminator-value="2"> <property name="swimSpeed"></property> </subclass> </class> </hibernate-mapping>
生成的表结构:
整个继承结构一张表,在映射文件建中通过subclass节点,对子类进行映射。由于整个继承结构一张表,所以在表中需要区分具体是哪个类,所以需要一个鉴别字段,这里通过 discriminator指定,然后在映射类的节点上添加鉴别值,使用这种映射的限制是,子类属性不能有非空约束。
2、每个类一张表
Animal.hbm.xml映射文件如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.hml.domain.a"> <class name="Animal" table="t_animal" > <id name="id"> <generator class="native"></generator> </id> <property name="name"></property> <joined-subclass name="Dog" table="t_dog"> <key column="id"></key> <property name="runSpeed"></property> </joined-subclass> <joined-subclass name="Fish" table="t_fish"> <key column="id"></key> <property name="swimSpeed"></property> </joined-subclass> </class> </hibernate-mapping>
生成的表结构如下:
t_animal:
t_dog
t_fish
每个类一张表是通过joined-subclass映射子类,joined-subclass中的key是个外键,在基类中存储基类中的信息,然后每个子类生成的表存储本类中的数据。
3、每个具体类一张表
映射文件如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.hml.domain.a"> <class name="Animal" table="t_animal" abstract="true"> <id name="id"> <generator class="hilo"> <param name="table">hi_value</param> <param name="column">next_value</param> <param name="max_lo">100</param> </generator> </id> <property name="name"></property> <union-subclass name="Dog" table="t_dog"> <property name="runSpeed"></property> </union-subclass> <union-subclass name="Fish" table="t_fish"> <property name="swimSpeed"></property> </union-subclass> </class> </hibernate-mapping>
每个具体类一张表需要在抽象类上添加abstract="true",不然,抽象了也会生成表的。每个具体类一张表时,主键不能使用自增长,如果使用自增长会报错的。
值得注意的是,继承结构表结构的映射一般不会使用,原因是太复杂,效率低。