标签:c style class blog code java
上篇文章讨论了多对多映射,在使用多对多映射时重点是使用<many-to-many>标签,并在标签的两端加入外键这样在生成关系时会创建两个关系之间的关系表,通过关系表来维护它们之间的关系,另外对于单向和双向的区别是在映射的哪一端添加标签的问题。在面向对象中很重要的一个特性就是继承,继承实现了代码的复用,而且Hibernate把基本上所有的对象模型进行了映射封装,其中就包括继承映射,接下来就详细讨论。
继承是面向对象很重要的特性,它实现了代码的服用,在关系模型中同样也有继承关系,这种继承关系其实可以看做是一种枚举关系,一种类型中可以枚举出很多子类型,这些子类型和父对象形成了继承关系,能够对其进行枚举的大部分都可以看做是一种继承映射,所以这种枚举关系可以看做是继承映射,例如动物就是一种抽象类,它是其它动物猪、猫等的父类,它们之间就是一种继承关系,如下图:
这种继承映射在转化为关系模型后会生成一张表,那么这张表是如何区分这两种类型的呢?用的是关系字段,需要在表中添加类型字段,使用关键字来标明对象的类型。所以上图中的对象模型对应的表结构如下:
在生成表结构时,需要添加对应的字段类型,所以需要在映射文件中添加对应的映射鉴别器,这里就需要使用discriminator-value属性。清单一:Animal类代码,只需要添加基本的属性。
package com.src.hibernate; public class Animal { //id号 private int id; public int getId() { return id; } public void setId(int id) { this.id = id; } //名称 private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } //性别 private boolean sex; public boolean isSex() { return sex; } public void setSex(boolean sex) { this.sex = sex; } }
package com.src.hibernate; public class Bird extends Animal { //高度 private int height; public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } } package com.src.hibernate; 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> <class name="com.src.hibernate.Animal" table="t_animal"> <id name="id"> <generator class="native"/> </id> <!-- 加入鉴别标签,且必须放在id后面 --> <discriminator column="type" /> <property name="name"/> <property name="sex" type="boolean"/> <subclass name="com.src.hibernate.Pig" discriminator-value="P"> <property name="weight"/> </subclass> <subclass name="com.src.hibernate.Bird" discriminator-value="B"> <property name="height"/> </subclass> </class> </hibernate-mapping>
生成的mysql数据库表中不仅会添加Animal的基本属性,而且会添加Pig和Bird的属性,因为在映射文件中使用<subclass>写出了所添加的属性,另外还添加了相应的鉴别器属性,所以在数据库中会添加对应的鉴别列,生成的表结构如下图:
public void testSave(){ Session session=null; try{ //创建session对象 session=HibernateUtils.getSession(); //开启事务 session.beginTransaction(); Pig pig=new Pig(); pig.setName("小猪猪"); pig.setSex(true); pig.setWeight(200); session.save(pig); Bird bird=new Bird(); bird.setName("xiaoniaoniao"); bird.setSex(true); bird.setHeight(100); session.save(bird); session.getTransaction().commit(); }catch(Exception e){ e.printStackTrace(); session.getTransaction().rollback(); }finally{ HibernateUtils.closeSession(session); } }
<?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> <class name="com.src.hibernate.Animal" table="t_animal" lazy="false"> <id name="id"> <generator class="native"/> </id> <!-- 加入鉴别标签,且必须放在id后面 --> <discriminator column="type" /> <property name="name"/> <property name="sex" type="boolean"/> <subclass name="com.src.hibernate.Pig" discriminator-value="P"> <property name="weight"/> </subclass> <subclass name="com.src.hibernate.Bird" discriminator-value="B"> <property name="height"/> </subclass> </class> </hibernate-mapping>
public void testLoad(){ Session session=null; try{ session=HibernateUtils.getSession(); session.beginTransaction(); Animal ani=(Animal)session.load(Animal.class,1); System.out.println(ani.getName()); //因为load默认支持lazy,所以我们看到的是Animal的代理 //所以采用了instanceof无法鉴别出真正的类型Pig //所以load在此情况下是不支持多态查询的 if(ani instanceof Pig){ System.out.println("我是小猪猪!"); }else{ System.out.println("我不是小猪猪!"); } session.getTransaction().commit(); }catch(Exception e){ e.printStackTrace(); session.getTransaction().rollback(); }finally{ HibernateUtils.closeSession(session); } }
public void testLoad5(){ Session session=null; try{ session=HibernateUtils.getSession(); session.beginTransaction(); List<Animal> list=session.createQuery("from Animal").list(); for(Iterator iter=list.iterator();iter.hasNext();){ Animal a=(Animal)iter.next(); if(a instanceof Pig){ System.out.println("我是小猪猪!"); }else{ System.out.println("我不是小猪猪!"); } } session.getTransaction().commit(); }catch(Exception e){ e.printStackTrace(); session.getTransaction().rollback(); }finally{ HibernateUtils.closeSession(session); } }
Hibernate: select animal0_.id as id0_, animal0_.name as name0_, animal0_.sex as sex0_, animal0_.weight as weight0_, animal0_.height as height0_, animal0_.type as type0_ from t_animal animal0_ 我是小猪猪! 我不是小猪猪! 我是小猪猪! 我不是小猪猪!
继承映射是对象模型中重要的关系映射,通过使用继承映射能够将继承关系转换为对应的关系表,在配置映射文件时需要使用<subclass>标签,另外还需要在标签中添加鉴别器属性来标明不同的类型,在操作读取时才能很快的鉴别出相应的类型。
【Hibernate步步为营】--继承映射详解,布布扣,bubuko.com
标签:c style class blog code java
原文地址:http://blog.csdn.net/zhang_xinxiu/article/details/27485119