Eclipse快速上手Hibernate--4. 继承映射(2)(摘自javamxj的blog)

来源:互联网 发布:java 动态生成流程图 编辑:程序博客网 时间:2024/05/16 05:03
上篇文章《Eclipse快速上手Hibernate--4. 继承映射(1) 》中已经谈了每个类层次结构一个表(table per class hierarchy)的策略,这篇文章主要说的是每个子类一个表(table per subclass)的策略。一些重复的部分这里就不说了,请参考上篇文章。
 
1. 创建项目 
·  继续沿用上篇文章中所建的Java项目:InheritanceMapping。 
 
 
2. 编写类文件
 
·  新建一个类,包名:javamxj.inheritance.two,类名:Animal。然后在生成的代码中添加变量,再利用“生成 Getter 和 Setter”,具体方式同《Eclipse快速上手Hibernate--1. 入门实例 》文章中的编辑User.java的方式一样。
·  这个类是父类,只是生成一个简单的表。

Vehicle.java

/* * Hibernate - 继承映射(每个子类一个表) * 创建日期 2005-4-9 * @author javamxj(分享java快乐) * @link  Blog: htpp://javamxj.mblogger.cn   *              htpp://blog.csdn.net/javamxj/  */package javamxj.inheritance.two;/** * @hibernate.class */public class Vehicle {private Long id;private String name;/** * @hibernate.id  *   column="ID"  *   generator-class="hilo"  *   unsaved-value="null" */public Long getId() {return id;}public void setId(Long id) {this.id = id;}/** * @hibernate.property  *   length = "24" */public String getName() {return name;}public void setName(String name) {this.name = name;}}
 
·  子类Car.java
Car.java
package javamxj.inheritance.two;/** * @hibernate.joined-subclass * @hibernate.joined-subclass-key  *   column="id" */public class Car extends Vehicle {private String seat;/** * @hibernate.property  *   column = "载客"  *   length = "24" */public String getSeat() {return seat;}public void setSeat(String seat) {this.seat = seat;}}
 
·  子类Truck.java
Truck.java
package javamxj.inheritance.two;/** * @hibernate.joined-subclass * @hibernate.joined-subclass-key  *   column="id" */public class Truck extends Vehicle {private String load;/** * @hibernate.property  *   column = "载重"  *   length = "24" */public String getLoad() {return load;}public void setLoad(String load) {this.load = load;}}
· 这两个子类都很简单,注意添加的hibernate.joined-subclass的标记。
 
· 好了,这时整个项目的结构如下:
 
 
3. 运行任务
 
·  双击“generate-hbm”任务,会发现在包中多了一个Vehicle.hbm.xml文件。如果没有,按F5键刷新一下(这里建议打开Eclipse的“首选项”对话框,在“工作台”中勾选“自动刷新工作空间”和“在构建之前自动保存”这两项,这样以后不用每次都刷新了)。

Vehicle.hbm.xml

<?xml version="1.0" encoding="GBK"?><!DOCTYPE hibernate-mapping PUBLIC    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"     "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"><hibernate-mapping>    <class        name="javamxj.inheritance.two.Vehicle"        dynamic-update="false"        dynamic-insert="false"        select-before-update="false"        optimistic-lock="version"    >        <id            name="id"            column="ID"            type="java.lang.Long"            unsaved-value="null"        >            <generator class="hilo">              <!--                    To add non XDoclet generator parameters, create a file named                   hibernate-generator-params-Vehicle.xml                   containing the additional parameters and place it in your merge dir.               -->             </generator>        </id>        <property            name="name"            type="java.lang.String"            update="true"            insert="true"            access="property"            column="name"            length="24"        />        <!--            To add non XDoclet property mappings, create a file named                hibernate-properties-Vehicle.xml            containing the additional properties and place it in your merge dir.        -->        <joined-subclass            name="javamxj.inheritance.two.Truck"            dynamic-update="false"            dynamic-insert="false"        >        <key            column="id"        />        <property            name="load"            type="java.lang.String"            update="true"            insert="true"            access="property"            column="载重"            length="24"        />        </joined-subclass>        <joined-subclass            name="javamxj.inheritance.two.Car"            dynamic-update="false"            dynamic-insert="false"        >        <key            column="id"        />        <property            name="seat"            type="java.lang.String"            update="true"            insert="true"            access="property"            column="载客"            length="24"        />        </joined-subclass>    </class></hibernate-mapping>
· 重点是看看“joined-subclass”标签。
 
