Hibernate是一个免费的开源Java包,它使得与关系数据库打交道变得十分轻松,就像您的数据库中包含每天使用的普通Java对象一样,同时不必考虑如何把它们从神秘的数据库表中取出(或放回到数据库表中)。它解放了您,使您可以专注于应用程序的对象和功能,而不必担心如何保存它们或稍后如何找到它们。
历史与背景
大多数应用程序都需要处理数据。Java应用程序运行时,往往把数据封装为相互连接的对象网络,但是当程序结束时,这些对象就会消失在一团逻辑中,所以需要有一些保存它们的方法。有时候,甚至在编写应用程序之前,数据就已经存在了,所以需要有读入它们和将其表示为对象的方法。手动编写代码来执行这些任务不仅单调乏味、易于出错,而且会占用整个应用程序的很大一部分开发工作量。
优秀的面向对象开发人员厌倦了这种重复性的劳动,他们开始采用通常的"积极"偷懒做法,即,创建工具,使整个过程自动化。对于关系数据库来说,这种努力的最大成果就是对象/关系映射(ORM)工具。
这类工具有很多,从昂贵的商业产品到内置于J2EE中的EJB标准。然而,在很多情况下,这些工具具有自身的复杂性,使得开发人员必须学习使用它们的详细规则,并修改组成应用程序的类以满足映射系统的需要。由于这些工具为应付更加严格和复杂的企业需求而不断发展,于是在比较简单和常见的场景中,使用它们所面临的复杂性反而盖过了所能获得的好处。这引起了一场革命,促进了轻量级解决方案的出现,而Hibernate就是这样的一个例子。
Hibernate的工作方式
Hibernate不会对您造成妨碍,也不会强迫您修改对象的行为方式。它们不需要实现任何不可思议的接口以便能够持续存在。惟一需要做的就是创建一份 XML"映射文档",告诉Hibernate您希望能够保存在数据库中的类,以及它们如何关联到该数据库中的表和列,然后就可以要求它以对象的形式获取数据,或者把对象保存为数据。与其他解决方案相比,它几乎已经很完美了。
由于本文只是一篇介绍性的文章,所以不会引入构建和使用 Hibernate映射文档的具体例子(我在《Hibernate: A Developer"s Notebook》一书的头几章中已经介绍了一个例子)。此外,在网上和Hibernate的在线文档中,还可以找到一些不错的例子,请参见下面的"其他信息"部分。它实际上相当直观。应用程序对象中的属性以一种简单而自然的方式与正确的数据库结构相关联。
运行时, Hibernate读取映射文档,然后动态构建Java类,以便管理数据库与Java之间的转换。在Hibernate中有一个简单而直观的API,用于对数据库所表示的对象执行查询。要修改这些对象,(一般情况下)只需在程序中与它们进行交互,然后告诉Hibernate保存修改即可。类似地,创建新对象也很简单;只需以常规方式创建它们,然后告诉Hibernate有关它们的信息,这样就能在数据库中保存它们。
Hibernate API学习起来很简单,而且它与程序流的交互相当自然。在适当的位置调用它,就可以达成目的。它带来了很多自动化和代码节省方面的好处,所以花一点时间学习它是值得的。而且还可以获得另一个好处,即代码不用关心要使用的数据库种类(否则的话甚至必须知道)。我所在的公司就曾有过在开发过程后期被迫更换数据库厂商的经历。这会造成巨大的灾难,但是借助于Hibernate,只需要简单地修改Hibernate配置文件即可。
这里的讨论假定您已经通过创建Hibernate映射文档,建立了一个关系数据库,并且拥有要映射的Java类。有一个Hibernate"工具集"可在编译时使用,以支持不同的工作流。例如,如果您已经拥有Java类和映射文档,Hibernate可以为您创建(或更新)必需的数据库表。或者,仅仅从映射文档开始,Hibernate也能够生成数据类。或者,它可以反向设计您的数据库和类,从而拟定映射文档。还有一些用于Eclipse的alpha 插件,它们可以在IDE中提供智能的编辑支持以及对这些工具的图形访问。
如果您使用的是Hibernate 2环境,这些工具鲜有提供,但是存在可用的第三方工具。
使用Hibernate的场合
既然Hibernate看起来如此灵活好用,为什么还要使用其他的工具呢?下面有一些场景,可以帮助您做出判断(或许通过提供一些比较和上下文,可以有助于鉴别非常适用Hibernate的场合)。
如果应用对于数据存储的需要十分简单--例如,您只想管理一组用户优先选择--您根本不需要数据库,更不用说一个优秀的对象-关系映射系统了(即使它也如Hibernate这般易于使用)!从Java 1.4开始,有一个标准的Java Preferences API可以很好地发挥这个作用。(在ONJava文章中可以找到有关Preferences API的更多信息。)
对于熟悉使用关系数据库和了解如何执行完美的SQL查询与企业数据库交互的人来说,Hibernate似乎有些碍手碍脚,这就像带有动力和自动排挡的快艇车会使注重性能的赛车驾驶员不耐烦一样。如果您属于这种人,如果您所在的项目团队拥有一个强大的DBA,或者有一些存储过程要处理,您可能想研究一下iBATIS。 Hibernate的创建者本身就把iBATIS当作是另一种有趣的选择。我对它很有兴趣,因为我们曾为一个电子商务站点开发了一个类似的系统(其功能更为强大),而且从那时到现在,我们已经在其他环境中使用过它,尽管在发现Hibernate之后,在新项目中我们通常更喜欢使用Hibernate。您可以认为,以SQL为中心的解决方案(比如iBATIS)是"反向的"对象/关系映射工具,而Hibernate是一个更为传统的ORM。
当然,还有其他的外部原因会导致采用另外的方法。比如,在一个企业环境中,必须使用成熟的EJB架构(或者其他的一些非普通对象映射系统)。可以为提供自己的数据存储工具的平台量身定做代码,比如Mac OS X"s Core Data。使用的可能是像XML DTD这样的存储规范,而它根本不涉及关系数据库。
但是,如果您使用的是富对象模型,而且想要灵活、轻松且高效地保存它(无论您是否正要开始或已经决定使用关系数据库,只要这是一个选择--而且存在可用的优秀免费数据库,比如MySQL,或可嵌入Java的HSQLDB,它就应该始终是一个选择),那么Hibernate很可能就是您理想的选择。您可能会惊讶于节省的时间之多,以及您将会多么地喜欢使用它。
其他信息
Hibernate项目有大量的在线文档,可以帮助您找准方向,快速开始使用。
权威性的参考资料是Hibernate in Action,作者是Christian Bauer和Gavin King,都是Hibernate的创建者。该书全面而基础地讲述了Hibernate包的功能和正确的使用方法。
阅读我的书Hibernate: A Developer"s Notebook,也是一种快速上手的好方法。它直接但详细地讲述了如何在Java项目中设置Hibernate,以及如何使用它的一些最重要的功能。其中的代码示例普遍基于Hibernate和HSQLDB的早期版本,所以如果您想不加改动地使用它们,需要使用这两种软件的正确版本。无论如何,基本的概念是正确的,而且我希望能够尽快地针对Hibernate 3更新本书。
另一本有趣的书是Better Faster Lighter Java,作者是Bruce Tate 和Justin Gehtland。书中给出了一些实用方法,可以以合理的方式完成实际的项目,这也是它流行的原因之一。它在如何评估和使用(或否决)可用的Java技术方面给出了合理建议,并作为正确方法的例子提到了Hibernate和Spring。
最后,"Working with Hibernate in Eclipse"(它预先提到了更强大的新的alpha版的Hibernate 3工具)中详细讲述了如何将一个叫做Hibernate Synchronizer的Eclipse插件与Hibernate一起使用。