hibernate学习笔记第14讲-继承映射
?
继承映射:
?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支持多态查询???
映射关系:
<hibernate-mapping package="com.bjsxt.hibernate">
<classname="Animal" table="t_animal" lazy="false">
?????????? <idname="id">
??????????????????? <generatorstyle="margin-left: 18.0pt; text-align: left;">?????????? </id>
//鉴别器,必须放在id后面??????????
<discriminator column="type"type="string"/>
?????????? <propertyname="name"/>
?????????? <propertyname="sex"/>
//鉴别值:discriminator-value
?????????? <subclassname="Pig" discriminator-value="P">
??????????????????? <propertyname="weight"/>
?????????? </subclass>
?????????? <subclassname="Bird" discriminator-value="B">
??????????????????? <propertyname="height"/>
?????????? </subclass>
</class>
</hibernate-mapping>
加载:
/**
?* 采用load,通过Pig查询
?*/
session.beginTransaction();
??????????????????? Pig pig =(Pig)session.load(Pig.class, 1);
??????????????????? System.out.println(pig.getName());
??????????????????? session.getTransaction().commit();
/**
?* 采用load,通过Animal查询
?*/
???????? session.beginTransaction();
??????????????????? Animalanimal = (Animal)session.load(Animal.class, 1);
??????????????????? System.out.println(animal.getName());
??????????????????? session.getTransaction().commit();
/**
?* 采用load,通过Animal查询,不支持多态查询
多态查询:在hibernate加载数据时,能鉴别出真正的类型(instanceof)
?*/
session.beginTransaction();
??????????????????? Animalanimal = (Animal)session.load(Animal.class, 1);
?????????? ???????? //因为load默认只是lazy,因为我们看到的是Animal的代理对象
??????????????????? //所以通过instanceof是反应不出正真的对象类型的
??????????????????? //因此load在默认情况下是不支持多态查询的
??????????????????? if (animalinstanceof Pig) {
???????????????????????????? System.out.println(animal.getName());
??????????????????? }else {
???????????????????????????? System.out.println("不是猪");
??????????????????? }
??????????????????? session.getTransaction().commit();
/**
?* 采用load,通过Animal查询,将<class>标签上的lazy=false,load失效后支持多态查询
?*/
session.beginTransaction();
??????????????????? Animalanimal = (Animal)session.load(Animal.class, 1);
???????? //可以正确的判断出Pig的类型,因为lazy=false,返回的是具体的Pig类型
?????????? //此时load支持多态查询
??????????????????? if (animalinstanceof Pig) {
???????????????????????????? System.out.println(animal.getName());
??????????????????? }else {
???????????????????????????? System.out.println("不是猪");
??????????????????? }
??????????????????? session.getTransaction().commit();
/**
?* 采用get,通过Animal查询,能够支持多态查询
?*/
session.beginTransaction();
?????????? ???????? //可以正确的判断出Pig的类型,因为返回的是具体的Pig类型
??????????????????? //get支持多态查询
??????????????????? Animalanimal = (Animal)session.get(Animal.class, 1);
??????????????????? if (animalinstanceof Pig) {
???????????????????????????? System.out.println(animal.getName());
??????????????????? }else {
???????????????????????????? System.out.println("不是猪");
??????????????????? }
??????????????????? session.getTransaction().commit();
???????? /**
?* 查询所有实体对象,因为支持多态查询
?*/
session.beginTransaction();
??????????????????? List list =session.createQuery("from java.lang.Object").list();
??????????????????? for(Iterator iter=list.iterator(); iter.hasNext();) {
???????????????????????????? Objecto = iter.next();
???????????????????????????? if(o instanceof Pig) {
?????????????????????????????????????? System.out.println("是Pig");
???????????????????????????? }elseif (o instanceof Bird) {
?????????????????????????????????????? System.out.println("是bird");
???????????????????????????? }
??????????????????? }
??????????????????? session.getTransaction().commit();
?映射关系:
<hibernate-mapping package="com.bjsxt.hibernate">
????? <classname="Animal" table="t_animal">
?????????????? <idname="id">
???????????????????????? <generatorstyle="margin-left: 28.45pt; text-align: left;">?????????????? </id>
????? ???????? <property name="name"/>
?????????????? <propertyname="sex"/>
?????????????? <joined-subclassname="Pig" table="t_pig">
???????????????????????? <keycolumn="pid"/>
???????????????????????? <propertyname="weight"/>
?????????????? </joined-subclass>
?????????????? <joined-subclassname="Bird" table="t_bird">
???????????????????????? <keycolumn="bid"/>
???????????????????????? <propertyname="height"/>
?????????????? </joined-subclass>
????? </class>
</hibernate-mapping>
?<hibernate-mappingpackage="com.bjsxt.hibernate">
// abstract="true"抽象,不会生成表
<classname="Animal" abstract="true">
?????????? <id name="id">
//不能使用native,自增,因为pig、bird两个表中的id不能相同
??????????????????? <generatorstyle="margin-left: 18.0pt; text-align: left;">?????????? </id>
?????????? <propertyname="name"/>
?????????? <propertyname="sex"/>
?????????? <union-subclassname="Pig" table="t_pig">
??????????????????? <propertyname="weight"/>
?????????? </union-subclass>
?????????? <union-subclassname="Bird" table="t_bird">
??????????????????? <propertyname="height"/>
?????????? </union-subclass>
</class>
</hibernate-mapping>
?
?