- 浏览: 111956 次
- 性别:
- 来自: 成都
最近访客 更多访客>>
文章分类
最新评论
-
dev_liu:
lipengyu2006 写道现在怎么样儿了啊 房子多少钱买 ...
最近比较心烦 -
lipengyu2006:
现在怎么样儿了啊 房子多少钱买的。
最近比较心烦 -
cynan168:
...
hibernate数据查询的几种方式 -
My_Choice:
joram中文文档 -
My_Choice:
非常感谢,太有用了,中文文档不好找啊,而且是这么详细的
joram中文文档
由于Java只允许一个类最多有一个直接的父类,因此Employ类、HourlyEmployee类和SalariedEmployee类构成了一棵继承关系树。
图 继承关系树
多态在图中的表现:
List employees=businessService.findAllEmployees();
Iterator it=employees.iterator();
while(it.hasNext()){
Employee e=(Employee)it.next();
if(e instanceof HourlyEmployee){
System.out.println(e.getName()+""+((HourlyEmployee)e).getRate());
}else{
System.out.println(e.getName()+""+((SalariedEmployee)e).getSalary());
}
第一种方式:是将每个具体的类映射为一张表也是最简单的。
继承关系树的每个具体类对应一张表:这种映射方式关系数据模型完全不支持域模型中的继承关系和多态。
图 1 每个具体类对应的表
图 2 持久化类、映射文件和数据表之间的对应关系
如果Employee类不是抽象类(这里Employee类被设计成了抽象类),即Employee类也能被实例化,那么还需要为Employee类创建对应的Employees表,此时HOURLY_EMPLOYEES表和SALARIED_EMPLOYEES表结构仍然和图1相同,只不过多了一个EMPLOYEES表。
图 3 每个具体类对应的表
另外,还需要为Employee类创建单独的Employee.hbm.xml文件。
在这里我只讨论设计成常用的抽象类的模式。
从Company类到Employee类是多态关联,但是由于关系数据<nobr>模型</nobr>没有描述Employee类和它的两个子类的继承关系,因此无法映射Company类的employees集合。Company.hbm.xml文件的代码,该文件仅仅映射了Company类的id和name属性。
例程:Company.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping >
<class name="mypack.Company" table="COMPANIES" >
<id name="id" type="long" column="ID">
<generator class="increment"/>
</id>
<property name="name" type="string" column="NAME" />
</class>
</hibernate-mapping>
HourlyEmployee.hbm.xml文件用于把HourlyEmployee类映射到HE表,在这个映射文件中,除了需要映射HourlyEmployee类本身的rate属性,还需要映射从Employee类中继承的name属性,此外还需要映射从Employee类中继承与Company类的关联关系。
例程:HourlyEmployee.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping >
<class name="mypack.HourlyEmployee" table="HOURLY_EMPLOYEES">
<id name="id" type="long" column="ID">
<generator class="increment"/>
</id>
<property name="name" type="string" column="NAME" />
<property name="rate" column="RATE" type="double" />
<many-to-one
name="company"
column="COMPANY_ID"
class="mypack.Company"
/>
</class>
</hibernate-mapping>
SalariedEmployee.hbm.xml文件用于把SalariedEmployee类映射到SE表,在这个映射文件中,除了需要映射SalariedEmployee类本身的salary<nobr>属性</nobr>,还需要映射从Employee类中继承的name属性,此外还需要映射从Employee类中继承的与Company类的关联关系。
例程:SalariedEmployee.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping >
<class name="mypack.SalariedEmployee" table="SALARIED_EMPLOYEES">
<id name="id" type="long" column="ID">
<generator class="increment"/>
</id>
<property name="name" type="string" column="NAME" />
<property name="salary" column="SALARY" type="double" />
<many-to-one
name="company"
column="COMPANY_ID"
class="mypack.Company"
/>
</class>
</hibernate-mapping>
由于Employee类没有映射文件,因此在初始化Hibernate时,只需向Configuration对象中加入Company类、HourlyEmployee类和SalariedEmployee类:
Configuration config=new Configuration();
config.addClass(Company.class)
.addClass(HourlyEmployee.class)
.addClass(SalariedEmployee.class);
这中方式不支持多态查询,所以
List employees=session.find("from Employee");
会抛出异常。因为Employee是抽象类,但如果Employee类是具体类的话也只会查询出EMPLOYEE表的记录不会检索出它的两个子类的实例。
源码如下:
hibernate.properties
hibernate.dialect=net.sf.hibernate.dialect.MySQLDialect
hibernate.connection.driver_class=com.mysql.jdbc.Driver
hibernate.connection.url=jdbc:mysql://localhost:3306/SAMPLEDB
hibernate.connection.username=root
hibernate.connection.password=1234
hibernate.show_sql=true
BusinessService.java
package mypack;
import net.sf.hibernate.*;
import net.sf.hibernate.cfg.Configuration;
import java.util.*;
import java.sql.*;
public class BusinessService{
public static SessionFactory sessionFactory;
static{
try{
// Create a configuration based on the properties file we've put
Configuration config = new Configuration();
config.addClass(Company.class)
.addClass(HourlyEmployee.class)
.addClass(SalariedEmployee.class);
// Get the session factory we can use for persistence
sessionFactory = config.buildSessionFactory();
}catch(Exception e){e.printStackTrace();}
}
public void saveEmployee(Employee employee) throws Exception{
Session session = sessionFactory.openSession();
Transaction tx = null;
List results=new ArrayList();
try {
tx = session.beginTransaction();
session.save(employee);
tx.commit();
}catch (Exception e) {
if (tx != null) {
// Something went wrong; discard all partial changes
tx.rollback();
}
throw e;
} finally {
// No matter what, close the session
session.close();
}
}
public List findAllEmployees() throws Exception{
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
List results=new ArrayList();
tx = session.beginTransaction();
List hourlyEmployees=session.find("from HourlyEmployee");
results.addAll(hourlyEmployees);
List salariedEmployees=session.find("from SalariedEmployee");
results.addAll(salariedEmployees);
tx.commit();
return results;
}catch (Exception e) {
if (tx != null) {
// Something went wrong; discard all partial changes
tx.rollback();
}
throw e;
} finally {
// No matter what, close the session
session.close();
}
}
public Company loadCompany(long id) throws Exception{
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Company company=(Company)session.load(Company.class,new Long(id));
List hourlyEmployees=session.find("from HourlyEmployee h where h.company.id="+id);
company.getEmployees().addAll(hourlyEmployees);
List salariedEmployees=session.find("from SalariedEmployee s where s.company.id="+id);
company.getEmployees().addAll(salariedEmployees);
tx.commit();
return company;
}catch (Exception e) {
if (tx != null) {
// Something went wrong; discard all partial changes
tx.rollback();
}
throw e;
} finally {
// No matter what, close the session
session.close();
}
}
public void test() throws Exception{
List employees=findAllEmployees();
printAllEmployees(employees.iterator());
Company company=loadCompany(1);
printAllEmployees(company.getEmployees().iterator());
Employee employee=new HourlyEmployee("Mary",300,company);
saveEmployee(employee);
}
private void printAllEmployees(Iterator it){
while(it.hasNext()){
Employee e=(Employee)it.next();
if(e instanceof HourlyEmployee){
System.out.println(((HourlyEmployee)e).getRate());
}else
System.out.println(((SalariedEmployee)e).getSalary());
}
}
public static void main(String args[]) throws Exception {
new BusinessService().test();
sessionFactory.close();
}
}
Company.java
package mypack;
import java.io.Serializable;
import java.util.Set;
import java.util.HashSet;
public class Company implements Serializable {
private Long id;
private String name;
private Set employees=new HashSet();
/** full constructor */
public Company(String name, Set employees) {
this.name = name;
this.employees = employees;
}
/** default constructor */
public Company() {
}
/** minimal constructor */
public Company(Set employees) {
this.employees = employees;
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Set getEmployees() {
return this.employees;
}
public void setEmployees(Set employees) {
this.employees = employees;
}
}
Company.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping >
<class name="mypack.Company" table="COMPANIES" >
<id name="id" type="long" column="ID">
<generator class="increment"/>
</id>
<property name="name" type="string" column="NAME" />
</class>
</hibernate-mapping>
Employee.java
package mypack;
import java.io.Serializable;
abstract public class Employee implements Serializable {
private Long id;
private String name;
private Company company;
/** full constructor */
public Employee(String name,Company company) {
this.name = name;
this.company = company;
}
/** default constructor */
public Employee() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Company getCompany() {
return this.company;
}
public void setCompany(Company company) {
this.company = company;
}
}
HourlyEmployee.java
package mypack;
import java.io.Serializable;
public class HourlyEmployee extends Employee{
private double rate;
/** full constructor */
public HourlyEmployee(String name, double rate,Company company) {
super(name,company);
this.rate=rate;
}
/** default constructor */
public HourlyEmployee() {
}
public double getRate() {
return this.rate;
}
public void setRate(double rate) {
this.rate = rate;
}
}
HourlyEmployee.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping >
<class name="mypack.HourlyEmployee" table="HOURLY_EMPLOYEES">
<id name="id" type="long" column="ID">
<generator class="increment"/>
</id>
<property name="name" type="string" column="NAME" />
<property name="rate" column="RATE" type="double" />
<many-to-one
name="company"
column="COMPANY_ID"
class="mypack.Company"
/>
</class>
</hibernate-mapping>
SalariedEmployee.java
package mypack;
import java.io.Serializable;
public class SalariedEmployee extends Employee {
private double salary;
/** full constructor */
public SalariedEmployee(String name, double salary,Company company) {
super(name,company);
this.salary=salary;
}
/** default constructor */
public SalariedEmployee() {
}
public double getSalary() {
return this.salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
SalariedEmployee.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping >
<class name="mypack.SalariedEmployee" table="SALARIED_EMPLOYEES">
<id name="id" type="long" column="ID">
<generator class="increment"/>
</id>
<property name="name" type="string" column="NAME" />
<property name="salary" column="SALARY" type="double" />
<many-to-one
name="company"
column="COMPANY_ID"
class="mypack.Company"
/>
</class>
</hibernate-mapping>
sampledb.sql
drop database if exists SAMPLEDB;
create database SAMPLEDB;
use SAMPLEDB;
create table COMPANIES (
ID bigint not null,
NAME varchar(15),
primary key (ID)
);
create table HOURLY_EMPLOYEES (
ID bigint not null,
NAME varchar(15),
RATE double precision,
COMPANY_ID bigint,
primary key (ID)
);
create table SALARIED_EMPLOYEES (
ID bigint not null,
NAME varchar(15),
SALARY double precision,
COMPANY_ID bigint,
primary key (ID)
);
alter table HOURLY_EMPLOYEES add index IDX1_COMPANY(COMPANY_ID), add constraint FK1_COMPANY foreign key (COMPANY_ID) references COMPANIES (ID);
alter table SALARIED_EMPLOYEES add index IDX2_COMPANY(COMPANY_ID), add constraint FK2_COMPANY foreign key (COMPANY_ID) references COMPANIES (ID);
insert into COMPANIES(ID,NAME) values(1,'ABC Company');
insert into HOURLY_EMPLOYEES(ID,NAME,RATE,COMPANY_ID) values(1,'Tom',100,1);
insert into HOURLY_EMPLOYEES(ID,NAME,RATE,COMPANY_ID) values(2,'Mike',200,1);
insert into SALARIED_EMPLOYEES(ID,NAME,SALARY,COMPANY_ID)
values(1,'Jack',5000,1);
insert into SALARIED_EMPLOYEES(ID,NAME,SALARY,COMPANY_ID)
values(2,'Linda',6000,1);
总结:
BusinessServic的main()方法调用test()方法,test()方法依次调用以下方法。
* findAllEmployees():检索数据库中所有的Employee对象
* loadCompany():加载一个Company对象
* saveEmployee():保存一个Employee对象
(1) 运行findAllEmployee()方法,它的代码如下:
List results=new ArrayList();
tx=session.beginTransaction();
List hourlyEmployees=session.find("from HourlyEmployee");
results.addAll(hourlyEmployee);
List salariedEmployees=session.find("from SalariedEmployee");
results.addAll(salariedEmployees);
tx.commit();
return results;
为了检索所有的Employee对象,必须分别检索所有的HourlyEmployee实例和SalariedEmployee实例,然后将它们合并到一个集合中去。在运行Session的第一个find()方法时,Hibernate执行以下select语句:
select * from HOURLY_EMPLOYEES;
select * from COMPANIES where ID=1;
从HourlyEmployee类到Company类不是多态关联,在加载HourlyEmployee对象时,会同时加载与它关联的Company对象。
在运行Session的第二个find()方法时,Hibernate执行以下select语句:
select * from SALARIED_EMPLOYEES;
从SalariedEmployee类到Company类不是多态关联,在加载SalariedEmployee对象时,会同时加载与它关联的Company对象。在本测试数据中,所有的HourlyEmployee实例和SalariedEmployee实例都与OID为1的Company对象关联,由于该Company对象已经被加载到内存中,所以Hibernate不再需要执行检索该对象的 select语句。
(2) 运行loadCompany()方法,它的代码如下:
tx=session.beginTransaction();
Company company=(Company)session.load(Company.class,new Long(id));
List hourlyEmployees=session.find("from HourlyEmployee h where h.company.id="+id);
company.getEmployees().addAll(hourlyEmployees);
//抽象类不能用new来创建
List salariedEmployees=session.find("from SalariedEmployee s where s.company.id="+id);
company.getEmployees().addAll(salariedEmployees);
tx.commit();
return company;
由于这种映射方式不支持多态关联,因此由Session的load()方法加载的Company<nobr>对象</nobr>的employees<nobr>集合</nobr>中不包含任何Employee对象。BusinessService类必须负责从数据库中检索出所有与Company对象关联的HourlyEmployee对象以及SalariedEmployee对象,然后把它们加入到employees集合中。
(3) 运行saveEmployee(Employee employee)方法,它的代码如下:
tx=session.beginTransaction();
session.save(employee);
tx.commit();
在test()方法中,创建了一个HourlyEmployee实例,然后调用saveEmployee()方法保存这个实例:
Employee employee=new HourlyEmployee("Mary",300,company);
saveEmployee(employee);
Session的save()方法能判断employee变量实际引用的实例的类型,如果employee变量引用HourlyEmployee实例,就向HE表中插入一条记录,执行如下insert<nobr>语句</nobr>:
insert into HOURLY_EMPLOYEES (ID,NAME,RATE,CUSTOMER_ID) values(3,'Mary',300,1);
如果employee<nobr>变量</nobr>引用SalariedEmployee<nobr>实例</nobr>,就向SE表插入一条记录。
发表评论
-
hibernate数据查询的几种方式
2007-01-25 11:52 43921.使用主键id加载对象(load(),get()); 2.通 ... -
HIBERNATE 学习笔记(基础篇一)
2007-01-18 19:28 1016书非借不能不读----------------------- ... -
Hibernate性能优化策略2 (zt)
2007-01-09 15:38 1476本文依照HIBERNATE幫助文檔,一些網路書籍及項目經驗整理 ... -
浅谈hibernate性能优化的几点建议 (zt)
2007-01-09 13:17 1345浅谈hibernate性能优化的几点建议 1、针对orac ... -
Hibernate性能优化策略 (zt)
2007-01-09 13:16 3685Hibernate性能优化策略 1. 简介 版本:Hi ... -
hibernate性能问题(关于他的bug和sql写法)
2007-01-09 13:12 1606就hibernate本身来说,他的效率很高,但常常在项目技术时 ... -
myeclipse里hibernate的开发如此简单
2007-01-09 11:52 1227才接触myeclipse,我靠,我用了一周的时间去熟悉xxx, ... -
hibernate包(入门基础)
2007-01-08 17:45 966Hibernate一共包括了23个jar包,令人眼花缭乱。本文 ... -
HIBERNATE 学习笔记(preface)
2006-12-28 22:49 1028前段时间学习了一下hibernate!不过学习几天就因为项目原 ...
相关推荐
第三种映射方式是**类表映射**(Class-Table Inheritance Mapping),其中继承关系树的每个类(包括抽象类)都有其对应的表。这需要使用外键来建立类之间的关系。 ##### 14.3.1 创建映射文件 `Employee`类的映射文件...
本文将详细探讨Hibernate中处理继承关系的三种映射策略:subclass、joined-subclass以及union-subclass。 首先,让我们理解继承关系在面向对象编程中的重要性。继承允许我们创建一个类(子类)作为另一个类(父类)...
Hibernate,作为Java中广泛使用的对象关系映射(ORM)框架,提供了多种方式来处理继承关系的映射,其中一种就是"每个类都对应一张表"的策略。本文将深入探讨这种映射方式,以及如何在Hibernate中实现它。 首先,...
在Java世界中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者用面向对象的方式处理数据库操作。在大型项目中,由于业务需求复杂,我们常常会使用到类的继承来组织代码结构,而Hibernate提供了对...
总之,单一表继承策略是一种简单且直观的Hibernate继承映射方式,适合类继承层次结构不深且子类数量较少的情况。但在大型项目或复杂的类继承结构中,可能需要考虑其他策略,如`JOINED`或`TABLE_PER_CLASS`。理解并...
Hibernate支持四种继承映射策略:单表继承(Single Table Inheritance)、联合继承( Joined Subclass)、表 per 类继承(Table per Class Inheritance)和子类表(Concrete Table Inheritance)。在实际应用中,最...
本主题将深入探讨Hibernate框架下,如何通过XML映射文件和注解进行对象关系映射的配置,包括实体类的设计、字段映射、关联关系的建立,并可能结合具体代码实例进行解析,帮助读者理解并掌握这两种映射方式的使用。...
本文档主要聚焦于Hibernate框架下继承关系的映射,通过三种不同的策略——隐式继承映射、单表映射和关联表映射,来实现类的继承结构在数据库中的映射。 ### 隐式继承映射 #### 定义与配置 隐式继承映射也称为“表...
本文将深入探讨Hibernate如何处理继承多态映射关系,主要通过三种不同的策略来实现这一目标。 #### 继承多态的概念与背景 在面向对象编程中,继承允许子类继承父类的属性和方法,从而实现代码复用和功能扩展。而...
1. Hibernate 是一种开源的持久层框架,提供了一个高效的数据访问机制,能够将 Java 对象与数据库表进行映射。 2. MyEclipse 是一个集成开发环境(IDE),提供了丰富的开发工具和插件,包括数据库管理、代码编辑、...
hibernate映射文件是Java开发中用于对象关系映射(ORM)的重要组成部分,它将数据库表与Java类之间的关系进行定义,使得开发者无需编写大量的SQL语句,就能实现对数据库的操作。`生成hibernate映射文件工具`是为了...
Hibernate通过XML或注解方式将Java类与数据库表进行映射,使得开发者可以使用面向对象的方式来处理数据库。然而,手动编写这些映射文件可能会耗费大量时间,因此“Hibernate 映射文件自动生成”是一个非常实用的功能...
在 Hibernate 中,映射关系是将数据库表与 Java 类之间的关联方式,使得对象模型可以与关系模型无缝对接。本篇文章将详细探讨 Hibernate 中的多种映射关系。 1. **一对一映射 (One-to-One)** 一对一映射表示两个...
【标题】"Hibernate教程20_关系映射案例三"主要涵盖了在Hibernate框架中如何进行对象关系映射(ORM)的实践,特别是针对复杂关系的处理。在这个教程中,我们可能会学习到以下关键知识点: 1. **关系映射**:...
在 Hibernate 中,对象关系映射(ORM)是将数据库表映射到 Java 类的过程。这个过程通过 `hibernate.cfg.xml` 配置文件和实体类(Entity Class)来实现。在 `hibernate.cfg.xml` 文件中,我们配置数据库连接参数,如...
Hibernate对象关系映射一对多 很基础等文档