Hibernate 的原理与配置
【导读】你是否听说过Hibernate的大名却对其知之甚少,或者一直渴望使用它进行开发?那么,这篇文章正是你期待已久的宝典!本文将重点介绍Hibernate的核心API调用库和基本配置,通过一系列介绍,让你对ORM(对象/关系映射)及其优点有深刻的认识。
【初探Hibernate】
让我们从一个简单的例子开始,展现Hibernate的魅力。如同众多经典计算机文章从“hello, world”的例子入手,我们的示例程序也将从相对简单的场景出发,阐述Hibernate的开发方法。要真正了解Hibernate的核心思想,仅仅在屏幕上打印字符是远远不够的。在我们的示例中,我们将创建对象,并将其保存在数据库中,然后进行更新和查询。
【阅读导航】
一、 “Hello World”示例程序:让你对Hibernate有一个简单的认识。
二、 理解Hibernate的架构:介绍Hibernate接口的主要功能。
三、 核心接口:Hibernate有5个核心接口,通过这些接口,开发人员可以存储和获取持久对象,并进行事务控制。
四、 重要的术语Type:Type是Hibernate中的一个基础而强大的元素,一个Type对象能将Java类型映射到数据库表的字段中。
五、 策略接口:Hibernate与某些其他开源软件不同的还有一点——高度的可扩展性,这通过其内置的策略机制来实现。
六、 基础配置:Hibernate可以配置成可在任何Java环境中运行,通常被用在2-3层的C/S模式的项目中,并被部署在服务端。
接下来,我们将详细这些内容。
【“Hello World”示例程序详解】
这个简单的持久类Message包含了一些属性,如id、文本内容、以及指向下一条消息的指针。其中,id属性用于唯一标识每条消息,通常对应数据库中的主键。如果多个Message实例拥有相同的id,那么它们代表数据库表的同一个记录。
Message类的代码遵循JavaBean的代码风格,并且有一个无参数的构造函数。在后续的代码中,我们将继续沿用这种风格来编写持久类的代码。
通过Hibernate,我们可以方便地操作这些持久类,将其实例存储在数据库中,并从数据库中查询出来,将信息展示给用户。这个过程将涉及到Hibernate的核心API调用和配置。
【总结】
本文向你介绍了Hibernate的核心概念和基本配置,通过一个简单的“Hello World”示例程序,展示了Hibernate的开发方法。通过深入了解Hibernate的架构、核心接口、Type术语、策略接口以及基础配置,你将能够更轻松地使用Hibernate进行开发。在接下来的文章中,我们将继续深入Hibernate的更多高级特性和使用方法。Hibernate是一个强大的对象关系映射工具,它能将Java对象与数据库无缝地连接起来。在这个特殊的场景中,我们有一个名为Message的普通Java类,Hibernate会自动管理这个类的实例,并将其持久化到数据库中,尽管Message类并没有实现任何特定的Hibernate类或接口。
创建一个新的Message实例就像这样:
```java
Message message = new Message("Hello World");
System.out.println(message.getText());
```
这段代码会打印出“Hello World”,这正是我们期望的结果。我们的目标不仅仅是如此。Hibernate与EJB容器等环境在持久层的实现上有显著的不同。我们的持久类(如Message类)可以在与容器无关的环境中使用,不像EJB那样必须依赖特定的容器才能运行。
为了展示这一点,让我们看一下如何将新的消息保存到数据库中。代码片段如下:
```java
Session session = getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
Message message = new Message("Hello World");
session.save(message);
txmit();
session.close();
```
```sql
insert into MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID) values (..., 'Hello World', ...)
```
你可能会问,MESSAGE_ID字段被初始化为多少呢?因为我们并没有为message对象的id属性赋予初始值。实际上,Hibernate会对id属性进行特殊处理。作为一个对象的唯一标识,当我们调用save()方法时,Hibernate会自动为它赋予一个唯一的值。这个值的生成方式将在后面的内容中详细介绍。
假设你已经在数据库中创建了一个名为MESSAGE的表。现在,你已经将Message对象存入数据库中了,接下来是如何将它们检索出来。以下代码将按照消息正文的字母顺序,从数据库中检索所有的Message对象,并将它们打印到屏幕上。
在这个过程中,你可能会对find()方法的参数感到困惑:“from Message as m order by m.text asc”。这是Hibernate自己的查询语言,全称为Hibernate Query Language(HQL)。通俗地讲,HQL与SQL的关系就像是方言与普通话之间的关系。在find()调用时,Hibernate会将这段HQL语言翻译成相应的SQL语句来执行。
最终的运行结果会是:
```vbnet
1 message(s) found:
Hello World
```
所有的SQL语句都是Hibernate幕后生成的精彩之作。或许你会觉得仅仅依靠代码Hibernate无法将Message类永久保存。确实如此,我们还需要更多的信息,那就是映射定义表。这个表在Hibernate中是以XML格式呈现的,它详细说明了Message类的属性是如何与数据库中的MESSAGES表的字段一一对应的。让我们看一下示例程序的映射配置文件清单。
示例程序的对象关系映射表是这样的:
这份文档向Hibernate揭示了如何将Message类映射到MESSAGES表中。例如,Message类的id属性与表的MESSAGE_ID字段相对应,text属性与表的MESSAGE_TEXT字段相对应,而nextMessage属性则展示了一个多对一的关系,它与表中的NEXT_MESSAGE_ID字段相对应。与其他开源项目相比,Hibernate的配置文件其实更容易理解。你可以轻松修改和维护它。只需定义好持久类与数据库中表字段的对应关系,Hibernate就会自动为你生成SQL语句,对Message对象进行增删改查操作。你甚至可以不需要写一句SQL语句,甚至不需要懂得SQL语言!
现在让我们做个小实验。我们先取出第一个Message对象,然后修改它的消息正文,再创建一个新的Message对象,并将其作为第一个Message对象的下一条消息。以下是相关的代码:
Session session = getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
// 1 是第一条消息的生成id
Message message = (Message) session.load(Message.class, new Long(1));
message.setText("Greetings Earthling");
Message nextMessage = new Message("Take me to your leader (please)");
message.setNextMessage(nextMessage);
txmit();
session.close();
如果我们运行一段代码来打印数据库中所有的Message对象,我们会发现结果清晰明了,例如:“2条消息找到:Greetings Earthling,Take me to your leader (please)”。通过这个简单的示例,我们对Hibernate有了初步的认识。接下来,我们将深入了解Hibernate的主要API调用。
在理解Hibernate的架构时,首先要熟悉其编程接口。Hibernate的API设计简洁明了,尽管由于ORM的复杂性,其API并不简单。但别担心,我们不需要一下子了解所有的接口。在应用层与持久层之间,应用层充当了持久层的客户端角色。但在某些简单的项目中,这两层并没有严格的区分。在这种情况下,你可以将它们合并为一层。
Hibernate的接口可以分为几种类型:一是用户应用程序调用的接口,用于完成创建、读取、更新、删除和查询操作,如Session、Transaction和Query接口;二是用于读取配置文件的接口,如Configuration类;三是回调接口,允许应用程序对事件的发生作出响应;四是用于扩展Hibernate映射机制的接口,如UserType、CompositeUserType和IdentifierGenerator。
在Hibernate中,JDBC、JTA和JNDI等J2EE技术得到了广泛应用。JDBC作为支持关系数据库操作的基础层,与JNDI和JTA结合,使Hibernate能方便地集成到J2EE应用服务器中。虽然在这里我们无法详细讨论Hibernate API中的所有方法,但我们可以简要介绍每个主要接口的功能。如果你想了解更多,可以查阅Hibernate源码包中的相关子包。
核心接口中的Session接口是Hibernate开发人员最常用的接口之一。它是一个轻量级的类,创建和销毁成本低,适合在客户程序中频繁创建和销毁。Session可以看作是一个持久对象的缓冲区,能够检测到这些持久对象的改变并刷新数据库。有时我们也称Session为持久层管理器,因为它包含了一些与持久层相关的操作,如将持久对象存储到数据库以及从数据库中获取它们。值得注意的是,Hibernate的Session不同于JSP应用中的HttpSession。在开发过程中保持对Session的正确管理是非常重要的。通过理解并有效使用这些核心接口,我们能够更加高效地使用Hibernate进行开发。当我们Hibernate中的session时,我们主要关注的是其核心的session功能。session这个词在使用时特指Hibernate中的数据会话,而对于Http Sesion对象,我们通常称之为用户session。
我们来看SessionFactory接口。这个接口遵循了工厂模式的设计原则。用户程序通过SessionFactory来创建session的实例。尽管SessionFactory并不是轻量级的,但它的设计初衷是为了在整个应用中实现共享。在实际应用中,一个项目往往只需要一个SessionFactory即可满足需求。当项目需要与多个数据库交互时,每个数据库对应一个SessionFactory。
SessionFactory在Hibernate中起到了缓冲的作用,存储了Hibernate自动生成的SQL语句和其他映射数据,甚至包括未来可能重复利用的数据。这种设计有效提升了数据的处理效率。
接着是Configuration接口,它的主要作用是对Hibernate进行配置和启动。在Hibernate启动过程中,Configuration类的实例负责定位映射文档,读取配置信息,并创建SessionFactory对象。虽然它在整个Hibernate项目中扮演的角色较小,但却是启动Hibernate时不可或缺的部分。
再来说说Transaction接口。这是一个可选的API,你可以选择使用Hibernate底层的事务处理代码,或者实现自己的事务管理。Transaction接口是对实际事务的抽象,包括JDBC事务、JTA中的UserTransaction,甚至是CORBA事务。这样的设计使得开发者可以使用统一的事务操作界面,方便项目在不同环境和容器之间迁移。
至于Query和Criteria接口,它们为数据库查询提供了便利。Query接口支持HQL语言或本地数据库的SQL语句,可以绑定查询参数、限制查询记录数量,并执行查询操作。Criteria接口与Query接口类似,允许你创建并执行面向对象的标准化查询。值得注意的是,Query接口是轻量级的,必须在session的上下文中使用。
另外还有一个重要的术语——Type。在Hibernate架构中,Type是一个基础而强大的元素。一个Type对象能将Java类型映射到数据库表的字段中。这种设计使得Hibernate具有高度灵活性和扩展性。Hibernate内置了许多type类型,包括所有的Java基本类型,并且还支持用户自定义type。通过实现UserType和CompositeUserType接口,你可以创建自己的type,如Address、Name等,从而提升项目的便利性和代码优雅性。
除了上述接口和术语,Hibernate还有Callback接口和一系列策略接口。Callback接口用于在持久对象的载入、存储、删除等事件发生时通知Hibernate。虽然Callback接口在用户程序中不是必需的,但在创建审计日志时可能会用到。而Hibernate的策略机制则赋予了它高度的可扩展性,这是与其他一些开源软件不同的地方。
Hibernate是一个功能强大、设计灵活的持久层框架,通过深入了解其各个接口和术语,我们可以更好地利用它构建高效、优雅的项目。Hibernate是一个强大的ORM框架,它允许开发者通过简单的Java代码与数据库进行交互。当Hibernate的某些默认功能无法满足我们的需求时,我们可以通过实现其提供的策略接口来扩展或替换其功能。Hibernate暴露了一系列策略接口,允许开发者根据自己的需求进行定制。
主键生成、本地SQL支持、缓冲机制、JDBC连接管理、事务管理、ORM策略、属性访问策略以及代理对象的创建等都是Hibernate的核心策略接口。只需要继承这些接口的默认实现,然后实现自己的逻辑,就可以轻松地扩展Hibernate的功能。
那么,开发者是如何获取Session的呢?Session是Hibernate中用于与数据库进行交互的主要接口。要获取Session,首先需要进行基础配置,创建一个SessionFactory对象。SessionFactory是线程安全的,只需要创建一次,然后在应用程序的生命周期中使用。
为了创建一个SessionFactory对象,需要创建一个Configuration类的实例,并处理映射文件。映射文件描述了Java类与数据库表之间的映射关系。将这些映射文件交给Configuration对象处理后,就可以创建一个SessionFactory对象。
在实际项目中,Hibernate可以在两种环境下运行:可管理环境和不可管理环境。可管理环境如J2EE服务器,提供了资源管理、事务管理和安全定义等功能。而不可管理的环境如servlet容器环境,只能提供一些基本的功能,事务处理、资源管理等都需要由应用程序自己定义。
对于开发者来说,大部分时间里都是在可管理的环境下工作。在这种情况下,Hibernate会将自己集成在J2EE环境中。创建SessionFactory的工作非常简单,只需从Configuration类创建一个实例,然后添加资源(映射文件)并设置属性即可。
映射文件的位置和命名都有特定的约定。默认情况下,映射文件以.hbm.xml为扩展名,并且每个持久类都应有一个独立的映射文件,以便于维护和管理。这些映射文件应放在classpath下的特定位置,以便Configuration类能够找到并处理它们。
Hibernate提供了丰富的策略和接口,允许开发者根据自己的需求进行定制和扩展。通过理解并善用这些策略和接口,开发者可以更加灵活地运用Hibernate,满足各种复杂的需求。Hibernate建议为每个持久类都创建一个与其同名的映射文件,并将其保存在与持久类相同的目录下。这样的组织方式清晰明了,就像在我们的示例程序中,Message持久类被放置在hello目录下,相应的映射文件也命名为Message.hbm.xml。这种结构避免了像struts项目中的“struts-config.xml地狱”这样的问题,使得管理更为简便。
如果你不遵循这一规则,你需要手动使用addResource()方法来加载每一个映射文件。如果你遵循这一建议,只需使用addClass()方法,就能轻松地将持久类和其映射文件一起载入。以下是一段示例代码:
SessionFactory sessions = new Configuration()
.addClass(hibernate.auction.model.Item.class)
.addClass(hibernate.auction.model.Category.class)
.addClass(hibernate.auction.model.Bid.class)
.setProperties(System.getProperties())
.buildSessionFactory();
Hibernate的映射文件具有许多其他配置选项,包括数据库连接的设定,以及能够改变Hibernate运行时行为的一些设定。尽管所有的设置可能看起来相当复杂,但你不必过于担心,因为Hibernate为大多数值都设定了合理的默认值,你只需要修改这些配置文件中的一小部分即可。
你可以通过以下几种方式来修改Hibernate的系统配置参数:
1. 创建一个Java.util.Properties实例并将其作为参数传递给Configuration类的setProperties()方法。
2. 在启动Hibernate时使用Java –Dproperty=value的方式设置值。
3. 在classpath可找到的路径下创建一个名为hibernate.properties的配置文件。
4. 在classpath可找到的路径下创建一个名为hibernate.cfg.xml的文件,并在其<property>标签中定义属性值。
以上就是关于Hibernate的大致介绍。如果你希望了解更多,现有的介绍还远远不够。我将陆续分享更多关于Hibernate的资料。但毫无疑问的是,它确实是一个出色的持久层解决方案!无论你是初学者还是经验丰富的开发者,Hibernate都能为你提供强大的功能和灵活的解决方案。
编程语言
- Hibernate 的原理与配置
- PHP实现原生态图片上传封装类方法
- PHP封装的svn类使用内置svn函数实现根据svn版本号
- php正则替换处理HTML页面的方法
- 基于jquery实现三级下拉菜单
- ASP.NET Core处理管道的深入理解
- PHP+redis实现添加处理投票的方法
- ASP.NET WebAPI2复杂请求跨域设置的方法介绍
- jQuery实现的经典竖向伸缩菜单效果代码
- 百度编辑器Ueditor增加字体的修改方法
- Bootstrap Table使用方法解析
- ES6中Math对象新增的方法实例详解
- 每个程序员需掌握的20个代码命名小贴士
- mysql 5.7.21解压版安装配置方法图文教程(win10)
- 详谈jQuery Ajax(load,post,get,ajax)的用法
- php cookie工作原理与实例详解