`

[原]Hibernate继承映射-具体类映射为数据库表

阅读更多

[标题]:[原]Hibernate继承映射-具体类映射为数据库表
[时间]:2009-6-21
[摘要]:每一个具体子类映射成单个数据库表,而抽象基类不参与映射。优点:数据操作实现简单,每个表中都包含自己所需要的具体子类的所有信息,减少了多表关联操作时的性能消耗。缺点:类的修改会导致相对应的表及其子类所对应表的更改。不支持多态查询。应用:适合在类层次结构上有一定数量的抽象类的情况下使用。
[关键字]:Hibernate,ORM,关联,继承,持久化,映射,Abstract
[环境]:MyEclipse7,Hibernate3.2,MySQL5.1
[作者]:Winty (wintys@gmail.com) http://www.blogjava.net/wintys

[正文]:
    每一个具体子类映射成单个数据库表,而抽象基类不参与映射。
优点:数据操作实现简单,每个表中都包含自己所需要的具体子类的所有信息,减少了多表关联操作时的性能消耗。

缺点:
    类的修改会导致相对应的表及其子类所对应表的更改。不支持多态查询。

应用:
    适合在类层次结构上有一定数量的抽象类的情况下使用。
    
    例:学校管理系统中的实体关系:



 
    【图:department.jpg】

1、概述
a.实体类
public class Department {
    ......
    //由于Person类没有被映射,所以无法实现Department到Person的关联
    ......
}

public abstract class Person {
    ......
    private Department department;
    ......
}

public class Student extends Person {
    ......
}

public class Teacher extends Person {
    ......
}

b.数据库表
    具体子类Student和Teacher分别映射成一张表,各自的表中都包含从父类继承来的属性。

c.配置文件
由于Person类没有被映射,所以无法映射Person到Department的关联,只能由子类Student和Teacher实现映射。

Student.hbm.xml:
包含父类属性的映射
......
<many-to-one name="department"
            unique="true"
            column="dept"
            class="wintys.hibernate.inheritance.concrete.Department"/>
......


Teacher.hbm.xml:
包含父类属性的映射
......
<many-to-one name="department"
            unique="true"
            column="dept"
            class="wintys.hibernate.inheritance.concrete.Department"/>
......

2、实体类:
Department.java:

package wintys.hibernate.inheritance.concrete;

/**
 *
 * @version 2009-06-20
 * @author Winty (wintys@gmail.com)
 *
 */
public class Department {
    private Integer id;
    private String name;
    private String desc;
    
    
    public Department(){
        
    }
    
    public Department(String name , String desc){
        this.name = name;
        this.desc = desc;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDesc() {
        return desc;
    }
    public void setDesc(String desc) {
        this.desc = desc;
    }
}



Person.java:

package wintys.hibernate.inheritance.concrete;

/**
 *
 * @version 2009-06-20
 * @author Winty (wintys@gmail.com)
 *
 */
public abstract class Person {
    private Integer id;
    private String name;
    private Department department;
    
    public Person(){
    }
    
    public Person(String name){
        this.name = name;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Department getDepartment() {
        return department;
    }
    public void setDepartment(Department department) {
        this.department = department;
    }
}



Student.java:

package wintys.hibernate.inheritance.concrete;

/**
 *
 * @version 2009-06-20
 * @author Winty (wintys@gmail.com)
 *
 */
public class Student extends Person {
    private String studentMajor;
    
    public Student(){
        
    }
    
    public Student(String name , String major){
        super(name);
        this.studentMajor = major;
    }

    public String getStudentMajor() {
        return studentMajor;
    }

    public void setStudentMajor(String studentMajor) {
        this.studentMajor = studentMajor;
    }
}



Teacher.java:

package wintys.hibernate.inheritance.concrete;

/**
 *
 * @version 2009-06-20
 * @author Winty (wintys@gmail.com)
 *
 */
public class Teacher extends Person {
    private Float teacherSalary;

    public Teacher(){
        
    }
    
    public Teacher(String name , Float teacherSalary){
        super(name);
        this.teacherSalary = teacherSalary;
    }
    
    public Float getTeacherSalary() {
        return teacherSalary;
    }

    public void setTeacherSalary(Float teacherSalary) {
        this.teacherSalary = teacherSalary;
    }
}




3、数据库表:



 
【图:concret_db.jpg】

db.sql:

-- Author:Winty (wintys@gmail.com)
-- Date:2009-06-20
-- http://www.blogjava.net/wintys

-- Department
CREATE TABLE mydepartment(
    id      INT(4) NOT NULL,
    name    VARCHAR(100),
    descs  VARCHAR(100),
    PRIMARY KEY(id)
);

-- Student
CREATE TABLE mystudent(
    id              INT(4) NOT NULL,
    name            VARCHAR(100),
    dept            INT(4),-- 从Person继承了与Department的关联
    studentMajor    VARCHAR(100),
    PRIMARY KEY(id),
    CONSTRAINT FK_dept_s FOREIGN KEY(dept) REFERENCES mydepartment(id)
);

-- Teacher
CREATE TABLE myteacher(
    id              INT(4) NOT NULL,
    name            VARCHAR(100),
    dept            INT(4), -- 从Person继承了与Department的关联
    teacherSalary   FLOAT(7,2),
    PRIMARY KEY(id),
    CONSTRAINT FK_dept_t FOREIGN KEY(dept) REFERENCES mydepartment(id)
);


4、映射文件:



 
【图:concrete_mapping.jpg】

Department.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">
<!--
    Mapping file autogenerated by MyEclipse Persistence Tools
-->

<hibernate-mapping>
    <class name="wintys.hibernate.inheritance.concrete.Department" table="mydepartment" catalog="db">
        <id name="id" type="int">
            <column name="id" not-null="true"/>
            <generator class="increment" />
        </id>
        <property name="name" />
        <property name="desc" type="string" column="descs"/>
    </class>
</hibernate-mapping>



Student.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">
<!--
    Mapping file autogenerated by MyEclipse Persistence Tools
-->

<hibernate-mapping>
    <class name="wintys.hibernate.inheritance.concrete.Student" table="mystudent" catalog="db">
        <id name="id" type="int">
            <column name="id" not-null="true"/>
            <generator class="increment" />
        </id>
        <property name="name" />
        <property name="studentMajor" />
        
        <many-to-one name="department"
                    unique="true"
                    column="dept"
                    class="wintys.hibernate.inheritance.concrete.Department"/>
    </class>
</hibernate-mapping>



Teacher.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">
<!--
    Mapping file autogenerated by MyEclipse Persistence Tools
-->

<hibernate-mapping>
    <class name="wintys.hibernate.inheritance.concrete.Teacher" table="myteacher" catalog="db">
        <id name="id" type="int">
            <column name="id" not-null="true"/>
            <generator class="increment" />
        </id>
        <property name="name" />
        <property name="teacherSalary" type="float"/>
        
        <many-to-one name="department"
                    unique="true"
                    column="dept"
                    class="wintys.hibernate.inheritance.concrete.Department"/>
    </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">

<!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration>

<session-factory>
    <property name="connection.username">root</property>
    <property name="connection.url">
        jdbc:mysql://localhost:3306/db?useUnicode=true&amp;characterEncoding=utf-8
    </property>
    <property name="dialect">
        org.hibernate.dialect.MySQLDialect
    </property>
    <property name="myeclipse.connection.profile">MySQLDriver</property>
    <property name="connection.password">root</property>
    <property name="connection.driver_class">
        com.mysql.jdbc.Driver
    </property>
    <property name="show_sql">true</property>
    <mapping
        resource="wintys/hibernate/inheritance/concrete/Department.hbm.xml" />
    <mapping
        resource="wintys/hibernate/inheritance/concrete/Student.hbm.xml" />
    <mapping
        resource="wintys/hibernate/inheritance/concrete/Teacher.hbm.xml" />

</session-factory>

</hibernate-configuration>



4、使用测试:
DAO.java:

package wintys.hibernate.inheritance.concrete;

import java.util.List;

public interface DAO {
    public void insert();
    public <T> List<T> select(String hql);
}



DAOBean.java:

package wintys.hibernate.inheritance.concrete;

import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 *
 * @version 2009-06-20
 * @author Winty (wintys@gmail.com)
 *
 */
public class DAOBean implements DAO {

    @Override
    public void insert() {
        Transaction tc = null;
        try{
            Department dept = new Department("college of math" , "the top 3 college");
            Person p1,p2;
            p1 = new Student("Sam" , "Math");
            p1.setDepartment(dept);
            p2 = new Teacher("Martin" , new Float(15000f));
            p2.setDepartment(dept);
            
            Session session = HibernateUtil.getSession();
            tc = session.beginTransaction();
                        
            session.save(dept);
            //多态保存
            session.save(p1);
            session.save(p2);
        
            tc.commit();
        }catch(HibernateException e){
            try{
                if(tc != null)
                    tc.rollback();
            }catch(Exception ex){
                System.err.println(ex.getMessage());
            }
            System.err.println(e.getMessage());
        }finally{
            HibernateUtil.closeSession();            
        }    
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> List<T> select(String hql) {
        List<T> items = null;
        Transaction tc = null;
        try{
            Session session = HibernateUtil.getSession();
            tc = session.beginTransaction();
                        
            Query query = session.createQuery(hql);
            items = query.list();
            
            tc.commit();
        }catch(HibernateException e){
            try{
                if(tc != null){
                    tc.rollback();
                    items = null;
                }
            }catch(Exception ex){
                System.err.println(ex.getMessage());
            }
            System.err.println(e.getMessage());
        }finally{
            //HibernateUtil.closeSession();            
        }
        
        return items;
    }
}



HibernateUtil.java:

package wintys.hibernate.inheritance.concrete;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
 * Hibernate Session管理
 * @author Winty
 */
public class HibernateUtil {
    private static SessionFactory factory = null;
    private static ThreadLocal<Session> threadLocal;
        
    static {    
        threadLocal = new ThreadLocal<Session>();
    }
    
    private HibernateUtil(){    
    }
    
    //Should be call only once.
    //设置Hibernate.cfg.xml的位置
    public static void setConfigFile(String hibernate_cfg_xml){
        try{
            factory = new Configuration()
                    .configure(hibernate_cfg_xml)
                    .buildSessionFactory();
        }catch(HibernateException e){
            System.err.println(e.getMessage());
        }
    }
    
    public static Session getSession()throws HibernateException{
        Session session = threadLocal.get();
        if(session == null){
            session = factory.openSession();
            threadLocal.set(session);
        }
        
        return session;
    }
    
    public static void closeSession()throws HibernateException{
        Session session = threadLocal.get();
        if(session != null){
            session.close();
        }
        threadLocal.set(null);
    }
}




Test.java:

package wintys.hibernate.inheritance.concrete;

import java.util.Iterator;
import java.util.List;

public class Test {

    public static void main(String[] args) {
        String config = "wintys/hibernate/inheritance/concrete/hibernate.cfg.xml";
        HibernateUtil.setConfigFile(config);
        
        DAO dao = new DAOBean();
        dao.insert();
        //不支持多态查询
        //Error:Person is not mapped
        //List<Person> ps = dao.select("from Person");
        //System.out.println(printStudentOrTeacher(ps));
        
        List<Student> students = dao.select("from Student");
        System.out.println(printStudentOrTeacher(students));
        
        List<Student> teachers = dao.select("from Teacher");
        System.out.println(printStudentOrTeacher(teachers));        
    }
    
    public static String printStudentOrTeacher(List<? extends Person> students){
        String str = "";
        Iterator<? extends Person> it = students.iterator();
        while(it.hasNext()){
            Person person = it.next();
            int id = person.getId();
            String name = person.getName();
            Department dept = person.getDepartment();
                
            int deptId = dept.getId();
            String deptName = dept.getName();
            String deptDesc = dept.getDesc();
            
            str += "id:" +id + ""n";
            str += "name:" + name + ""n";
            if(person instanceof Student)
                str += "major:"  + ((Student) person).getStudentMajor() + ""n";
            if(person instanceof Teacher)
                str += "salary:" + ((Teacher) person).getTeacherSalary().toString() + ""n";
            str += "dept:" + ""n";
            str += "  deptId:" + deptId + ""n";
            str += "  deptName:" + deptName + ""n";
            str += "  deptDesc:" + deptDesc + ""n";    
            str += ""n";
        }
        return str;
    }
}



5、运行结果
控制台显示:

......
Hibernate: select max(id) from mydepartment
Hibernate: select max(id) from mystudent
Hibernate: select max(id) from myteacher
Hibernate: insert into db.mydepartment (name, descs, id) values (?, ?, ?)
Hibernate: insert into db.mystudent (name, studentMajor, dept, id) values (?, ?, ?, ?)
Hibernate: insert into db.myteacher (name, teacherSalary, dept, id) values (?, ?, ?, ?)
Hibernate: select student0_.id as id1_, student0_.name as name1_, student0_.studentMajor as studentM3_1_, student0_.dept as dept1_ from db.mystudent student0_
Hibernate: select department0_.id as id0_0_, department0_.name as name0_0_, department0_.descs as descs0_0_ from db.mydepartment department0_ where department0_.id=?
id:1
name:Sam
major:Math
dept:
  deptId:1
  deptName:college of math
  deptDesc:the top 3 college


Hibernate: select teacher0_.id as id2_, teacher0_.name as name2_, teacher0_.teacherSalary as teacherS3_2_, teacher0_.dept as dept2_ from db.myteacher teacher0_
id:1
name:Martin
salary:15000.0
dept:
  deptId:1
  deptName:college of math
  deptDesc:the top 3 college


[参考资料]:
《J2EE项目实训--Hibernate框架技术》-杨少波 : 清华大学出版社

原创作品,转载请注明出处。
作者:Winty (wintys@gmail.com)
博客:http://www.blogjava.net/wintys

 

  • 大小: 119.8 KB
  • 大小: 26.6 KB
  • 大小: 33.6 KB
分享到:
评论

相关推荐

    Hibernate继承映射-概述

    《Hibernate继承映射详解》 在Java开发中,对象关系映射(ORM)框架如Hibernate大大简化了数据库操作。Hibernate不仅提供了对基本数据类型的映射,还支持复杂的数据结构,如继承关系的映射。本篇文章将深入探讨...

    HIBERNATE - 符合Java习惯的关系数据库持久化

    4. **继承映射**:支持多种继承映射策略,如单表(Single Table)、类表(Class Table)、子表(Subclass Table)等。 5. **属性映射**:定义实体类属性与数据库表字段之间的映射关系,支持基本类型、枚举类型、复杂...

    Hibernate继承映射代码

    本主题将深入探讨"Hibernate继承映射+C3P0代码"的相关知识点。 首先,让我们理解Hibernate的继承映射。在Java中,我们可以创建一个基类,然后派生出多个子类,这种设计模式在数据库中也可以被映射出来。Hibernate...

    Hibernate继承映射的第一种策略:每棵类继承树对应一张表

    Hibernate继承映射是将Java类的继承关系映射到数据库表的一种策略,使得对象模型的复杂性能够平滑地转化为关系数据库模型。本篇将详细介绍Hibernate继承映射的第一种策略——每棵类继承树对应一张表,即单一表继承...

    hibernate继承映射.rar

    Hibernate继承映射是将Java中的继承关系映射到数据库的关系模型中。在Java中,一个基类可以有多个子类,而在数据库中,这些子类可以共享一张表或者各自拥有独立的表,这取决于我们选择的继承策略。Hibernate提供了四...

    用Hibernate映射继承关系

    在Hibernate中映射继承关系时,一种常见的策略是将继承关系树的每个具体类映射到单独的数据库表中。这种方法称为**表/类映射**(Table/Class Mapping),是最直观且简单的映射方式。它不考虑抽象类或继承关系,而是...

    Hibernate继承映射的第一种策略:每个具体类一张表

    本篇文章将详细探讨Hibernate继承映射的策略,特别是“每个具体类一张表”(Table Per Concrete Class)的映射方式。 在面向对象编程中,继承是常见的代码复用手段,但在关系型数据库中,这种概念并不直接对应。...

    Hibernate继承映射(annotation)

    本文将深入探讨使用注解配置的Hibernate继承映射策略,尤其是单表继承策略。 **一、Hibernate继承映射类型** 1. **单表继承(Single Table Inheritance)** - 这种策略将所有继承类的数据存储在一个单一的表中,...

    Hibernate继承映射二:每个子类一张表

    总结来说,“每个子类一张表”的继承映射策略是Hibernate提供的一种处理继承关系的方法,它将类的继承结构映射到数据库的多个表中。这种策略适合于子类具有大量特有属性的情况,但需要权衡可能带来的数据库设计复杂...

    hibernate-distribution-3.6.0

    1. **对象关系映射(ORM)**:Hibernate通过XML配置文件或注解,将Java类与数据库表进行映射,使得我们可以像操作普通Java对象一样操作数据库,减少了对SQL的直接依赖,提高了代码的可读性和可维护性。 2. **...

    Hibernate继承关系映射.pdf

    本文档主要聚焦于Hibernate框架下继承关系的映射,通过三种不同的策略——隐式继承映射、单表映射和关联表映射,来实现类的继承结构在数据库中的映射。 ### 隐式继承映射 #### 定义与配置 隐式继承映射也称为“表...

    hibernate-orm-master.zip

    实体类需要继承Hibernate的Entity接口或使用@Entity注解,属性通过@Id和@Column等注解进行映射。 四、查询机制 Hibernate提供了两种查询方式:HQL和 Criteria API。HQL是面向对象的查询语言,类似于SQL,但操作的是...

    Hibernate继承映射的第一种策略:每个类对应一张表

    本文将详细探讨“Hibernate继承映射的第一种策略:每个类对应一张表”的概念、实现方式以及其优缺点。 首先,我们需要理解Hibernate继承映射的基本策略。在面向对象编程中,类继承是常见的代码复用手段,但在数据库...

    hibernate-annotations-3.4.0.GA.rar

    8. **继承映射** - `@Inheritance`: 控制类的继承策略,如SINGLE_TABLE、JOINED、TABLE_PER_CLASS。 - `@DiscriminatorValue`: 用于多态继承,定义子类在父类表中的区分值。 9. **复合主键** - `@EmbeddedId`: ...

    Hibernate继承映射一:每个类分层结构一张表

    本篇文章主要探讨的是Hibernate的继承映射策略,特别是“每个类分层结构一张表”(Table per Concrete Class)的方式。这种映射策略是Hibernate提供的多种继承映射方案之一,适用于处理复杂的对象模型。 首先,我们...

Global site tag (gtag.js) - Google Analytics