Hibernate学习(七)---【继承映射--每棵继承树映射成一张表】
每棵继承树映射成一张表
1、理解如何映射
因为类继承树肯定是对应多个类,要把多个类的信息存放在一张表中,必须有某种机制来区分哪些记录是属于哪个类的。
这种机制就是,在表中添加一个字段,用这个字段的值来进行区分。用hibernate实现这种策略的时候,有如下步骤:
父类用普通的<class>标签定义
在父类中定义一个discriminator,即指定这个区分的字段的名称和类型
如:<discriminator column=”XXX” type=”string”/>
子类使用<subclass>标签定义,在定义subclass的时候,需要注意如下几点:
Subclass标签的name属性是子类的全路径名
在Subclass标签中,用discriminator-value属性来标明本子类的discriminator字段(用来区分不同类的字段)
的值Subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),也可以与class标
签平行。 当subclass标签的定义与class标签平行的时候,需要在subclass标签中,添加extends属性,里面的值
是父类的全路径名称。子类的其它属性,像普通类一样,定义在subclass标签的内部。
2、理解如何存储
存储的时候hibernate会自动将鉴别字段值插入到数据库中,在加载数据的时候,hibernate能根据这个鉴别值
正确的加载对象
多态查询:在hibernate加载数据的时候能鉴别出正真的类型(instanceOf)
get支持多态查询
load只有在lazy=false,才支持多态查询
hql支持多态查询
package
com.bjsxt.hibernate;
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 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;
}
}
package
com.bjsxt.hibernate;
public class Bird extends Animal {
private int height;
public int getHeight() {
return height;
}
public void setHeight( int height) {
this .height = height;
}
}
public class Bird extends Animal {
private int height;
public int getHeight() {
return height;
}
public void setHeight( int height) {
this .height = height;
}
}
package
com.bjsxt.hibernate;
public class Pig extends Animal {
private int weight;
public int getWeight() {
return weight;
}
public void setWeight( int weight) {
this .weight = weight;
}
}
public class Pig extends Animal {
private int weight;
public int getWeight() {
return weight;
}
public void setWeight( int weight) {
this .weight = weight;
}
}
<?
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.bjsxt.hibernate" >
< 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 >
<! DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
< hibernate-mapping package ="com.bjsxt.hibernate" >
< 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 >
package
com.bjsxt.hibernate;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Session;
import junit.framework.TestCase;
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);
}
}
}
import java.util.Iterator;
import java.util.List;
import org.hibernate.Session;
import junit.framework.TestCase;
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);
}
}
}