Hibernate之继承映射----采用单具体表继承
Hibernate之继承映射----采用单具体表继承
所谓继承映射就是把继承关系映射到数据库里。就像A继承B这样的。
继承映射有三种实现策略:
1》单表继承。每棵类继承树使用一个表(table per class hierarcy)
2》具体表继承。每个子类一个表(table per subclass)
3》类表继承。每个具体类一个表(table per concrete class )(有一些限制)
下面才用第二种方法,还是采用上面的例子,这样每个子类一个表,这样就会生成三个表。
采用这种策略,对象模型不需要变化,我们只是把关系模型改变了
第一步:首先建立实体的对象模型:
public class Animal {
private int id;
private String name;
private boolean sex;
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 boolean isSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
}
public class Bird extends Animal {
private int height;
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
}
public class Pig extends Animal {
private int weight;
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}
第二步:因为每个对象映射成一张表,故映射文件就不一样了。
每个子类映射成一张表
t_animal
|
id |
name |
sex |
|
|
猪猪 |
true |
|
|
鸟鸟 |
false |
t_pig
|
pid |
weight |
|
1 |
100 |
t_bird
|
bid |
height |
|
2 |
50 |
第三步,建立hibernate的配置文件:
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.url">jdbc:mysql://localhost/hibernate_extends_2</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">bjsxt</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<mapping resource="com/bjsxt/hibernate/extends.hbm.xml"/>
</session-factory>
</hibernate-configuration>
第四步:写测试代码:
public class ExtendsTest extends TestCase {
public void testSave1() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Pig pig = new Pig();
pig.setName("猪猪");
pig.setSex(true);
pig.setWeight(100);
session.save(pig);
Bird bird = new Bird();
bird.setName("鸟鸟");
bird.setSex(false);
bird.setHeight(50);
session.save(bird);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
/**
* 采用load,通过Pig查询
*/
public void testLoad1() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Pig pig = (Pig)session.load(Pig.class, 1);
System.out.println(pig.getName());
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
/**
* 采用load,通过Animal查询
*/
public void testLoad2() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Animal animal = (Animal)session.load(Animal.class, 1);
System.out.println(animal.getName());
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
/**
* 采用load,通过Animal查询
*/
public void testLoad3() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Animal animal = (Animal)session.load(Animal.class, 1);
//因为load默认只是lazy,因为我们看到的是Animal的代理对象
//所以通过instanceof是反应不出正真的对象类型的
//因此load在默认情况下是不支持多态查询的
if (animal instanceof Pig) {
System.out.println(animal.getName());
}else {
System.out.println("不是猪");
}
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
/**
* 采用load,通过Animal查询,将<class>标签上的lazy=false
*/
public void testLoad4() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Animal animal = (Animal)session.load(Animal.class, 1);
//可以正确的判断出Pig的类型,因为lazy=false,返回的是具体的Pig类型
//此时load支持多态查询
if (animal instanceof Pig) {
System.out.println(animal.getName());
}else {
System.out.println("不是猪");
}
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
/**
* 采用get,通过Animal查询
*/
public void testLoad5() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
//可以正确的判断出Pig的类型,因为返回的是具体的Pig类型
//get支持多态查询
Animal animal = (Animal)session.get(Animal.class, 1);
if (animal instanceof Pig) {
System.out.println(animal.getName());
}else {
System.out.println("不是猪");
}
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
/**
* 采用get,通过Animal查询
*/
public void testLoad6() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
// List animalList = session.createQuery("from Animal").list();
// for (Iterator iter = animalList.iterator(); iter.hasNext();) {
// Animal a = (Animal)iter.next();
// //能够正确的鉴别出正真的类型,hql是支持多态查询的
// if (a instanceof Pig) {
// System.out.println("是Pig");
// }else if (a instanceof Bird) {
// System.out.println("是bird");
// }
// }
List list = session.createQuery("from java.lang.Object").list();
for (Iterator iter=list.iterator(); iter.hasNext();) {
Object o = iter.next();
if (o instanceof Pig) {
System.out.println("是Pig");
}else if (o instanceof Bird) {
System.out.println("是bird");
}
}
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
}