Hibernate的构架性选择-第1部分

1.     前言
在使用Java进行应用开发时,访问数据库往往是一项必备的功能,对此,早期的做法要么是使用原始的JDBC,要么使用标准但笨重的EJB2,后来通过开发者社区和软件厂商的不断努力,开发出了大量的轻量级持久化工具,例如商业软件TopLink,开源软件Hibernate,以及标准化但分歧严重的JDO。在这场混战中,毫无疑问,Hibernate获得了胜利。但是,时间走到了今天,情况又发生了一点变化,那就是Java社区为统一持久层技术而做出的努力终于有了成果——Java EE 5规范(JSR 244)最终发布了。
Java EE 5的持久层技术包含在EJB 3.0(JSR-220)中,该技术从企业bean组件体系(新的组件体系仅包含session bean和message-driven bean)中独立出来,重新命名为Java Persistence API(即JPA) [ 注]。从技术上看,这个全新的规范已经具备了一统天下的能力:轻量级;即能宿主于容器,也能独立运行;元数据映射;标准化。
从目前的情况看来,JPA似乎无可阻挡,大多数现存的持久层工具,包括Hibernate、某些JDO实现、TopLink等在内,都已经提供了JPA兼容接口。面对新的形势,作为一个开发者,熟悉这个新的编程模式,并对各类持久层技术进行选择,就成了一个无法回避的现实。
幸运的是,对Hibernate开发者来说,这个学习或转变过程是非常容易的;此外,新的编程模型是如此的简单,即使是一个Hibernate新手,也可以快速的掌握。本文试图通过一个完整的示例,对Hibernate的各类编程模型进行说明,以便于开发者以更适合自己的方式使用Hibernate。
[ 注]
EJB 3.0规范被组织成以下三个文档:
l        EJB 3.0 Simplified API
l        EJB Core Contracts and Requirements
l        Java Persistence API
其中 JPA在第三个文档中进行定义。
2.     选择合适的方案
2.1     Hibernate构件
Hibernate是一个采用LGPL协议的开放源代码软件,为应用程序提供功能强大、性能出众的对象/关系持久化和查询服务。
从版本3开始,Hibernate被分解为三个主要的组成部分:
l        Hibernate Core:通过XML映射元数据和原生编程接口,提供了持久化。当前版本为3.2.0 CR2。
l        Hibernate Annotiations:实现了JPA规范中的元数据映射;此外也包含了Hibernate特有的O/R映射扩展和验证框架。当前版本为3.2.0 CR1。
l        Hibernate EntityManager:实现了JPA规范中的编程接口和生命周期规则部分。当前版本为3.2.0 CR1。
可以看出,对于持久化的一些关键技术,Hibernate既提供了自己特有的实现方式,也提供了标准化JPA的实现,从而为开发者提供了更多的选择。例如,对于O/R映射方式,我们可以选择:
l        使用Hbm映射文件(通过Hibernate Core提供)
l        使用JPA元数据及Hibernate扩展(通过Hibernate Annotations提供)
对于编程接口,我们可以选择:
l        Hibernate原生编程接口(通过Hibernate Core提供)
l        JPA编程接口(通过Hibernate EntityManager提供)
2.2     构件组合
实际上,上述两类技术方案是可以任意组合的,选择何种技术路线只取决于你的实际需求:
1)传统方式
在原生Hibernate编程接口下使用Hbm映射。这是一个代价最小的选择,你不用引入任何新的技术元素,就可以继续享用Hibernate带来的任何好处。当然,这也意味着你必须绑定到Hibernate这部战车上(其实我们丝毫不用为Hibernate的未来担心,连续发生的两次收购,只会使Hibernate更加强大;即使需要转换到JPA体系中,那也是一件非常容易完成的任务)。
2)只引入Annotation映射的方式
在原生Hibernate编程接口下使用JPA映射。我们可以不用改变代码和学习新的API,仅仅是利用Java SE 5.0 Annotation方式的JPA元数据映射,即可简化开发工作。而且,基于Annotation的映射方式是非常直观的,只需要很小的代价即可掌握。
3)只引入JPA编程接口的方式
继续使用hbm映射方式,但引入新的JPA编程接口。这种方式实际上不具备现实意义:因为这使你继依赖于Hibernate,但又不能充分利用Hibernate的全部能力。
4)完整的JPA方式
同时使用JPA编程接口和JPA元数据映射。这样,你的代码就彻底摆脱了对Hibernate的依赖,只要你愿意,就可以移植到任何JPA兼容的环境中。
Hibernate提供了足够的灵活性,开发者可以根据自己的需求,使用上述任何一种编程模式。
2.3     Spring集成
没错,就是你经常听到,或者经常使用的那个Spring。尽管Spring的设计目标之一是为了让我们减少对第三方类库的依赖性,但我们还是心甘情愿的依赖于Spring。
Spring通过几个包对持久化提供了支持,与我们话题相关的,则主要是org.springframework.orm.hibernate3和org.springframework.orm.jpa。它们分别提供了对hibernate3和JPA的支持,目的在于提高代码效率和依赖注入。要利用hibernate3和JPA的完整特性,唯一可用的spring版本是2.0,目前处于m5阶段(尽管本文所使用的软件包,包括spring在内,都不是其最终发行版,但它们都足够可用了;此外,对于掌握一个有前途的新技术来说,付出一些调试的代价是值得的)。
使用Spring持久化支持的常用方法是使用DAO模式。在80%的情况下,对于Hibernate来说,也许只需要与org.springframework.orm.hibernate3.support.HibernateDaoSupport和org.springframework.orm.hibernate3.HibernateTemplate打交道就够了;相对应于JPA,则是org.springframework.orm.jpa.support.JpaDaoSupport和org.springframework.orm.jpa.JpaTemplate。
下面是一个典型的应用场景:
SomeDao是一个接口,定义了一组领域相关的持久化API;在不同的情况下,它可能有多种实现,比如Hibernate实现和JPA实现。不同的实现方式中,分别继承了相应的抽象基类DaoSupport,通过该基类,可以获得相应的Template类,以获得编程的便利性。在种Template类(这里是HibernateTemplate和JpaTemplate)中可以进行针对实体的各种操作,如保存、更新、删除、查询等。
当上述API不足以完成某些功能的时候,你可以非常容易的得到hibernate/JPA的原生API,甚至是返回到原始的JDBC,Spring在效率和功能之间取得了很好的平衡。
3.     从一个示例程序开始
为了验证和解释本文的观点,开发出一个示例程序,该示例程序演示了ORM应用中的一些实际需求:包括实体间的持久化映射和实体间的多种关系。
在此可以下载示例程序。目前的示例程序已经包含了“使用Annotation方式的持久化”和“使用JPA方式的持久化”两种应用场景完整演示。
示例程序在Eclipse 3.1.2环境下编写,并需要Java SE 5.0环境支持,数据库为hsqldb 1.8。
3.1     模型
示例程序模拟了一个与出版物相关的实体模型。这个模型可以用两种方式进行描述,一种的面向对象的方式,一种是面向数据库的方式。
采用面向对象的方式进行建模,得到如下类图:
在上图示例的模型中,有6类实体:
l        Publisher:出版商。每个出版商都有一个描述信息(PubInfo),出版商可以发行多种出版物(Title)。
l        PubInfo:出版商信息。
l        Title:出版物,可能包括图书(Book),以及其他可能的种类(如杂志)。
l        Book:出版物的一种。
l        Author:作者。每个作者都有联系方式(ContactInfo),作者自己可以创作多种出版物,当然也可以和其他作者合著。
l        ContactInfo:作者的联系方式。
实体间的关系包括:
l        一对一:一个出版商有一个描述信息。
l        多对一:一个出版商有多个出版物。
l        多对对:一个出版物可以有多个作者,一个作者可以有多部出版物
l        继承:出版物有多种类型,但它们都有一些共同的特征。
l        嵌入:作者有一个联系方式的属性。
面向数据库的模型可以用关系-实体图进行描述,在这里我们只用自然语言进行简单说明:
l        Publisher表:出版商,与Publisher类对应。
l        PubInfo表:出版商信息,与PubInfo类对应。
l        Title表:出版物,与Title类对应。
l        Book表:图书,与Book类对应
l        Author表:作者,与Author类和ContactInfo两个类对应。
l        TitleAuthor表:关系表,对应于Author表和Title表之间的多对多关系,没有直接对应的Java类。
3.2     程序结构
3.2.1     源代码
示例程序的代码组织如下:

