您的位置:首页 > 编程语言 > Java开发

Eclipse快速上手Hibernate--4. 继承映射(2)

2005-04-11 23:41 686 查看
上篇文章《Eclipse快速上手Hibernate--4. 继承映射(1)
document.title="Eclipse快速上手Hibernate--4. 继承映射(1) - "+document.title
》中已经谈了每个类层次结构一个表(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 下篇文章会谈谈每个具体类一个表的策略。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: