`

用 Hibernate 和 Spring 开发事务持久层(转贴)

阅读更多

用 Hibernate 和 Spring 开发事务持久层(转贴)

用 Hibernate 和 Spring 开发事务持久层

作者:Richard      来自:IBM

  当您自以为已经了解了所有开发工具时,肯定又会冒出一个新的工具。在本文中,developerWorks 的固定撰稿人 Rick Hightower 用一个真实世界的例子向您介绍两个最激动人心的企业新技术。Hibernate 是一个对象关系映射工具,而 Spring 是一个 AOP 框架和 IOC 容器。Rick 介绍了如何结合这两者,为企业应用程序构建一个事务持久层。

   如果关心开发人员的最新热点,那么您可能听说过 IOC (控制倒置,Inversion of Control)容器和 AOP (面向方面编程)。不过,像许多开发人员一样,您可能不清楚在自己的开发工作中如何使用这些技术。在本文中,通过具体介绍使用 Hibernate 和 Spring 在企业应用程序中构建一个事务持久层,您会认识到这些技术。

  Hibernate 是 Java 平台上的一种流行的、容易使用的开放源代码对象关系(OR)映射框架。Spring 是一个 AOP 框架和 IOC 容器。这两种技术一起提供了本文中介绍的开发工作的基础。将使用 Hibernate 把一些持久性对象映射到关系数据库中,用 Spring 使 Hibernate 更容易使用并提供声明性事务支持。由于为示例类编写测试代码时使用了 DbUnit,我还附带介绍了一点 TDD (测试驱动的开发)的内容。

  注意,本文假定读者熟悉 Java 平台上的企业开发,包括 JDBC、OR 映射内容、J2EE 设计模式如 DAO,以及声明性事务支持,如 Enterprise JavaBean (EJB)技术所提供的事务支持。理解这里的讨论不需要成为这些技术的专家,也不需要熟悉 AOP、IOC 或者 TDD,因为在本文中对这三者都做了介绍。

  我将首先介绍两种开发技术,然后分析例子。

  Hibernate 简介

   Hibernate 是 Java 平台上的一种全功能的、开放源代码 OR 映射框架。Hibernate 在许多方面类似于 EJB CMP CMR (容器管理的持久性/容器管理的关系)和 JDO(Java Data Objects)。与 JDO 不同,Hibernate 完全着眼于关系数据库的 OR 映射,并且包括比大多数商业产品更多的功能。大多数 EJB CMP CMR 解决方案使用代码生成实现持久性代码,而 JDO 使用字节码修饰。与之相反,Hibernate 使用反射和运行时字节码生成,使它对于最终用户几乎是透明的(以前 Hibernate 的实现只使用反射,它有助于调试,当前版本保留了这种选项)。

  移植基于 Hibernate 的应用程序

  如果应用程 序必须在多个 RDBMS 系统上运行 ,那么基于 Hibernate 的应用程序可以毫不费力地移植到 IBM DB2、MySQL、PostgreSQL、Sybase、Oracle、HypersonicSQL 和许多其他数据库。我最近甚至将一个应用程序从 MySQL 移植到 Hibernate 没有很好支持的 Firebird,而这种移植是很容易的。
Hibernate 可以模拟继承(有几种方式)、关联(一对一或者一对多、containment 和 aggregation)和 composition。我将在本文中讨论每种关系类型的几个例子。

   Hibernate 提供了一种称为 Hibernate Query Language (HQL) 的 查询语言,它类似于 JDO 的 JDOQL 和 EJB 的 EJB QL,尽管它更接近于前者。但是 Hibernate 没有就此止步:它还可以进行直接的 SQL 查询和/或使用 object criteria 很容易地在运行时构成查询条件。在本文的例子中我将只使用 HQL。

  与 EJB CMP CMR 不同,Hibernate 像 JDO 一样可以在 J2EE 容器内部或者外部工作,这可以让那些进行 TDD 和敏捷开发的人受益。

  Spring 简介

   AOP 专家 Nicholas Lesiecki 第一次向我解释 AOP 时,他说的我一个词也没理解,我觉得就像第一次考虑使用 IOC 容器的可能性时一样。每一种技术的概念基础本身就需要很好地消化,每一种技术所使用的各种各样的缩写让事情更糟了——特别是其中许多术语与我们已经使用的 根本不一样了。

  像许多技术一样,理解这两种技术的实际使用比学习理论更容易。经过自己对 AOP 和 IOC 容器实现(即 XWork、PicoContainer 和 Spring)的分析,我发现这些技术可以帮助我获得功能,而不会在多框架中添加基于代码的依赖性。它们都将成为我后面开发项目的一部分。

  简单地说,AOP 让开发人员可以创建非行为性的关注点,称为横切关注点,并将它们插入到应用程序代码中。使用 AOP 后,公共服务(比如日志、持久性、事务等)就可以分解成方面并应用到域对象上,同时不会增加域对象的对象模型的复杂性。

   IOC 允许创建一个可以构造对象的应用环境,然后向这些对象传递它们的协作对象。正如单词 倒置 所表明的,IOC 就像反过来的 JNDI。没有使用一堆抽象工厂、服务定位器、单元素(singleton)和直接构造(straight construction),每一个对象都是用其协作对象构造的。因此是由容器管理协作对象(collaborator)。

   Spring 既是一个 AOP 框架、也是一个 IOC 容器。我记得 Grady Booch 说过,对象最好的地方是可以替换它们,而 Spring 最好的地方是它有助于您替换它们。有了 Spring,只要用 JavaBean 属性和配置文件加入依赖性(协作对象)。然后可以很容易地在需要时替换具有类似接口的协作对象。

  Spring 为 IOC 容器和 AOP 提供了很好的入口(on-ramp)。因此,不需要熟悉 AOP 就可以理解本文中的例子。所需要知道的就是将要用 AOP 为示例应用程序声明式地添加事务支持,与使用 EJB 技术时的方式基本相同。

  具体到业务

  在本文的其余部分,所有的讨论都将基于一个实际的例子。起点是一个企业应用程序,要为它实现一个事务持久层。持久层是一个对象关系数据库,它包括像 User、User Group、Roles 和 ContactInfo 这些熟悉的抽象。

  在深入到数据库的要素——查询和事务管理——之前,需要建立它的基础:对象关系映射。我将用 Hibernate 设置它,并只使用一点 Spring。

  用 Hibernate 进行 OR 映射

   Hibernate 使用 XML (*.hbm.xml) 文件将 Java 类映射到表,将 JavaBean 属性映射到数据库表。幸运的是,有一组 XDoclet 标签支持 Hibernate 开发,这使得创建所需要的 *.hbm.xml 文件更容易了。清单 1 中的代码将一个 Java 类映射到数据库表。

  清单 1. 将 Java 类映射到 DB 表
[User.java]

/**
* @hibernate.class table="TBL_USER"
* ..
* ..
* ...
*/
public class User {

private Long id = new Long(-1);
private String email;
private String password;

.
.
.

/**
* @return
* @hibernate.id column="PK_USER_ID"
* unsaved-value="-1"
* generator-class="native"
*/
public Long getId() {
   return id;
}

...

/**
* @hibernate.property column="VC_EMAIL"
* type="string"
* update="false"
* insert="true"
* unique="true"
* not-null="true"
* length="82"
* @return
*/
public String getEmail() {
   return email;
}

/**
* @hibernate.property column="VC_PASSWORD"
* type="string"
* update="false"
* insert="true"
* unique="true"
* not-null="true"
* length="20"
* @return
*/
public String getPassword() {
   return password;
}

...
...
...
}

   可以看到,@hibernate.class table="TBL_USER" 标签将 User 映射到 TBL_USER 表。@hibernate.property column="VC_PASSWORD" 将 JavaBean 属性 password 映射到 VC_PASSWORD 列。@hibernate.id column="PK_USER_ID" 标签声明id 属性是主键,它将使用本机(generator-class="native")数据库机制生成键(例如,Oracle sequences 和 SQL Server Identity 键)。Hibernate 可以指定 generator-class="native" 以外的、其他可以想象的得到主键获得策略,不过我更愿意使用 native。type 和 length 属性用于从 Hibernate *.hbm.xml OR 映射文件生成表。这些 final 属性是可选的,因为使用的可能不是 green-field 数据库。在这个例子中,已经有数据库了,所以不需要额外的属性。(green-field 应用程序 是一个新的应用程序, green-field 数据 是新应用程序的一个新数据库。不会经常开发一个全新的应用程序,不过偶尔有一两次也不错)。

  看过了表如何映射到类以及列如何映射到 JavaBean 属性,该使用 Hibernate 在 OR 数据库中设置一些关系了。

  设置对象关系

  在本节中,我将只触及 Hibernate 提供的设置对象间关系的选项的一小部分。首先设置像 User、User Group、Roles 和 ContactInfo 这些类之间的关系。其中一些关系如图 1 所示,这是数据库的验证对象模型。


图 1. 关系的图示

   如您所见,在上述抽象中存在各种各样的关系。User 与 ContactInfo 有一对一关系。ContactInfo 的生命周期与 User 相同(用数据库的术语,UML 中的组成 aka 级联删除)。如果删除 User,则相应的 ContactInfo 也会删除。在 Users 与 Roles 之间存在多对多关系(即与独立生命周期相关联)。在 Groups 与 Users 之间存在一对多关系,因为组有许多用户。用户可以存在于组外,即是 aggregation 而不是 composition (用数据库的说法,在 Groups 和 Users 之间没有级联删除关系)。此外,User 和 Employee 有子类关系,就是说,Employee 的类型为 User。表 1 显示了如何用 XDoclet 标签创建一些不同类型的对象关系。

表 1. 用 XDoclet 创建对象关系
关系 Java/XDoclet SQL DDL(由 Hibernate Schema Export 生成的 MySQL)
组包含用户
一对多
Aggregation
双向
(Group<-->Users)
[Group.java]
/**
*
* @return
*
* @hibernate.bag name="users"
* cascade="save-update"
* lazy="true"
* inverse="true"
*
* @hibernate.collection-key
* column="FK_GROUP_ID"
*
* @hibernate.collection-one-to-many
* class="net.sf.hibernateExamples.User"
*/
public List getUsers() {
return users;
}

[User.java]
/**
* @hibernate.many-to-one
* column="FK_GROUP_ID"
* class="net.sf.hibernateExamples.Group"
*/
public Group getGroup() {
return group;
}

create table TBL_USER (
PK_USER_ID BIGINT NOT NULL AUTO_INCREMENT,
USER_TYPE VARCHAR(255) not null,
FK_GROUP_ID BIGINT,
VC_EMAIL VARCHAR(82) not null unique,
primary key (PK_USER_ID)
)


create table TBL_GROUP (
PK_GROUP_ID BIGINT NOT NULL AUTO_INCREMENT,
VC_DESCRIPTION VARCHAR(255),
VC_NAME VARCHAR(40) unique,
primary key (PK_GROUP_ID)
)

alter table TBL_USER add index (FK_GROUP_ID),
add constraint FK_111 foreign key (FK_GROUP_ID)
references TBL_GROUP (PK_GROUP_ID)

用户有联系信息
一对一
Composition
单向
(User-->ContactInfo)
[User.java]
/**
* @return
*
* @hibernate.one-to-one cascade="all"
*
*/
public ContactInfo getContactInfo() {
return contactInfo;
}

[ContactInfo.java]
(Nothing to see here. Unidirectional!)

create table TBL_USER (
PK_USER_ID BIGINT NOT NULL AUTO_INCREMENT,
USER_TYPE VARCHAR(255) not null,
FK_GROUP_ID BIGINT,
VC_EMAIL VARCHAR(82) not null unique,
primary key (PK_USER_ID)
)

create table TBL_CONTACT_INFO (
PK_CONTACT_INFO_ID BIGINT not null,
...
...
...
primary key (PK_CONTACT_INFO_ID)
)

用户与角色关联
多对多
Association
单向
(Users-->Roles)
[User.java]
/**
* @return
* @hibernate.bag
* table="TBL_JOIN_USER_ROLE"
* cascade="all"
* inverse="true"
*
* @hibernate.collection-key
* column="FK_USER_ID"
*
* @hibernate.collection-many-to-many
* class="net.sf.hibernateExamples.Role"
* column="FK_ROLE_ID"
*
*/
public List getRoles() {
return roles;
}

[Role.java]
Nothing to see here. Unidirectional!

create table TBL_ROLE (
PK_ROLE_ID BIGINT NOT NULL AUTO_INCREMENT,
VC_DESCRIPTION VARCHAR(200),
VC_NAME VARCHAR(20),
primary key (PK_ROLE_ID)
)

create table TBL_USER (
PK_USER_ID BIGINT NOT NULL AUTO_INCREMENT,
USER_TYPE VARCHAR(255) not null,
FK_GROUP_ID BIGINT,
VC_EMAIL VARCHAR(82) not null unique,
primary key (PK_USER_ID)
)

create table TBL_JOIN_USER_ROLE (
FK_USER_ID BIGINT not null,
FK_ROLE_ID BIGINT not null
)

雇员是用户
Inheritance
用户
雇员
[User.java]
/**
* @hibernate.class table="TBL_USER"
* discriminator-value="2"
* @hibernate.discriminator column="USER_TYPE"
*
...
...
...
*/
public class User {

[Employee.java]
/**
* @hibernate.subclass discriminator-value = "1"
*/
public class Employee extends User{

create table TBL_USER (
PK_USER_ID BIGINT NOT NULL AUTO_INCREMENT,
USER_TYPE VARCHAR(255) not null,
FK_GROUP_ID BIGINT,
VC_EMAIL VARCHAR(82) not null unique,
primary key (PK_USER_ID)
)

  Hibernate 中的查询

  Hibernate 有三种类型的查询:

  ☆ Criteria, object composition
☆ SQL
☆ HQL

   在下面的例子中将只使用 HQL。本节还要使用 Spring,用它的 AOP-driven HibernateTemplate 简化 Hibernate 会话的处理。在本节将开发一个 DAO(Data Access Object)。要了解更多关于 DAO 的内容,请参阅 参考资料。

  清单 2 展示了两个方法:一个使用 HQL 查询的组查询,另一个是后面接一个操作的组查询。注意在第二个方法中,Spring HibernateTemplate 是如何简化会话管理的。

  清单 2. 使用查询

import net.sf.hibernate.HibernateException;
import net.sf.hibernate.S ...

分享到:
评论

相关推荐

    用Hibernate和Spring开发事务持久层.rar_spring

    接下来,我们关注`用Hibernate和Spring开发事务持久层`这个主题。在实际项目中,通常会有一个Service层,它封装了业务逻辑并负责调用DAO(Data Access Object)层的方法。Service层的方法上添加`@Transactional`注解...

    用 Hibernate 和 Spring 开发持久层

    ### 使用Hibernate和Spring开发持久层的关键知识点 #### 引言 在现代企业级应用开发中,数据持久化是一项核心需求,而使用Hibernate和Spring构建事务持久层成为了许多开发者的选择。Hibernate,作为一款强大的对象...

    用 hibernate 和 spring 开发持久层.doc

    【标题】: 使用Hibernate和Spring开发持久层 【描述】: 本文主要讲解如何利用Hibernate和Spring框架构建企业级应用的持久层,帮助开发者从初学者到专家的进阶。 【标签】: Hibernate 【正文】: 在Java开发中,...

    用 Hibernate 和 Spring 开发持久层.zip

    在"用 Hibernate 和 Spring 开发持久层.zip"这个压缩包中,可能包含的文件有项目结构示例、配置文件、源代码以及相关的文档说明。开发者可以学习如何配置Spring和Hibernate的整合,如何编写Repository接口,以及如何...

    用Hibernate和Spring开发持久层

    ### 用Hibernate和Spring开发持久层 #### 一、引言 随着企业级应用的不断发展,数据持久化层的设计和实现成为了系统架构中的关键部分。本文将深入探讨如何结合使用Hibernate和Spring框架来构建高效、稳定的事务...

    基于Hibernate和Spring的数据持久层设计与开发(软件工程课程设计).pdf

    总结,本课程设计通过学习和实践,旨在使学生掌握ORM技术,深入理解Hibernate和Spring的使用,从而能够构建出高效、灵活的数据持久层,为实际的软件开发提供有力的支持。在实际项目中,这样的设计可以显著提高开发...

    Struts2+Hibernate+Spring整合开发深入剖析与范例应用03

    其次,Hibernate是一个持久层框架,用于管理和操作数据库。它简化了对象关系映射(ORM),使开发者无需编写大量SQL代码即可操作数据库。Hibernate支持多种数据库,提供了一套强大的查询语言HQL,以及Criteria和...

    Hibernate编程式事务与Spring Aop的声明式事务(spring与hibernate集成)

    3. **事务管理**: 使用Spring的`HibernateTransactionManager`作为事务管理器,它可以理解Hibernate的Session和Transaction。 4. **事务传播行为**: 在多层服务调用中,可以通过设置`@Transactional`的propagation...

    Hibernate缓存与spring事务详解

    **标题:“Hibernate缓存与Spring事务详解”** 在IT领域,尤其是Java开发中,Hibernate作为一款流行的ORM(对象关系映射)框架,极大地简化了数据库操作。而Spring框架则以其全面的功能,包括依赖注入、AOP(面向切...

    spring hibernate,spring jdbc事务管理

    两个项目,一个项目是基于spring jdbc实现的分布式事务,一个是基于spring hibernate的分布式事务,hibernate项目里的applicationContext2.xml...这两个项目下来,关于spring事务这一块基本上明了,绝对对得起这个分数

    Struts1+Hibernate+Spring开发例子

    Struts1、Hibernate和Spring是Java企业级开发中经典的三个框架,它们的组合通常被称为SSH(Struts1、Spring、Hibernate)集成框架。这个开发例子是基于SSH来实现一个基本的CRUD(创建、读取、更新、删除)功能,这...

    eclipse_struts_hibernate_spring集成开发宝典 StrutsInterface.rar

    《Eclipse、Struts、Hibernate、Spring 集成开发宝典》是针对Java企业级应用开发的一套经典教程,涵盖了四个核心的技术框架:Eclipse作为开发环境,Struts作为表现层框架,Hibernate作为持久层框架,Spring作为全面...

    hibernate和spring整合Java项目

    在Java开发领域,Hibernate和Spring是两个非常重要的开源框架,它们分别在对象关系映射(ORM)和依赖注入(DI)方面发挥着关键作用。整合这两个框架,可以创建出高效、灵活且易于维护的Java应用。本文将深入探讨...

    spring hibernate 事务管理学习笔记(一)

    在IT行业中,Spring和Hibernate是两个非常重要的框架,它们分别在应用上下文管理和持久化层提供了强大的支持。本文将深入探讨Spring与Hibernate整合时的事务管理,帮助你更好地理解和运用这些技术。 首先,Spring...

    Struts.2.Hibernate.Spring整合开发技术详解.rar

    Struts 2、Hibernate 和 Spring 是Java开发中最流行的三大开源框架,它们的整合使用被称为SSH(Struts2、Spring、Hibernate)集成开发。这三大框架分别解决了Web应用中的不同问题,Struts 2负责表现层,Spring处理...

    spring_struts_hibernate整合开发书籍

    在书中,读者会了解到如何使用Spring管理对象的生命周期,实现松耦合,以及如何利用Spring MVC进行Web层的开发。 Struts作为经典的MVC框架,是Java Web开发中的重要组成部分。它通过分离业务逻辑、视图和控制,提供...

    hibernate与spring整合demo

    5. 创建DAO接口和实现类:定义数据访问接口,然后使用Spring的@Repository注解标记实现类,实现DAO方法。 6. 配置事务管理:在Spring配置文件中启用事务管理,并定义事务边界。 7. 测试整合:编写测试用例,验证...

Global site tag (gtag.js) - Google Analytics