第十五章 Hibernate应用详解 Hibernate是一个基于Java的对象/关系数据库映 射工具,它将对象模型表示的数据映射到用SQL表 示的关系模型上去。Hibernate管理Java到数据库 的映射,还提供了数据查询和存取的方法,大幅 度减少开发者的数据持久化相关的编程任务。在 本章内容中,首先介绍对象关系映射(ORM)及 Hibernate的基本概念,再详细介绍关于 Hibernate的持久化对象以及ORM的详细内容和 Hibernate查询相关知识。通过本章的学习,读者 可以从整体上了解Hibernate,并学习使用 Hibernate做数据持久化工作。
15.1 Hibernate简介 在当今的软件开发过程中,同时使用面向对象和 关系数据库是一件耗时和头痛的工作。Hibernate 是一个开源的对象/关系数据库映射工具,它的目 标是较少应用开发过程中数据持久层的编程任务。 将开发人员从繁杂的持久化层开发过程中解放出 来。在本节中,将对对象关系映射以及Hibernate 做基本的介绍。
15.1.1 对象持久化与ORM 什么是持久化?简单地说,持久化就是把数据同 步保存到数据库或者某些存储设备中。在软件的 分成体系结构中,持久化是和数据库打交道的层 次。在数据库中对数据的增加、删除、查找和修 改都是通过持久化来完成的。在常见的JSP相关的 Web开发中,经常有很多相关的数据库连接、查询 等操作语句,这是把数据库相关的持久化工作和 展现以及一些业务处理耦合在一起,这将使前期 的代码编写和后期的工程维护都相当困难。
15.1.2 Hibernate架构概述 Hibernate作为ORM映射工具,了解其整体架构对 Hibernate的工作原理和以后介绍到的如何使用将 有指导性的作用。Hibernate的高层架构图如图 15.1所示。这个图显示了Hibernate利用数据库和 配置数据向应用程序提供持久化服务和持久化对 象。(具体内容请参照书。)
15.1.3 开发环境的简单配置 为了开发基于Hibernate应用,都需要一些数据库 服务器,在此采用Mysql数据库,可以在下载/安 装。Hibernate开发环境的配置方法比较简单,可 以在http://www.hibernate.org下载Hibernate的 发布包,把下载下来的压缩文件解压到硬盘中, 然后把hibernate.jar和其他相关类库加入项目即 可。
15.2 Hibernate配置和相关类 在使用Hibernate过程中,会发现Hibernate提供 很多类,但常用的不会很多。其中最核心的就是 关于整体数据库的配置文件和与之相关的类,在 此对这些进行说明。Hibernate被设计为可以在不 同的环境下工作,所以有很多配置参数,不过很 多参数已经有默认值了,所以配置较少的参数就 可以运行了。
15.2.1 Configuration类 Configuration类负责管理Hibernate的配置信息, 一个Configuration类的实例代表了应用程序中 Java类到数据库的映射的集合。应用程序通常只 是创建一个Configuration实例,并通过它创建 SessionFactory实例。例如下面的代码: SessionFactory sessionFactory = new Configuration().configure().buildSessionFac tory();
15.2.2 Hibernate配置文件 这里我们来重点分析一下Hibernate配置文件,以 现在最常用的hibernate.cfg.xml格式的配置文件 做说明。这个配置文件默认会期望在类路径的根 目录中找到。
15.2.3 SessionFactory类 SessionFactory负责Session实例的创建。为了创 建一个SessionFactory对象,必须在Hibernate初 始化时创建一个Configuration类的实例,并将已 写好的映射文件交由它处理。这样, Configuration对象就可以创建一个 SessionFactory对象,当SessionFactory对象传 教成功后,Configuration对象就没有用了,可以 简单地抛弃它。例如下面的实例代码: Configuration config = new Configuration().configure(); SessionFactory sessionFactory = config.buildSessionFactory();
15.2.4 Session管理 Session是Hibernate运作的核心,对象的声明周 期、事务的管理、数据库的存取都与它密切相关。 所以有效地管理Session成为使用Hibernate的重 点。从上面的描述可以知晓,Session是由 SessionFactory所创建。SessionFactory是线程 安全的,可以让多个线程同时存取 SessionFactory对象而不会引起数据共享的问题。 可是Session不是线程安全的,所以让多个线程共 享一个Session,会引起冲突和混乱的问题。
15.3 Hibernate中的对象 Hibernate中对象有三种状态,临时对象 (Transient Objects)、持久化对象 (Persistent Objects)和脱管对象(Detached Objects)。理解这集中对象,对Hibernate中关 于持久化处理是很有帮助的,这一节将对这几种 对象做说明。
15.3.1对象在Hibernate的状态 如图15.3所示,显示了Hibernate中临时对象、持 久化对象和托管对象之间的关系,它们之间的转 换。下面就对这三种状态进行解释。 (1)临时状态 (2)持久化状态 (3)脱管状态(具体内容请参照书。)
15.3.2 持久化类 上面所述的三种对象状态,在编程过程中就体现为持久化 类的实例 15.3.2 持久化类 上面所述的三种对象状态,在编程过程中就体现为持久化 类的实例 持久化类是应用程序用来解决商业问题的类(如我们将在 下面提到的Customer类)。持久化类的实例通过Hibernate 持久化管理层,将保存到数据库中的。 持久化类只需要符合简单的规则,也就是POJO(Plain Old Java Object)编程模型,Hibernate就会工作的很好。但 是这些规则不是硬性要求的,最新的Hibernate对持久化对 象的要求很少,你可以用自己的方法表示持久化对象。
15.3.3 对象识别 实现equals()和hashCode()最显而易见的方法是 比较两个对象标识符的值。如果值相同,则两个 对象对应于数据库的同一行,因此它们是相等的 (如果都被添加到 Set,则在Set中只有一个元 素),不幸的是,对生成的标识不能使用这种方 法。Hibernate仅对那些持久化对象赋标识值,一 个新创建的实例将不会有任何标识值。此外, 如 果一个实例没有被保存(unsaved),并且它当前正 在一个Set中,保存它将会给这个对象 赋一个标 识值。如果equals() 和 hashCode()是基于标识 值实现的,则其哈希码将会改变,这违反了Set的 契约。
15.4 Hibernate中对象关系映射 Hibernate的本质就是对象关系映射。映射文件就 是将对象和关系数据库关联的纽带,在Hibernate 中,映射文件通常以.hbm.xml作为后缀的。对象 和关系数据库之间的映射通常是用一个XML文档来 定义的。这个映射文档被设计为易读的, 并且可 以手工修改。映射语言是以Java为中心,这意味 着映射文档是按照持久化类的定义来创建的, 而 非表的定义。虽然很多Hibernate用户选择手写 XML映射文档,但也有一些工具可以用来生成映射 文档, 包括XDoclet,Middlegen和AndroMDA。
15.4.1 基本类映射 (具体内容请参照书。)
15.4.2 主键策略 在关系数据库中,以主键来区分不同的记录。 Hibernate的主键策略分为3大类: 15.4.2 主键策略 在关系数据库中,以主键来区分不同的记录。 Hibernate的主键策略分为3大类: Hibernate对主键id赋值; 应用程序对id赋值; 由数据库对id赋值
15.4.3 多表对象关系映射 多表映射主要是一对一、一对多(多对一)和多 对多映射,下面分别对这些映射做分析。(具体 内容请参照书。)
15.4.4 组件映射 组件(Component)是一个被包含的对象,在持久化 的过程中,它被当作值类型,而并非一个实体的 引用。在这篇文档中,组件这一术语指的是面向 对象的合成概念(而并不是系统构架层次上的组 件的概念)。
15.5 操作持久化数据 有了持久化对象,则可以利用Hibernate API对其 进行操作,间接地把持久化类中的属性信息通过 底层的JDBC API同步到数据库中。这一节来说明 怎么操作持久化数据。
15.5.1 Session缓存与持久化操作 在15.3节中,我们提到Hibernate中对象的状态, 提到持久化对象不会立即同步到数据库中。在此 有必要对Session的flush做些说明。每间隔一段 时间,Session会执行一些必需的SQL语句来把内 存中的对象的状态同步到JDBC连接中。这个过程 被称为刷出(flush),默认会在下面的时间点执行:
15.5.2 利用DAO来操作数据 在操纵持久化数据时,直接利用Session提供的方 法,可能对数据操作的封装粒度太小,在实际开 发过程中一般都不好使用。在此引入DAO(Data Access Object)的概念,他是持久化对象的客户 端,负责所有与数据库操作相关的逻辑。例如数 据查询、增加、删除、更新等,在这里提供一个 关于Customer的DAO的例子,开如何开发DAO操作 数据,提供给高层应用更抽象的API。
15.6 Hibernate数据查询 Hibernate支持强大且易于使用的面向对象查询语 言(HQL)。如果希望通过编程的方式创建查询, Hibernate提供了完善的按条件(Query By Criteria, QBC)以及按样例(Query By Example, QBE)进行查询的功能。你也可以用原生 SQL(native SQL)描述查询,Hibernate额外提供 了将结果集(result set)转化为对象的支持。其 中最重要的一种就是HQL(Hibernate Query Language)。
15.6.1 HQL检索方式 Hibernate配备了一种非常强大的查询语言,这种 语言看上去很像SQL。但是不要被语法结构 上的 相似所迷惑,HQL是非常有意识的被设计为完全面 向对象的查询,它可以理解如继承、多态 和关联 之类的概念。(具体内容请参照书。)
15.6.2 条件查询 (1)创建一个Criteria实例 (2)限制结果集 内容(3)结果集排序 (4)关联(5)动态关 联抓取 (6)查询示例
15.6.3 本地SQL查询 你也可以使用你的数据库的Native SQL语言来查 询数据。这对你在要使用数据库的某些特性的时 候(比如说在查询提示或者Oracle中的 CONNECT关 键字),这是非常有用的。这就能够扫清你把原来 直接使用SQL/JDBC 的程序迁移到基于 Hibernate 应用的道路上的障碍。
15.7 小结 在这一章中,我们介绍了Hibernate的整体架构, Hibernate配置相关内容,并对Hibernate中对象 做了较为详尽的描述。重点介绍了对象关系映射 的配置和Hibernate数据的查询。通过本章学习, 能够对Hibernate技术有着详细的了解,为实际应 用中的数据层持久化工作开发打下坚实的基础。