1 整个继承树映射到一张表
类关系图:

表结构:

type: 用此字段区分元祖为技术还是销售
映射文件:
<hibernate-mapping package="com.coffee.subclass">
<class name="Employee" discriminator-value="0" >
<id name="id">
<generator class="native"></generator>
</id>
<property name="name" unique="true"/>
<many-to-one name="department" class="Department" column="department_id"/>
<class name="Employee" discriminator-value="0" >
<id name="id">
<generator class="native"></generator>
</id>
<property name="name" unique="true"/>
<many-to-one name="department" class="Department" column="department_id"/>
//鉴别器元素 区分子类 这个字段是hibernate使用的 ,程序不需要操作,对程序来说是没有意义的
<discriminator column="work_type" type="int"/> 缺省类型:String
<!-- 使用鉴别器 -->
< subclass name="Sale" discriminator-value="1">
<property name="sell"></property>
</subclass>
< subclass name="Skiller" discriminator-value="2">
<property name="skill"></property>
</subclass>
</class>
</hibernate-mapping>
<discriminator column="work_type" type="int"/> 缺省类型:String
<!-- 使用鉴别器 -->
< subclass name="Sale" discriminator-value="1">
<property name="sell"></property>
</subclass>
< subclass name="Skiller" discriminator-value="2">
<property name="skill"></property>
</subclass>
</class>
</hibernate-mapping>
插入和检索:
插入的时候,hibernate会根据对象的实例,进行插入,不需要去指定type自动分类 ,整合到一张表
检索的时候,如get方式查询,hibernate会根据查询的class查询出具体的实例
优点:只操作一张表,效率比较高
缺点:表结构因为继承关系已经固定了,不利于扩展,如果要添加子类,需要修改表结构,字段也不能有非空的约束,因为子类不同,有些字段必须是空的。
如果改进:如果子类很多,属性也很多,则空字段也很多,添加 子类,需要修改表结构 所以可以用每个类一张表的方式来映射:
2每个子类一张表
对象模型 如上不变
表结构:

映射文件:
<hibernate-mapping package="com.coffee.subAndPer">
<class name="Employee" table="employees">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name" unique="true"/>
<many-to-one name="department" class="Department" column="department_id"/>
<!-- 使用内连接 和union-subclass区别:-->
<hibernate-mapping package="com.coffee.subAndPer">
<class name="Employee" table="employees">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name" unique="true"/>
<many-to-one name="department" class="Department" column="department_id"/>
<!-- 使用内连接 和union-subclass区别:-->
//用joined-subclass :因为 hibernate主要是靠链接来查询
<joined-subclass name="Sale" table=" sales">
< key column="emp_id"></key> //外键
<property name="sell"></property>
</joined-subclass>
<joined-subclass name="Sale" table=" sales">
< key column="emp_id"></key> //外键
<property name="sell"></property>
</joined-subclass>
//表变多了,需要指定table
<joined-subclass name="Skiller" table=" skillers">
<key column="emp_id"/>
<property name="skill"></property>
</joined-subclass>
</class>
</hibernate-mapping>
<joined-subclass name="Skiller" table=" skillers">
<key column="emp_id"/>
<property name="skill"></property>
</joined-subclass>
</class>
</hibernate-mapping>
如果把第一种方式和第二种方式结合起来:
如果技术人员非常少,销售人员总类很多,不需把技术人员单独列个表出来的时候,就可以采用第三种方式 将内连接join-subclass和 鉴别器第一种方式结合起来使用
3内连接和鉴别器结合使用 技术和员工一张表,销售单独一张表
表结构:

映射文件:
<hibernate-mapping package="com.coffee.subAndPer">
<class name="Employee" table="employees">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name" unique="true"/>
<discriminator type="int" column="type" force="false"></discriminator>
<many-to-one name="department" column="department_id"/>
<subclass name="Skiller" discriminator-value="1">
<property name="skill"></property>
</subclass>
<class name="Employee" table="employees">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name" unique="true"/>
<discriminator type="int" column="type" force="false"></discriminator>
<many-to-one name="department" column="department_id"/>
<subclass name="Skiller" discriminator-value="1">
<property name="skill"></property>
</subclass>
//都是使用subclass 不过加了个join table 跟第二种方式有些不同
<subclass name="Sale" discriminator-value="2">//这个鉴别器的值要给出,鉴别器默认类型是String
<join table="sales">
<key column="emp_id"></key>
<property name="sell"></property>
</join>
</subclass>
</class>
</hibernate-mapping>
<subclass name="Sale" discriminator-value="2">//这个鉴别器的值要给出,鉴别器默认类型是String
<join table="sales">
<key column="emp_id"></key>
<property name="sell"></property>
</join>
</subclass>
</class>
</hibernate-mapping>
4每个具体的类一张独立的表:
之前的查询,都需要关联另外一张表,如果把完整的信息放到一张表里,表与表之间就独立开来,在效率上就有一定的提升
表结构:

映射文件:
<hibernate-mapping package="com.coffee.unionSubClass">
< !--如果Employee是个抽象类 可以加上一个abstract=true 这样这张表就不会产生了 -->
<class name="Employee" discriminator-value="0" >
<id name="id">
<!-- 每个具体类一张表和之前每个子类一张表的区别是,这里的employee只存放普通员工,不同员工只操作一张表,而之前的每个子类一张表是必须要依赖于employee存在。 所以这里的映射的主键不能重复,3张表中的id不能一样,用hilo(高低位)不用native ,native是自增长方式 -->
< !--如果Employee是个抽象类 可以加上一个abstract=true 这样这张表就不会产生了 -->
<class name="Employee" discriminator-value="0" >
<id name="id">
<!-- 每个具体类一张表和之前每个子类一张表的区别是,这里的employee只存放普通员工,不同员工只操作一张表,而之前的每个子类一张表是必须要依赖于employee存在。 所以这里的映射的主键不能重复,3张表中的id不能一样,用hilo(高低位)不用native ,native是自增长方式 -->
<generator class=" hilo"></generator>
</id>
<property name="name" unique="true"/>
<many-to-one name="department" class="Department" column="department_id"/>
<union-subclass name="Skiller" >
<property name="skill"></property>
</union-subclass>
//这里的鉴别器不需要了
<union-subclass name="Sale">
<property name="sell"></property>
</union-subclass>
</class>
</hibernate-mapping>
</union-subclass>
</class>
</hibernate-mapping>
hilo:高低位 主键生成器:
具体实现 :hibernate会单独建立一张表存放主键的高位,然后程序运行的时候,在内存中产生低位的自增长
增删改:
增删改的操作 和之前的继承关系效率差不多,插入到自己的表中
而查询:
根据id需要查询三张表,把3张表链接起来查询,效率可能要低一点