动物Animal为基类,Pig和Bird为子类,他们之间存在继承关系。这里我们来演示每颗类继承树一张表即一个继承体系共用一张表。
类图:
映射成的数据库表:
Animal.java:
public class Animal {
private int id;
private String name;
private boolean sex;
//省略setter和getter方法
}
Bird.java:
public class Bird extends Animal {
private int height;
//省略setter和getter方法
}
Pig.java:
public class Pig extends Animal {
private int weight;
//省略setter和getter方法
}
映射文件Extends.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.lixue.bean">
<class name="Animal" table="t_animal" lazy="false">
<id name="id">
<generator class="native" />
</id>
<!-- 区分器(标记字段) -->
<discriminator column="type" type="string"/>
<property name="name" />
<property name="sex"/>
<subclass name="Pig" discriminator-value="p">
<property name="weight" />
</subclass>
<subclass name="Bird" discriminator-value="B">
<property name="height"/>
</subclass>
</class>
</hibernate-mapping>
注:
1.在<class>标签中加一个discriminator属性来标识(要指定类型)。
2.子类用<subclass>标签来指定,另外要用discriminator-value来标识当前对象的类型。
测试添加方法:
public void testSave(){
/*定义Session和事物*/
Session session = null;
Transaction transaction = null;
try {
/*获取Session并开启事物*/
session = HibernateUtils.getSession();
transaction = session.beginTransaction();
/*创建Pig对象并设置属性*/
Pig pig = new Pig();
pig.setName("小猪");
pig.setSex(true);
pig.setWeight(200);
session.save(pig);
/*创建Bird对象并设置属性*/
Bird bird = new Bird();
bird.setName("小鸟");
bird.setSex(false);
bird.setHeight(100);
session.save(bird);
/*提交事物*/
transaction.commit();
} catch (Exception e) {
e.printStackTrace();
transaction.rollback();
} finally{
HibernateUtils.closeSession(session);
}
}
public void testLoad() {
Animal animal = (Animal) HibernateUtils.getSession().get(Animal.class, 1);
if (animal instanceof Pig){
System.out.println("猪:" + animal.getName());
} else {
System.out.println("不是猪!");
}
}
注:虽然表面上看起来查询出的对象的类型为Animal,其实Hibernate为此做了优化,非常智能,ID对应的对象是什么类型,查出来的对象就是什么类型,如上述程序,假设ID为1时的记录为Pig对象,那么上述程序输出的结果应该为:"猪 :XXX",因为animal instanceof Pig 为true。
每颗类继承树一长表(一个继承就一张表)的思想:
因为类继承树肯定是对应多个类,要把多个类的信息存放在一张表中,必须有某种机制来区分哪些记录时属于哪个类的,这种机制就是,在表中添加一个字段,用这个字段的值来进行区分。
实现步骤:
1.在父类中用普通的<class>标签定义,另外加上一个discriminator区分器,即指定这个区分的字段的名称和类型。
如:<discriminator column="XXX" type="string" />
2.子类使用<subclass>标签来定义,并且通过discriminator-value属性来指定当前对象用是区分字段来唯一标识。