站内搜索: 请输入搜索关键词

当前页面: 开发资料首页Eclipse 专题Eclipse快速上手Hibernate--4. 继承映射(3)

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

摘要: Eclipse快速上手Hibernate--4. 继承映射(3)
前两篇文章《Eclipse快速上手Hibernate--4. 继承映射(1) document.title="Eclipse快速上手Hibernate--4. 继承映射(1) - "+document.title 》和《继承映射(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
<table bordercolor="#000000" cellspacing="0" cellpadding="4" width="70%" border="0"><tr><td style="FONT-WEIGHT: bold; FONT-SIZE: 14px; BORDER-BOTTOM: rgb(51,51,204) thin inset; FONT-STYLE: italic; FONT-FAMILY: Courier New" valign="top" width="100%" bgcolor="#cccccc" height="16">
Student.java</td></tr><tr><td style="FONT-SIZE: 12px; BORDER-TOP-STYLE: none; BORDER-TOP-COLOR: rgb(236,233,216); FONT-FAMILY: Courier New" valign="top" width="100%" bgcolor="#e2e2e2">
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;

}

}
</td></tr></table>
· 子类Professor.java
<table bordercolor="#000000" cellspacing="0" cellpadding="4" width="70%" border="0"><tr><td style="FONT-WEIGHT: bold; FONT-SIZE: 14px; BORDER-BOTTOM: rgb(51,51,204) thin inset; FONT-STYLE: italic; FONT-FAMILY: Courier New" valign="top" width="100%" bgcolor="#cccccc" height="16">
Professor.java</td></tr><tr><td style="FONT-SIZE: 12px; BORDER-TOP-STYLE: none; BORDER-TOP-COLOR: rgb(236,233,216); FONT-FAMILY: Courier New" valign="top" width="100%" bgcolor="#e2e2e2">
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;

}

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

Professor.hbm.xml

<?xml version="1.0" encoding="GBK"?>

 hibernate-mapping PUBLIC

    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"

    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">



    

        

            

             

                  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.

              

            

        

        

        

       

            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.

       

    



Student.hbm.xml

<?xml version="1.0" encoding="GBK"?>

 hibernate-mapping PUBLIC

    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"

    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">



    

        

            

             

                  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.

              

            

        

        

        

       

            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.

       

    



· 同时在hibernate.cfg.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章)· Hibernate 简化继承映射· Mapping Objects to Relational Databases: O/R Mapping In Detail· Mapping objects to relational databases
下篇文章说说组件(Component)映射。


↑返回目录
前一篇: Eclipse快速上手Hibernate--5. 组件映射
后一篇: Eclipse插件配置