动物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属性来指定当前对象用是区分字段来唯一标识。