什么是持久化 .
<!--[if !supportLists]-->1.1 <!--[endif]-->什么是持久化
几乎所有的程序都需要持久化数据。持久化是程序开发中的一个基础问题。当一个信息系统不能保存用户所输入的数据的时候,一旦主机出现诸如断电的故障,那么系统便变得毫无价值。当我们讨论java中的持久化的时候,我们通常指的是用SQL在关系型数据库中存取数据。我们从如何使用Java来完成这样的任务说起。然后我们就可以继续我们持久化的讨论,以及如何在面向对象的程序中去使用它们。
<!--[if !supportLists]-->1.1.1 <!--[endif]-->关系型数据库
和其他许多开发人员一样,你可能会和关系型数据库打交道。事实上,我们当中的大部分人都在使用关系型数据库。关系型技术已经被广泛使用。光这一点就足以成为许多公司选择它的原因了。但是光从口头上并不能体现它的价值。关系型数据库拥有强健和弹性的数据管理方法以至于遇到一些意外也不会造成系统的崩溃。
关系型数据并不是针对Java程序而设计的,当然也不是针对其他程序而设计的。关系型技术为不同的程序之间或同一程序的不同技术(例如事务引擎和报告引擎)之间提供了一种共享数据的方式。关系型技术也是许多毫不相干的系统和平台之间的共同特性。因此,关系型数据模型通常是企业级的业务模型的表现方式。
关系数据库管理系统使用提供了SQL的程序接口,因此,我们也可以把关系型数据库称之为SQL数据库管理系统或者我们也可以直接叫做SQL数据库。
1.1.2 理解SQL
为了更好地使用Hibernate,你可以理解关系模型以及SQL。你需要运用你的SQL的质量是来调试Hibernate的性能。对于许多需要在持久化反复做的工作,Hibernate会帮你的自动生成代码,但是如果你想利用好SQL数据库的话,那么你的持久化知识不能仅仅局限于Hibernate。应当知道底层的目标就是强健的,高效的管理持久化数据。
首先让我们浏览一下在本书中使用的SQL技术。你可以把SQL用作DDL(数据定义语言)去创建一个数据库定义,在这个过程中,你会使用到Create或者Alter语句。在创建表格之后,你还可以把SQL用作DML(数据控制语言)。通过DML,你可以达到控制和恢复数据的目的。你可以通过插入,更新和删除来完成数据控制,通过限定,投影和连接来完成数据的恢复。你可以通过group,order和aggregate操作来更好的输出数据。你甚至可以把一个SQL语句嵌套早另外一个语句里面来完成子查询。你可能使用SQL很多年了,已经非常熟悉其中的操作了。从我们自身的经验来看,SQL有时候不太容易记忆。为了理解本书,我们将使用SQL中相同的术语和概念,因此如果你对刚才所提到的概念不熟悉的话,我建议你去阅读一下附录A。
开发Java数据库应用程序的时候,SQL的知识是必备的。如果你需要了解更多细节的话,建议你去看一下Dan Tow的书SQL Tuning。你也可以阅读An Intrudction To Database Systems去获得有关数据库的理论,概念以及思想。关系型数据库只是ORM的一部分,另外一部分则来自Java程序中需要被持久化的对象。
<!--[if !supportLists]-->1.1.3 <!--[endif]-->在Java中使用SQL
当你在Java程序中使用SQL数据库的时候,你需要通过JDBC API来使用SQL。在Java中,你可以通过手工来写SQL,或者通过自动生成工具来生成SQL。你可以通过JDBC向SQL传递参数,发起查询,浏览结果,并且能够恢复数据。这些都是底层的数据访问任务,应用程序员关注的应该是业务逻辑,而不是这些数据访问。我们不应该关注这些呆板机械的工作。
我们真正需要关心的是如果向数据库存取复杂的数据,以及从数据库中恢复这些数据。
因为数据存取是如此的枯燥无聊,我们经常会问,关系数据模型以及SQL是面向对象持久化的正确选择吗?我们可以毫不犹豫的告诉你,是的。我可以列举许多理由来告诉你为什么SQL数据库能够支配计算机工业。关系型数据库管理系统也是唯一被证明的数据管理技术,当然在Java项目中也是经常被用到。
然而,在过去的15年里面,开发者经常会说的就是范式不匹配。这种不匹配解释了为什么我们每次在项目中都需要花费很大的精力去完成数据的持久化。这种范式指的是对象模型和关系模型,也可以是面向对象的编程和SQL。我们通过一个问题来探讨不匹配的问题,那就是在面向对象的开发中什么才是持久化。首先我们需要扩充一下我们在本章开头关于数据持久化的定义,这里给出的新的定义更加深入的描述数据的维护和存取。
<!--[if !supportLists]-->1.1.4 <!--[endif]-->面向对象程序中的持久化
在面向对象的程序中,持久化意味着一个对象的生命期可以超过创建它的程序。对象的状态可以被存储在磁盘中,将来在使用的时候可以将具有相同状态的对象恢复。
应用程序不仅仅局限于持久化单个对象,许多相互关联的对象都需要被持久化并在一个过程中被重新创建。但是大多数对象并不能被持久化,transient对象的生命期也仅仅有创建它的过程决定。几乎所有的java程序都包含大量的这种可以被持久化以及无法被持久化的对象,因此我们需要一个子系统来管理持久化数据。
现代的关系型数据库提供了结构化的数据表达方式,你可以对数据进行排序,查找以及聚集。数据库管理系统负责数据的并发控制和完整性;同时也负责管理在多个用户和程序中共享数据。数据库管理系统也提供了一个数据级的安全保护。当我们在本书中讨论持久化的时候,我们需要考虑下面这些事情:
<!--[if !supportLists]-->l <!--[endif]-->存储,组织和恢复结构化数据
<!--[if !supportLists]-->l <!--[endif]-->并发控制和数据完整性
<!--[if !supportLists]-->l <!--[endif]-->数据共享
尤其是我们需要在使用了领域模型的面向对象的环境中去考虑这些问题。
具有领域模型的应用程序并不能平滑的和业务实体进行对接,对于业务实体,这种应用程序通常有着自己的模型。如果数据库有一个ITEM和BID表,那么与此对应,Java应用程序也会定义ITEM和BID类。
为了避免和SQL结果集中的行和列直接打交道,业务逻辑通常会和面向领域的对象来打交道。业务逻辑从来都不是在数据库中执行(作为一个SQL存储过程),它们都是由Java来实现。
通过这种方式,业务逻辑可以使用面向对象中的概念,如继承和多态。举例来说,业务逻辑可以使用诸如Strategy,Mediator和Composite设计模式,这些都应用了多态的概念。在这里可能存在反对的声音:并不是所有的Java程序都是这样设计的。对于简单的应用来说,直接应用JDBC可能来的更直接,更容易理解,而且新版本的JDBC使操作数据也变得更加简单易用。直接使用表格化数据,更直接更容易理解。
但是,在业务逻辑比较复杂的程序中,领域模型能够使代码重用和维护变得更加有意义。在本书中我们关注的是领域模型,因为Hibernate和ORM关注也是这种类型的程序。
如果我们重新考虑SQL和关系数据库,那么就会发现两种范例之中存在着不匹配的情况。
SQL操作的结果通常以表格化的数据来表示。这个Java中对象之间的联系有很大的不同,它们是两种截然不同的模型,并不是同一模型的不同表达方式。
带着这种认识,我们来审视这些问题——一些已知的和一些未知的,这些都应该被连接着两种模型的应用程序来解决,包括面向对象的领域模型以及持久关系模型。