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

前两篇文章《Eclipse快速上手Hibernate--4. 继承映射(1) 》和《继承映射(2)》 中已经谈了每个类层次结构一个表(table per class hierarchy)与每个子类一个表(table per subclass)的策略,这篇文章主要说的是每个具体类一个表(table per concrete class)。一些重复的部分这里就不说了,请参考前两篇文章。

 
   这个策略很简单,抽象的基类不参与映射,具体子类参与映射。
1. 创建项目 
·  继续沿用上篇文章中所建的Java项目:InheritanceMapping。 
 
 
2. 编写类文件
 
·  新建一个类,包名:javamxj.inheritance.two,类名:Person。然后在生成的代码中添加变量,再利用“生成 Getter 和 Setter”,具体方式同《Eclipse快速上手Hibernate--1. 入门实例 》文章中的编辑User.java的方式一样。
·  这个类是父类,要注意,这里并没有将父类映射成表。

Person.java

/*
* Hibernate - 继承映射(每个具体类一个表)
* 创建日期 2005-4-9
* @author javamxj(分享java快乐)
* @link Blog: htpp://javamxj.mblogger.cn
* htpp://blog.csdn.net/javamxj/
*/
package javamxj.inheritance.three;


public abstract class Person {
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;
}
}
 
 
·  子类Student.java
Student.java
package javamxj.inheritance.three;

/**
* @hibernate.class
* table="Student"
*/
public class Student extends Person {
private String studentNumber;

/**
* @hibernate.property
* length = "24"
*/
public String getStudentNumber() {
return studentNumber;
}

public void setStudentNumber(String studentNumber) {
this.studentNumber = studentNumber;
}
}
 
·  子类Professor.java
Professor.java
package javamxj.inheritance.three;

/**
* @hibernate.class
* table="Professor"
*/
public class Professor extends Person {
private int salary;

/**
* @hibernate.property
*/
public int getSalary() {
return salary;
}

public void setSalary(int salary) {
this.salary = salary;
}
}
· 这两个子类都很简单,跟平常的写法相同,只是简单的映射成一个表。
 
· 好了,这时整个项目的结构如下:
 
 
 
 
3. 运行任务
 
·  双击“generate-hbm”任务,会发现在包中多了Professor.hbm.xml和Student.hbm.xml两个文件。如果没有,按 F5键刷新一下(这里建议打开Eclipse的“首选项”对话框,在“工作台”中勾选“自动刷新工作空间”和“在构建之前自动保存”这两项,这样以后不用 每次都刷新了)。
·  这是通过两个子类所生成的映射文件,注意没有生成父类的映射文件,而且这两个子类的映射文件都已经包含了父类的属性。

Professor.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.three.Professor"
table="Professor"
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-Professor.xml
containing the additional parameters and place it in your merge dir.
-->
</generator>
</id>

<property
name="salary"
type="int"
update="true"
insert="true"
access="property"
column="salary"
/>

<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-Professor.xml
containing the additional properties and place it in your merge dir.
-->

</class>

</hibernate-mapping>
 

Student.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.three.Student"
table="Student"
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-Student.xml
containing the additional parameters and place it in your merge dir.
-->
</generator>
</id>

<property
name="studentNumber"
type="java.lang.String"
update="true"
insert="true"
access="property"
column="studentNumber"
length="24"
/>

<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-Student.xml
containing the additional properties and place it in your merge dir.
-->

</class>

</hibernate-mapping>
 
 
· 同时在hibernate.cfg.xml文件中会自动添加这两个映射文件信息:
<mapping resource="javamxj/inheritance/three/Professor.hbm.xml"/>
<mapping resource="javamxj/inheritance/three/Student.hbm.xml"/>
 
· 先运行MySQL,然后双击“schemaexport”任务,在项目根目录下,会更新“schema-export.sql”文件。
打开这个文件,会发现添加了以下一些语句。 
create table Student (
   ID bigint not null,
   studentNumber varchar(24),
   name varchar(24),
   primary key (ID)
)
create table Professor (
   ID bigint not null,
   salary integer,
   name varchar(24),
   primary key (ID)
)
 
·  切换到数据库中,会发现已经自动产生了数据表Student、Professor。
 
 
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.three;

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();

Student student = new Student();
student.setName("张三");
student.setStudentNumber("1234554321");
sess.save(student);

Professor professor = new Professor();
professor.setName("李四");
professor.setSalary(4300);
sess.save(professor);

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 person = sess.find("from " + Person.class.getName());
for (Iterator it = person.iterator(); it.hasNext();) {
Person p = (Person) it.next();
System.out.println("人员 '" + p.getName() + "' its class is: "
+ p.getClass().getName());

}

tx.commit();
} catch (HibernateException e) {
if (tx != null)
tx.rollback();
throw e;
} finally {
sess.close();
}
}

}
 
·  运行这个类,控制台输出如下:
 
·  同时,数据表中生成如下数据:
 
 
 
小结:  
● 优点:
· 报表操作实现简单:表中包含了具体子类的所有信息。

● 缺点:
· 类的修改会导致相对应的表及其子类所对应表的更改。
· 当含有多重子类时,会造成在数据库表格中生成重复的字段。
 
 
参考:
· HIBERNATE - 符合Java习惯的关系数据库持久化(第8章)
 
  下篇文章说说组件(Component)映射。
AddThis Social Bookmark Button

相关文档(Relevant Entries)
Eclipse快速上手Hibernate-利用Hbm映射文件开发[转]
从hbm文件生成ddl
Hibernate代码生成工具 设计全攻略
Struts+Hibernate模板开发笔记
Struts+Spring+Hibernate练习(完整)
MyEclipse+struts+Hibernate配置开发
使用MiddleGen 产生hibernate的数据库表映射文件
使用Middlegen简化Hibernate开发
Posted on December 4, 2006 9:23 PM | | | | TrackBacks (0)

引用地址(TRACKBACKS)
 
TrackBack URL for this entry:
http://www.wujianrong.com/mt-tb.cgi/4202

发布评论(ADD YOUR COMMENTS)
 
感谢您参与评论;发表您的意见时请保持文章的相关性;不相关的或是单纯宣传的内容可能会被删掉。您的E-mail只是用来确认您发表的文章,不会出现在网页上。
Please keep your comments relevant to this blog entry. Email addresses are never displayed, but they are required to confirm your comments.

称呼(Name):      记住我的个人信息(Remember)
邮箱(Email):
网址(URL):
评论(Add your comments):

相关内容