【HIbernate框架学习】:Hibernate对象继承关系映射(二)
2016-12-12 21:39
661 查看
每个具体子类一张表
这种策略是使用union-subclass标签来定义子类的。每个子类对应一张表,而且这个表的信息是完备的,即包含了所有从父类继承下来的属性映射的字段(这就是它跟joined-subclass的不同之处,joined-subclass定义的子类的
表,只包含子类特有属性映射的字段)。
实现这种策略的时候,有如下步骤:
父类用普通<class>标签定义即可;
子类用<union-subclass>标签定义,在定义union-subclass的时候,需要注意如下几点:
union-subclass标签不再需要包含key标签(与joined-subclass不同);
union-subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),也可以与
class标签平行。 当Union-subclass标签的定义与class标签平行的时候,需要在Union-subclass标签中,添加
extends属性,里面的值是父类的全路径名称。
子类的其它属性,像普通类一样,定义在Union-subclass标签的内部。这个时候,虽然在union-subclass里面定
义的只有子类的属性,但是因为它继承了父类,所以,不需要定义其它的属性,在映射到数据库表的时候,依然包含
了父类的所有属性的映射字段。
我们来看例子,这个类继承树的类图以及数据表:
代码实现:
Animal实体类:
package com.demo.domain; 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; } }
Pig实现类:
package com.demo.domain; public class Pig extends Animal { private int weight; public int getWeight() { return weight; } public void setWeight(int weight) { this.weight = weight; } }
Bird实体类:
package com.demo.domain; public class Bird extends Animal { private int height; public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } }
对象关系映射文件:
<?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.demo.domain"> <class name="Animal" table="t_animal" abstract="true"> <id name="id"> <generator class="assigned"/> </id> <property name="name"/> <property name="sex"/> <union-subclass name="Pig" table="t_pig"> <property name="weight"/> </union-subclass> <union-subclass name="Bird" table="t_bird"> <property name="height"/> </union-subclass> </class> </hibernate-mapping>
测试类:
package com.demo.test; import java.util.Iterator; import java.util.List; import org.hibernate.Session; import com.demo.domain.Animal; import com.demo.domain.Bird; import com.demo.domain.HibernateUtils; import com.demo.domain.Pig; 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.setId(1); pig.setName("小猪猪"); pig.setSex(true); pig.setWeight(200); session.save(pig); Bird bird = new Bird(); bird.setId(2); bird.setName("小鸟鸟"); bird.setSex(false); bird.setHeight(100); 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 a = (Animal)session.load(Animal.class, 1); System.out.println(a.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 a = (Animal)session.load(Animal.class, 1); //因为load默认支持lazy,所以我们看到的是Animal的代理 //所以采用instanceof无法鉴别出真正的类型Pig //所load在此情况下是不支持多态查询的 //多态查询:hibernate在加载数据的时候,能够采用instancof鉴别出其真正的类型 if (a instanceof Pig) { System.out.println(a.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 a = (Animal)session.load(Animal.class, 1); //可以正确判断出其真正的类型 //因为映射文件中lazy设置为false,返回的不再是代理类而是真正的类型 //所以可以鉴别出来 //此种情况下load是支持多态查询的 if (a instanceof Pig) { System.out.println(a.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(); Animal a = (Animal)session.get(Animal.class, 1); //可以鉴别出其真正的类型,因为get返回的就是具体类 //get是支持多态查询的 if (a instanceof Pig) { System.out.println(a.getName()); }else { System.out.println("不是猪!"); } session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } } /** * 采用hql查询Animal */ @SuppressWarnings("unchecked") public void testLoad6() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); List<Animal> animalList = session.createQuery("from Animal").list(); for (Iterator<Animal> iter=animalList.iterator(); iter.hasNext();) { Animal a = (Animal)iter.next(); //采用hql查询返回的是真正的类型,所以hql支持多态查询 if (a instanceof Pig) { System.out.println(a.getName()); }else if (a instanceof Bird) { System.out.println(a.getName()); } } session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } } /** * 采用hql查询Animal */ @SuppressWarnings("rawtypes") public void testLoad7() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); 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(o); }else if (o instanceof Bird) { System.out.println(o); } } session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } } }
testSave1()方法:
控制台输出:
数据库显示:
testLoad1()方法:
控制台输出:
testLoad2()方法:
控制台输出:
testLoad3()方法:
控制台输出:
testLoad4()方法:
控制台输出:
testLoad5()方法:
控制台输出:
testLoad6()方法:
控制台输出:
testLoad7()方法:
控制台输出:
在保存对象的时候id不能重复(不能使用数据库的自增方式生成主键)
相关文章推荐
- 【HIbernate框架学习】:Hibernate对象继承关系映射(三)
- 【HIbernate框架学习】:Hibernate对象继承关系映射(一)
- 【HIbernate框架学习】:Hibernate对象关系映射之一对一关联映射(一)
- 【HIbernate框架学习】:Hibernate对象关系映射之一对一关联映射(二)
- 【HIbernate框架学习】:Hibernate对象关系映射之双向一对多关联映射
- 【HIbernate框架学习】:Hibernate对象关系映射之单向一对多关联映射
- 【HIbernate框架学习】:Hibernate对象关系映射之单向多对多关联映射
- 【HIbernate框架学习】:Hibernate对象关系映射之单向多对一关联映射
- 【HIbernate框架学习】:Hibernate对象关系映射之双向多对多关联映射
- [原创]java WEB学习笔记77:Hibernate学习之路---Hibernate 版本 helloword 与 解析,.环境搭建,hibernate.cfg.xml文件及参数说明,持久化类,对象-关系映射文件.hbm.xml,Hibernate API (Configuration 类,SessionFactory 接口,Session 接口,Transaction(事务))
- Hibernate对象继承关系映射优缺点统计
- Hibernate框架学习(三) 关系映射
- Hibernate 框架对象/关系(ORM)映射文件
- Hibernate框架学习(三) 关系映射
- Java的Hibernate框架中的继承映射学习教程
- Hibernate框架学习(三) 关系映射
- [原]Java web学习系列之 Java web开发中的Hibernate对象关系映射框架
- Hibernate学习---第八节:继承关系的映射配置
- Hibernate框架学习(三) 关系映射
- 【Hibernate学习笔记】映射继承关系