· 同时在hibernate.cfg.xml文件中会自动添加一个映射文件信息:
<mapping resource="javamxj/inheritance/two/Vehicle.hbm.xml"/>
 
 
·  先运行MySQL,然后双击“schemaexport”任务,在项目根目录下,会更新“schema-export.sql”文件。
打开这个文件,会发现添加了以下一些语句。
create table Car (
   id bigint not null,
   载客 varchar(24),
   primary key (id)
)
create table Truck (
   id bigint not null,
   载重 varchar(24),
   primary key (id)
)
create table Vehicle (
   ID bigint not null,
   name varchar(24),
   primary key (ID)
)
 
·  切换到数据库中,会发现已经自动产生了数据表Car、Truck、Vehicle。
 
· 将数据表与映射文件Vehicle.hbm.xml对照看看,可以更好的理解每个子类一个表的策略。
 
 
4. 测试程序
 
·  好了,在包javamxj.inheritance.two下新建一个Demo.java类,很简单,前半部分是添加数据,后半部分是简单的测试。

Demo.java

/* * Hibernate - 继承映射(每个子类一个表) * 创建日期 2005-4-9 * @author javamxj(分享java快乐) * @link  Blog: htpp://javamxj.mblogger.cn   *              htpp://blog.csdn.net/javamxj/  */package javamxj.inheritance.two;import java.util.Iterator;import java.util.List;import net.sf.hibernate.HibernateException;import net.sf.hibernate.Session;import net.sf.hibernate.SessionFactory;import net.sf.hibernate.Transaction;import net.sf.hibernate.cfg.Configuration;public class Demo {public static void main(String[] args) {try {new Demo();} catch (HibernateException he) {he.printStackTrace();}}public Demo() throws HibernateException {SessionFactory sf = new Configuration().configure().buildSessionFactory();Session sess = sf.openSession();Transaction tx = null;try {tx = sess.beginTransaction();Car car = new Car();car.setName("奇瑞QQ");car.setSeat("4人");sess.save(car);Truck truck = new Truck();truck.setName("一汽解放");truck.setLoad("10吨");sess.save(truck);tx.commit();} catch (HibernateException e) {if (tx != null)tx.rollback();throw e;} finally {sess.close();}sess = sf.openSession();tx = null;try {tx = sess.beginTransaction();List pets = sess.find("from " + Vehicle.class.getName());for (Iterator it = pets.iterator(); it.hasNext();) {Vehicle vehicle = (Vehicle) it.next();System.out.println("车型 " + vehicle.getName()+ " its class is: " + vehicle.getClass().getName());}tx.commit();} catch (HibernateException e) {if (tx != null)tx.rollback();throw e;} finally {sess.close();}}}
 
·  运行这个类,控制台输出如下:
 
·  同时,数据表中生成如下数据:
 
 
 
 
小结:  
● 优点:
· 与面向对象的概念的一致性最好。对多态的支持最好,对于对象所可能充当的角色仅需要在相应的表中保存
记录。
· 易于修改基类和增加新的类。
· 这种映射几乎有最佳的空间节约性。唯一的容易就是额外的OID,来连接不同的层级层次。

● 缺点:
· 数据库中存在大量的表。
· 访问数据的时间较长。在读写相关的任务上,这种映射方式相当费资源,这个代价还随着继承层次的增多而增大。
· 对报表的支持较差,除非定义视图。
 
参考:
· HIBERNATE - 符合Java习惯的关系数据库持久化(第8章)
· Hibernate 简化继承映射
· Mapping Objects to Relational Databases: O/R Mapping In Detail
· Mapping objects to relational databases
 
  下篇文章会谈谈每个具体类一个表的策略。
原创粉丝点击