说明
app.hbdemo
ApplicationContextFactory
加载spring的工具类
 
Test
程序入口
app.hbdemo.model
Author
作者
 
Book
图书
 
ContactInfo
联系方式
 
PubInfo
出版商信息
 
Publisher
出版商
 
Title
出版物
app.hbdemo.dao
PubsDao
DAO 接口
 
PubsDaoHibernate
DAO 的Hibernate实现
 
PubsDaoJpa
DAO 的JPA实现

 
3.2.2     配置文件
示例程序采用配置文件进行声明性编成,这些配置文件是:

类别
文件名
用途
组件配置
applicationContext.xml
主要的配置文件。定义了dataSource组件和导入文件。
 
hibernate-annotations.xml
定义了sessionFactory组件,为hibernate原生编程接口提供O/R映射信息。
 
hibernate-jpa.xml
定义了entityManagerFactory组件,与下面的 persistence.xml 一起 为JPA编程接口提供O/R映射信息。
 
dao-hibernate.xml
定义了Hibernate实现方式下的DAO组件。
 
dao-jpa.xml
定义了JPA实现方式下的DAO组件。
其他
META-INF/persistence.xml
JPA 风格的配置信息

 
3.2.3     数据库
示例数据库采用了In-Process模式的hsqldb,其数据库文件位于database目录下。
3.2.4     类库
依赖的主要类库包括:
l        hibernate3.jar(Hibernate Core 3.2.0 cr2)
l        hibernate-annotations.jar(Hibernate Annotations 3.2.0 cr1)
l        hibernate-entitymanager.jar(Hibernate EntityManager 3.2.0 cr1)
l        ejb3-persistence.jar(ejb3 persistence proposed final draft)
l        spring.jar(Spring framework 2.0 m5)
l        Hsqldb.jar(Hsqldb 1.8.0.4)
3.3     运行
示例程序采用eclipse开发,因此运行它的最简单方式就是将工程文件直接导入到eclipse中。
如果出现无法编译或运行错误,请检查一下内容:
l        JRE System Library设置是否正确;
l        hbdemolib设置是否正确,如果发生找不到某些类的错误,请设置好这个用户自定义库。
示例程序目前演示了hibenrate的两种编程模式: 使用Annotations方式的持久化使用JPA方式的持久化,要采用第一种方式,请取保配置文件applicationContext.xml中配置了如下内容:

    <!-- 使用 annotation 元数据映射和 hibernate 原生编程接口 -->
    <!--<import resource="hibernate-annotations.xml"/>
    <import resource="dao-hibernate.xml"/>-->
 
    <!-- 使用 annotation 元数据映射和 JPA 编程接口 -->
    <import resource ="hibernate-jpa.xml"/>
    <import resource ="dao-jpa.xml"/>

要采用第二种方式,请确保在配置文件applicationContext.xml中配置了如下内容:

    <!-- 使用 annotation 元数据映射和 hibernate 原生编程接口 -->
    <import resource ="hibernate-annotations.xml"/>
    <import resource ="dao-hibernate.xml"/>
 
    <!-- 使用 annotation 元数据映射和 JPA 编程接口 -->
    <!--<import resource="hibernate-jpa.xml"/>
    <import resource="dao-jpa.xml"/>-->

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值