对于hebernate中继承映射的实现共有4种方式:
首先我们建立一个Department部门表和Employee成员表,然后建立两个子类,分别是:技术人员(Skiller)和售价(Sales)。
方式一:整个的继承体系就用一张表。设计一张表employee里面包括id,name,depart_id,type,skill,sell。建立映射表如下:
<class name="Employee" table="employee"discriminator-value="0">
<id name="id"column="id">
<generator class="native"/>
</id>
<!-- 鉴别器 -->
<discriminator column="type"type="int" />
<property name="name"column="name" />
<many-to-one name="depart"column="depart_id" />
<subclass name="Skiller"discriminator-value="1">
<property name="skill"/>
</subclass>
<subclass name="Sales"discriminator-value="2">
<property name="sell"/>
</subclass>
</class>
discriminator-value (辨别标志): 一个用于区分不同的子类的值,在多态行为时使用。
Subclass:多态持久化需要为父类的每个子类都进行定义。对于“每一棵类继承树对应一个表”的策略来说,就需要使用<subclass>定义。
Type鉴别器默认为String类型。
方式二:每个子类一张表,存放所有特有的属性。建立映射表如下:
<class name="Employee" table="employee">
<id name="id">
<generator class="native"/>
</id>
<property name="name"column="name" />
<many-to-one name="depart"column="depart_id" /><!--
连接
--><joined-subclass name="Skiller" table="skiller">
<key column="employee_id"/>
<property name="skill"/>
</joined-subclass>
<joined-subclass name="Sales"table="sales">
<key column="employee_id"/>
<property name="sell"/>
</joined-subclass>
</class>
连接的子类(joined-subclass) 每个子类可能被映射到他自己的表中(每个子类一个表的策略)。被继承的状态通过和超类的表关联得到。我们使用<joined-subclass>元素。
方式三:混合使用“一个类继承体系一张表”和“每个子类一张表”。映射表如下:
<class name="Employee"table="employee" discriminator-value="0">
<id name="id">
<generator class="native"/>
</id>
<discriminator column="type"type="int" />
<property name="name"column="name" />
<many-to-one name="depart"column="depart_id" />
<subclass name="Skiller"discriminator-value="1">
<property name="skill"/>
</subclass>
<subclass name="Sales"discriminator-value="2">
<join table="sales">
<key column="employee_id"/>
<property name="sell"/>
</join>
</subclass>
</class>
方式四:每个具体类一张表(union-subclass) ,保存是子类完整信息。映射表如下:
<class name="Employee" table="employee"discriminator-value="0">
<id name="id"><!--
高低位的主键生成器
--><generator class="hilo"/>
</id>
<property name="name"column="name" />
<many-to-one name="depart"column="depart_id" />
<union-subclass name="Skiller"table="skiller">
<property name="skill"/>
</union-subclass>
<union-subclass name="Sales"table="sales">
<property name="sell"/>
</union-subclass>
</class>
Hilo:使用一个高/低位算法高效的生成long, short 或者 int类型的标识符。给定一个表和字段(默认分别是hibernate_unique_key 和next_hi)作为高位值的来源。 高/低位算法生成的标识符只在一个特定的数据库中是唯一的。
源码如下:Department类:
package cn.csdn.hibernat.domain;
import java.util.List;
public class Department {
private int id;
private String name;
private List<Employee> emps;
public Department() {
super();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Employee> getEmps() {
return emps;
}
public void setEmps(List<Employee> emps) {
this.emps = emps;
}
public String toString() {
return "Department[id=" + id + ",name=" + name + ",emps=" + emps
+ "]";
}
}
Employee类:
packagecn.csdn.hibernat.domain;
public class Employee {
private int id;
private String name;
private Department depart;
public Employee() {
super();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Department getDepart() {
return depart;
}
public void setDepart(Department depart) {
this.depart = depart;
}
public String toString() {
return "Employee[id=" + id + ",name=" + name + ",depart=" + depart
+ "]";
}
}
HibernateUtil工具类:
package cn.csdn.hibernate.util;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public final class HibernateUtil {
privatestatic SessionFactory sessionFactory;
publicHibernateUtil() {
}
static{
Configurationcfg = new Configuration();
cfg.configure();
/*
* 用来完成Hibernate的初始化---用来读取配置文件中的信息,可以指定配置文件的位置cfg.configure("");
* 得到sessionFactoroy的工厂对象,相当于DirverManager
*/
sessionFactory= cfg.buildSessionFactory();
//通过sessionFactory得到session,与会话中的session没有关系
}
publicstatic SessionFactory getSessionFactory() {
returnsessionFactory;
}
publicstatic Session getSession() {
returnsessionFactory.openSession();
}
}
子类Sales:
package cn.csdn.hibernat.domain;
public class Sales extends Employee {
private int sell;
public int getSell() {
return sell;
}
public void setSell(int sell) {
this.sell = sell;
}
}
子类Skiller:
package cn.csdn.hibernat.domain;
public class Skiller extends Employee {
private String skill;
public String getSkill() {
return skill;
}
public void setSkill(String skill) {
this.skill = skill;
}
}
测试类:
package cn.csdn.hibernate.test;
import org.hibernate.Session;
import org.hibernate.Transaction;
import cn.csdn.hibernat.domain.Department;
import cn.csdn.hibernat.domain.Employee;
import cn.csdn.hibernat.domain.Sales;
import cn.csdn.hibernat.domain.Skiller;
importcn.csdn.hibernate.util.HibernateUtil;
public class TestExtend {
publicstatic void main(String[] args) {
//TODO Auto-generated method stub
add();
System.out.println("---------------------------");
query(2);
}
staticvoid add() {
Sessions = null;
Transactiontx = null;
try{
s= HibernateUtil.getSession();
tx= s.beginTransaction();
Departmentdepart = new Department();
depart.setName("departmentone");
Employeeemp1 = new Employee();
emp1.setName("aaa");
emp1.setDepart(depart);
Skilleremp2 = new Skiller();
emp2.setName("bbb");
emp2.setDepart(depart);
emp2.setSkill("coding");
Salesemp3 = new Sales();
emp3.setName("ccc");
emp3.setDepart(depart);
emp3.setSell(1000);
s.save(depart);
s.save(emp1);
s.save(emp2);
s.save(emp3);
tx.commit();
}finally {
if(s != null)
s.close();
}
}
staticvoid query(int empId){
Sessions = null;
Transactiontx = null;
try{
s=HibernateUtil.getSession();
tx=s.beginTransaction();
//支持多态查询
Employeeemp = (Employee) s.get(Employee.class, empId);
System.out.println(emp.getName()+emp.getClass());
if(empinstanceof Skiller){
((Skiller)emp).getSkill();
}elseif(emp instanceof Sales){
((Sales)emp).getSell();
}
tx.commit();
}finally{
if(s!=null)
s.close();
}
}
}
Department.hbm.xml映射:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping
package="cn.csdn.hibernat.domain">
<class name="Department" table="department">
<id name="id"column="id">
<generator class="native"/>
</id>
<property name="name"column="name"/>
<set name="emps"cascade="save-update" inverse="true">
<key column="depart_id"/>
<one-to-many class="Employee"/>
</set>
</class>
</hibernate-mapping>
Employee.hbm.xml映射:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.csdn.hibernat.domain"><!--
方式一:
--><!-- <classtable="employee" discriminator-value="0"> <id
column="id"> <generatorclass="native" /> </id> 鉴别器 <discriminator
column="type" type="int" /><property column="name" /><many-to-one
column="depart_id" /><subclass discriminator-value="1">
<property /> </subclass><subclass discriminator-value="2">
<property /> </subclass></class> --><!--
方式二
--><!-- <class table="employee"><id> <generator
/> </id> <propertyname="name" column="name" /> <many-to-one
column="depart_id" /> 连接<joined-subclass table="skiller">
<key column="employee_id" /> <propertyname="skill" /> </joined-subclass>
<joined-subclasstable="sales"> <key column="employee_id" />
<property /></joined-subclass> </class> --><!--
方式三
--><!--<classtable="employee" discriminator-value="0"> <id
> <generator/> </id> <discriminator column="type"
type="int" /> <propertyname="name" column="name" /> <many-to-onename="depart"
column="depart_id" /> <subclassdiscriminator-value="1"> <property
/> </subclass> <subclassname="Sales" discriminator-value="2">
<join table="sales"> <keycolumn="employee_id" /> <property />
</join> </subclass> </class> --><!--
方式四
--><class name="Employee"table="employee" discriminator-value="0">
<id name="id"><!--
高低位的主键生成器
--><generator class="hilo"/>
</id>
<property name="name"column="name" />
<many-to-one name="depart"column="depart_id" />
<union-subclass name="Skiller"table="skiller">
<property name="skill"/>
</union-subclass>
<union-subclass name="Sales"table="sales">
<property name="sell"/>
</union-subclass>
</class>
</hibernate-mapping>