Hibernate简介

来源:互联网 发布:阿里云子目录绑定域名 编辑:程序博客网 时间:2024/05/16 14:25

大多数有一定规模的开发项目都涉及关系数据库。多数商业应用程序的核心是大型的有序信息存储库,比如编目、顾客列表、合同详细信息、出版的文章和建筑设计方案。

由于万维网的出现,对数据库的需求增长了。在线书店和在线报纸的顾客都要使用数据库,尽管他们可能不会意识到这一点。而实际上,在应用程序内部会查询数据库并提供响应。

Hibernate这样的对象-关系映射(Object-Relational Mapping,ORM)适合一部分解决方案,而对于其他情况,通过JDBC(Java Database Connectivity)API直接访问数据的传统方式可能更合适。我们认为Hibernate是很好的首选方式,因为使用他并不妨碍同时使用其他方式。

1.1 POJO

在理想环境中,获得任何Java对象并将它持久化到数据库中都应该是很轻松的。不需要为此编写特殊的代码,也不会有性能损失,而结果是完全可移植的。

没有特殊情况发生,不需要为类与数据库表的关联做任何额外的工作,也没有性能问题。

Hibernate已经非常接近这个理想目标了,至少与其他替代方式相比已经很方便了,但还是需要创建配置文件,而且要考虑微妙的性能问题。但无论如何,Hibernate实现了它的基本目标——使我们能够在数据库中存储POJO(Plain Old Java Object,普通Java对象)。图 1说明了Hibernate如何在客户机代码和数据库之间起到桥梁的作用。

clip_image002

图 1:Hibernate在Java应用程序中的角色

表示传统Java对象的直接持久化的常用术语是对象-关系映射——也就是说,将Java中的对象映射到数据库中的关系实体。

POJO可以是任何Java对象。Hibernate使我们能够对POJO进行持久化,而受到的限制却非常少。下面是一个简单的POJO示例,它代表一个消息。

/*** filename: Message.java*/package sample.entity;/*** @author: Sheldon Chen* @Date: 2010-8-28* @Time: 下午06:25:59* */public class Message {private int id;private String message;public Message(String message) {this.message = message;}Message() {}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}}

在这里,Hibernate需要的唯一东西是一个私有的默认构造器。Hibernate要求被存储的所有POJO都要提供一个默认构造器。但是,即使第三方类无法满足这个小小的要求,也是有其他解决方法的。

1.2 Hibernate和对象-关系映射的起源

如果Hibernate是一种解决方案,那么它所要解决的问题是什么呢?其一便是希望简化对象持久化的编程。这是因为在使用JDBC时需要编写相当多的代码,并且要仔细考虑各种规则(比如进行连接管理的那些规则),从而确保应用程序不会造成资源泄漏。即使在知道正确的消息标识符的情况下,用数据库中的数据填充下面的Motd对象也需要大量代码。

1.2.1 Hibernate作为持久化解决方案

Hibernate可以解决上述的许多问题,或者缓解某些问题,所以我们依次讨论Hibernate对这些问题的影响。

Hibernate不要求开发人员将POJO一一映射到表。可以由多个表列构造出一个POJO,也可以将几个POJO持久化到同一个表中。

Hibernate直接支持类之间的继承关系和各种其他关系。

尽管在Hibernate启动和处理配置文件阶段有一些性能开销,但总的来说,Hibernate被认为是一种很快速的工具。性能问题很难量化,对待所有性能问题,你都应该进行测试。而不是仅根据舆论趋势做出选择。

在Hibernate中,可以在部署时指定映射,但这不是必须的。Hibernate方式致力于减少在新环境中部署应用程序的代价。

Hibernate使用的POJO可以非常轻松自然地实现泛化,从而在其他应用程序中使用。对于Hibernate库没有直接的依赖性,所以POJO可以放进不需要持久化的环境中,也可以使用任何其他的“对POJO友好的”机制对它们进行持久化。

在处理可序列化POJO方面,Hibernate没有任何问题。

有许许多多现有的代码。任何能够持久化到数据库中的Java对象都适合进行Hibernate持久化。因此,Hibernate很自然地成为专用解决方案的替代品,也可以作为还没有集成数据库持久化功能的应用程序的持久化引擎。因此,通过选用Hibernate持久化,就不必亲自为应用程序中的业务对象做出任何特殊的设计决定。

1.3 Hibernate Hello World示例

 

/*** filename: ListMessages.java*/package sample;import java.util.List;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;import sample.entity.Message;/*** 消息应用程序.* * @author: Sheldon Chen* @Date: 2010-8-28* @Time: 下午06:33:21**/public class ListMessages {@SuppressWarnings("unchecked")public static void main(String[] args) {SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();Session session = sessionFactory.openSession();List<Message> messages = session.createQuery("FROM Message").list();for (Message message : messages) {System.out.println(message.getMessage());}session.close();sessionFactory.close();}}

一些额外的代码提供了JDBC示例不具备的功能(尤其是事务处理和缓存)。

1.4 映射

Hibernate需要有某个东西告诉它,哪些表与哪些对象相关(这一信息常常在一个XML映射文件中提供)。对于希望映射到数据库中的每个POJO,只需创建并关联一个短小简洁的映射文件。如果愿意的话,也可以使用一个单一配置文件,但这不是必须的,也不鼓励这样做。

为Hibernate的所有配置文件提供了一个DTD,所以在使用出色的XML编辑器创建配置文件时,应该能够利用文件的自动补全和自动检验功能。可以使用Java 5注解完全规制它们。

下面的代码Message.hbm.xml是将Message POJO映射进数据库的文件。

<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="sample.entity.Message" table="MESSAGE"><id type="int" column="id"><generator class="native"></generator></id><property name="message" column="message" type="string"></property></class></hibernate-mapping>

看起来复杂性似乎只是从应用程序代码转移到了XML映射文件中。但实际中,由于下述几个原因,情况并非如此。

首先,相比从结果集填充POJO的复杂过程,编辑这个XML文件要容易得多——而且,如果映射进数据库的对象在部署的后期发生了变化,那么修改起来也要容易很多。

其次,我们还避免了JDBC方式所需的复杂的错误处理。但是,这个原因可能是最不重要的,因为即使不借助于Hibernate,也有许多技术可以使错误处理尽可能简化。

最后,Hibernate可以解决对象的关联问题,开发人员可以从数据库中提取一个对象,这个对象与数据库中大量对象的引用相关联。Hibernate将其他提取操作延迟到实际方问这些对象的时候,这可以避免大量的内存开销并提高性能。

原创粉丝点击