hibernate详解(二)----->>继承关系映射(一)
hibernate详解(二)---->>继承关系映射(一)
继承是面对对象编程中一个很重要的特征,在做面对对象的分析和设计时,经常会设计出具体继承关联的持久化类,如何把这些持久化类之间的继承关系映射到关系数据库上的问题已经解决,继承在对象模型中是 is a(是一个)的关系,但是在关系模型中,实体之间只有has a(有一个)的关系,也就是说,继承在对象模型和关系模型上是不匹配的。所幸的是,hibernate提供了3种常见的基继承映射方案。
第一种:整个继承层次一张表
Singer.java
package com.zxf.domain; /** 歌手抽象类 */ public abstract class Singer { private Long id; //对象标识符(OID) private String name; //名称 private String region; //歌手所属区域(如:华人、日韩、欧美等) private String description; //描述 public Singer(){} //无参数的构造方法 //以下为所有属性的getters和setters方法... }
SingleSinger.java
package com.zxf.domain; /** 单人歌手实体类 */ public class SingleSinger extends Singer { private Character gender; //性别 public SingleSinger(){} //无参数的构造方法 //以下为所有属性的getters和setters方法... }
Bands.java
package com.qiujy.domain; /** 乐队组合实体类 */ public class Bands extends Singer { private String leader; //主唱姓名 public Bands(){} //无参数的构造方法 //以下为所有属性的getters和setters方法... }
Singer.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!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.zxf.domain.Singer" table="singer"> <!-- 映射对象标识符 --> <id name="id" column="id" type="long"> <generator class="native" /> </id> <!-- 指定鉴别器字段,要放置在所有属性映射之前 --> <discriminator column="type" type="string" /> <!-- 映射普通属性 --> <property name="name"/> <property name="region"/> <property name="description"/> <!-- 映射子类,指定鉴别字段值 --> <subclass name="com.zxf.domain.SingleSinger" discriminator-value="S"> <!-- 映射本子类的属性 --> <property name="gender"/> </subclass> <!-- 映射子类,指定鉴别字段值 --> <subclass name="com.zxf.domain.Bands" discriminator-value="B"> <!-- 映射本子类的属性 --> <property name="leader"/> </subclass> </class> </hibernate-mapping>
配置文件 hibernate.cfg.xml
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- 数据库方言设置 --> <property name="hibernate.dialect"> org.hibernate.dialect.MySQLInnoDBDialect </property> <!-- 数据库连接参数设置 --> <property name="hibernate.connection.driver_class"> com.mysql.jdbc.Driver </property> <property name="hibernate.connection.url">jdbc:mysql:///hibernate</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">123</property> <!--实际操作数据库时是否显示SQL --> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <!--将数据库schema的DDL导出到数据库 --> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 以下定义实体类与数据库表的映像文件 --> <mapping resource="com/zxf/domain/Singer.hbm.xml" /> </session-factory> </hibernate-configuration>
下面写一个测试类来测试一下:
SingerTest.java
import java.util.List; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import com.zxf.domain.Bands; import com.zxf.domain.Singer; import com.zxf.domain.SingleSinger; /** * 继承映射测试 * @author z_xiaofei168 */ public class SingerTest { @SuppressWarnings("unchecked") public static void main(String[] args) { //根据hibernate的默认配置文件构建一个SessoinFactory实例 SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(); testAdd(sessionFactory); testQuery(sessionFactory); } public static void testAdd(SessionFactory sessionFactory) { //获取Session实例 Session session = sessionFactory.openSession(); //开启事务 session.beginTransaction(); SingleSinger singer = new SingleSinger(); singer.setName("周杰棍"); singer.setRegion("华人"); singer.setDescription("大舌头"); singer.setGender('男'); session.save(singer); Bands bands = new Bands(); bands.setName("花朵乐队"); bands.setRegion("日韩"); bands.setDescription("以口水歌为主"); bands.setLeader("大伟"); session.save(bands); //提交事务 session.getTransaction().commit(); //关闭Session session.close(); } public static void testQuery(SessionFactory sessionFactory) { //获取Session实例 Session session = sessionFactory.openSession(); //开启事务 session.beginTransaction(); List<Singer> singers = session.createQuery("from Singer").list(); for (Singer singer2 : singers) { if(singer2 instanceof SingleSinger){ SingleSinger ss = (SingleSinger)singer2; System.out.println("是单人歌手:" + ss.getName() + ",性别:" + ss.getGender()); }else if(singer2 instanceof Bands){ Bands ban = (Bands)singer2; System.out.println("是乐队组合:" + ban.getName() + ",主唱:" + ban.getLeader()); } } //提交事务 session.getTransaction().commit(); //关闭Session session.close(); } }
程序的运行结果如下所示: