第5章Hibernate5框架技术入门
在Java Web项目开发中,有许多功能模块需要连接数据库系统,实现对数据库表的操作。在Java程序设计和JSP程序设计技术中,使用JDBC技术连接数据库。为了实现与数据库的**操作,提高Java Web的项目性能,可以使用Hibernate5框架技术。本章主要介绍Hibernate5的基本内容。
本章主要内容如下所示。
(1) Hibernate5的发展与特点。
(2) Hibernate5的下载与配置。
(3) Hibernate5的工作原理。
(4) Hibernate5的核心组件。
(5) 基于Struts2 Hibernate5的登录和注册系统。
5.1Hibernate5��基础知识
Hibernate是封装了JDBC的一种开放源代码的对象关系映射(ObjectRelation Mapping,ORM)框架,使程序员可以使用面向对象的思想来操作数据库。Hibernate是一种对象关系映射的解决方案,即将Java对象与对象之间的关系映射到数据库表与表之间的关系。
5.1.1Hibernate5的发展与特点
目前,Hibernate是Java工程师招聘中要求**的一门技能,也是Java Web三大经典框架之一。Christian Bauer是Hibernate之父,现是Redhat公司负责开发和维护Hibernate的项目经理。
2001年,Hibernate1发布,即Hibernate的**个版本;2003年,Hibernate2发布,并在当年获得Jolt 2003大奖(Jolt大奖素有“软件业界的奥斯卡”的美誉,共设通用类图书、技术类图书、语言和开发环境、框架库和组件、***网站等十余个分类大奖),2003年,Hibernate被JBoss公司收购,成为该公司的子项目之一;2005年,JBoss发布Hibernate3;2006年,JBoss公司被Redhat公司收购; 2012年11月发布Hibernate 4.1.8,2015年3月发布Hibernate 5.0。
Hibernate是封装了JDBC与ORM技术的数据持久性解决方案。在Java世界中,Hibernate是众多ORM软件中获得关注*多、使用*广泛的框架。它成功地实现了透明持久化,以面向对象的HQL语句封装SQL语句,为开发人员提供了一个简单灵活且面向对象的数据访问接口。Hibernate是一个开源软件,开发人员可以很方便地获得软件源代码。当遇到问题时,程序员可以深入到源代码中查看究竟,甚至修改Hibernate内部错误并将修改方案提供给JBoss组织,从而帮助Hibernate框架技术改进。
Hibernate自发布以来受到业界的欢迎,目前许多Java程序员学习和使用它来开发商业应用软件。另外,网络上有大量介绍和讨论Hibernate应用的文章,JBoss网站也提供了一个完善的社区,所以一旦在使用中遇到问题,***可以轻松地在网络上搜索到相应的解决方法,这又进一步吸引了更多的程序员来学习Hibernate,吸引更多的公司采用Hibernate开发软件。
Hibernate为使用者考虑得十分周全,对于一个普通的程序员来说,只需学习不到10个类的用法就可以开发基于Hibernate框架的应用系统,实际使用起来十分方便。
Hibernate提供了透明持久化功能,支持第三方框架,即能与其他框架进行整合,如Struts、Spring等,不但提供面向对象的HQL,而且支持传统的SQL语句。
在基于MVC设计模式的Java Web应用中,Hibernate可以作为应用的数据访问层或持久层。它具有以下特点。
(1) Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java工程师可以随心所欲地使用面向对象编程思维来操作数据库。Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet、JSP的Java Web应用中使用,*具革命意义的是,Hibernate可以在Java EE框架中取代CMP,完成数据持久化的重任。
(2) Hibernate的目标是成为Java中处理数据持久性问题的一种完整解决方案。它协调应用程序与关系数据库的交互,把***解放出来专注于项目的业务逻辑问题。
(3) Hibernate是一种非强迫性的解决方案。***在写业务逻辑和持久化类时,不会被要求遵循许多Hibernate特定的规则和设计模式。这样,Hibernate就可以与大多数新的和现有的应用程序进行集成,而不需要对应用程序的其余部分做破坏性的改动。
5.1.2Hibernate5软件包的下载和配置
本书的实例和项目使用的是Hibernate 5.2.12版本,2017年10月发布,如需使用Hibernate其他版本进行Web项目开发,可以在其官方网站下载。
1. 软件包下载
由于Hibernate先被JBoss公司收购,后来JBoss被Redhat公司收购,所以Hibernate5可以在以下3个网站下载: www.redhat.com、www.jboss.org和www.hibernate.org。根据需要在上述3个网站下载自己要使用的Hibernate版本。官方页面之一如图51所示。
单击图51所示页面中的Hibernate ORM,出现图52。
单击图52所示页面中的选择点5.2后,出现如图53所示的版本选择页面,在该页面的下方选择5.2.12.Final区域中的Download进行下载。
单击图53所示页面中Download后,出现如图54所示的下载页面,选择下载路径后进行下载。
2. Hibernate5软件包中主要文件
解压缩hibernaterelease5.2.12.Final.zip文件后得到一个名为hibernaterelease5.2.12.Final的文件夹,该文件夹结构如图55所示。图51Hibernate官方页面
图52选择下载页面
图53版本选择页面图54选择下载文件下载
图55Hibernate5文件夹结构
(1) documentation文件夹: 该文件夹中存放了Hibernate5的相关文档,包括Hibernate5的参考文档和API文档等。
(2) lib文件夹: 该文件夹存放Hibernate5框架的核心类库以及Hibernate5的第三方类库。该文件夹下的required子目录存放运行Hibernate5项目时必需的核心类库。
(3) project文件夹: 该文件夹存放Hibernate5项目的源代码。
3. Hibernate5的配置
Hibernate5的lib文件夹有6个子目录,需要在项目的类库中添加required和jpametamodelgenerate子目录下面的所有JAR文件,其他目录中的JAR文件可根据项目的实际需求添加。例如,使用连接池需要添加lib\\optional\\c3p0下面的JAR文件和使用缓存功能需要使用lib\\optional\\chcache下面的JAR文件。
由于NetBeans 8.2和MyEclipse 2017中都集成了Hibernate,所以可以使用工具中自带的Hibernate。集成的Hibernate版本一般不是Hibernate的*新版本。由于Hibernate各版本之间存在一些细节差异,有可能在配置文件和映射文件中存在差异导致项目无法运行。使用本书进行项目开发时建议使用Hibernate 5.2.12。在NetBeans 8.2、MyEclipse 2017和Eclipse中配置Hibernate与第1章中介绍的配置Struts 2.5.10的方法相似,这里不再介绍。
5.1.3Hibernate5的工作原理
Hibernate5的工作原理如图56所示。
图56Hibernate5的工作原理
Hibernate5的工作过程如下。
首先,Configuration读取Hibernate5的配置文件hibernate.cfg.xml和映射文件.hbm.xml中的信息,即加载配置文件和映射文件,并通过Hibernate5配置文件生成一个多线程的SessionFactory对象;然后,多线程SessionFactory对象生成一个线程Session对象;Session对象生成Query对象或者Transaction对象;可通过Session对象的get()、load()、save()、update()、delete()和saveOrUpdate()等方法对PO进行加载、保存、更新、删除等;也可利用Query对象执行查询操作;如果没有异常,Transaction对象将提交这些数据到数据库中。
5.2Hibernate5的核心组件
在基于Hibernate5框架的项目开发时,非常关键的一点就是使用Hibernate5的核心类和接口,即核心组件。Hibernate5的核心组件位于业务层和持久化层之间。Hibernate5除核心组件外还包括Hibernate5配置文件(hibernate.cfg.xml或hibernate.properties)、映射文件(xxx.hbm.xml)和持久化类(Persistent Objects,PO)。
1. Configuration
Configuration负责配置并启动Hibernate5,创建SessionFactory对象。在Hibernate5的启动过程中,Configuration类的实例首先定位映射文件位置、读取配置,然后创建SessionFactory对象。
2. SessionFactory
SessionFactroy负责初始化Hibernate5。它充当数据存储源的代理,并负责创建Session对象,这里用到了工厂模式。需要注意的是SessionFactory并不是轻量级的,因为一般情况下,一个项目通常只需要一个SessionFactory就可以了,当需要多次操作数据库时,可以为每个数据库指定一个SessionFactory线程对象。SessionFactroy是产生Session实例的工厂。
3. Session
Session负责执行持久化对象的操作,它用get()、load()、save()、update()和delete()等方法来对PO进行加载、保存、更新及删除等操作。但需要注意的是Session对象是非线程**的。同时,Hibernate5的Session不同于JSP应用中的HttpSession。这里使用的Session术语,其实指的是Hibernate5中的Session。
4. Transaction
Transaction负责事务相关的操作,用来管理Hibernate5事务,它的主要方法有commit()和rollback(),可以使用Session的beginTransaction()方法生成。它是可选的,开发人员也可以设计编写自己的底层事务处理代码。
5. Query
Query负责执行各种数据库查询。它可以使用HQL语言对PO进行查询操作。Query对象可以使用Session的createQuery()方法生成。
6. Hibernate5的配置文件
Hibernate5的配置文件主要用来配置数据库连接参数,例如,数据库的驱动程序、URL、用户名和密码、数据库方言等。它有两种格式: hibernate.cfg.xml和hibernate.properties。两者的配置内容基本相同,但前者比后者使用方便一些,如hibernate.cfg.xml 可以在其<mapping>子元素中定义用到的xxx.hbm.xml 映射文件列表,而使用hibernate.properties时则需要在程序中以编码方式指明映射文件。一般情况下,hibernate.cfg.xml是Hibernate5的默认配置文件。
7. 映射文件
映射文件(xxx.hbm.xml)用来把PO与数据库中的表、PO之间的关系与表之间的关系以及PO的属性与表字段一一映射起来,它是Hibernate5的核心文件。
8. 持久化对象
持久化对象(Persistent Object,PO)可以是普通的JavaBean,**特殊的是它们与Session相关联。PO在Hibernate5中存在三种状态: 临时状态(Transient)、持久化状态(Persistent)和脱管状态(Detached)。当一个JavaBean对象在内存中孤立存在不与数据库中的数据有任何关联关系时,那么这个JavaBean对象就称为临时对象(Transient Object);当它与一个Session相关联时,就变成持久化对象;在这个Session被关闭的同时,这个对象也会脱离持久化状态,变成脱管对象(Detached Object),这时可以被应用程序的任何层自由使用,例如,可用作与表示层(V)打交道的数据传输对象。
5.3基于Struts2和Hibernate5的登录和注册系统
下面使用Struts 2.5.10和Hibernate 5.2.12开发一个实现登录和注册功能的项目,该项目的文件结构如图57所示。将项目中使用到的Struts 2.5.10、Hibernate 5.2.12以及MySQL 5.5驱动的JAR文件添加到项目ch05的“库”中,如图58所示。
图57项目的文件结构
图58项目所需的JAR文件
1. 项目介绍
本项目实现用户登录和用户注册功能。有一个登录页面(login.jsp),代码如例51所示,登录页面对应的业务控制器为LoginAction,该Action中覆盖了validate()方法,使用手工验证对登录页面进行验证,该业务控制器类代码如例54所示,如果输入的用户名和密码都正确,进入登录成功页面(success.jsp),代码如例52所示;如果用户没有注册需先注册,注册页面(register.jsp)代码如例53所示,该注册页面对应的业务控制器为RegisterAction,代码如例55所示,注册成功后返回登录页面。还需要配置web.xml,代码如例13所示;在struts.xml中配置Action,代码如例56所示。
该项目使用MySQL数据库。数据库名为test,有一张名为info的表,表的字段名称、类型以及长度如图59所示。
图59数据库info表的结构
在基于Struts2 Hibernate5的项目开发中,连接数据库时需要Hibernate5的配置文件hibernate.cfg.xml或者hibernate.properties,本项目使用的是hibernate.cfg.xml,代码如例57所示,配置文件主要用于加载数据库的驱动以及与数据库建立连接等,该配置文件一般与struts.xml文件放在同一位置,参考图58。该配置文件在项目运行时需要加载,本项目编写一个加载该配置文件的类HibernateSessionFactory,该类封装了配置文件的加载方法,即加载配置文件的JavaBean,代码如例58所示。
另外,在使用Hibernate5时,项目所用数据库中的每一张表都对应一个持久化对象PO。通过PO把页面中的数据保存起来并把数据存到数据库中。为了简化开发,本项目的登录页面和注册页面都使用同一张表,登录页面和注册页面中的数据都保存在UserInfoPO中,代码如例59所示。每个PO一般都会对应一个映射文件UserInfoPO.hbm.xml,代码如例510所示,映射文件配置PO与数据库中表之间的映射关系;映射文件一般都放在和其对应的PO所在包中。为了封装登录和注册功能对数据的操作,即登录和注册页面要实现的业务逻辑,本项目编写一个名为LoginRegisterInfo的JavaBean,该类提供了登录和注册业务处理,可以实现登录和注册的持久化业务操作,代码如例511所示。
以上文件所在的路径可参考项目文件结构图57。
2. 在web.xml中配置核心控制器StrutsPrepareAndExecuteFilter
参考1.3.1节中的例13。
3. 编写视图组件(JSP页面)
登录页面(login.jsp)运行效果如图510所示,代码如例51所示。
图510登录页面
【例51】登录页面(login.jsp)。<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglibprefix="s" uri="/struts-tags" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><s:text name="基于SH的应用"></s:text></title>
</head>
<body bgcolor="#CCCCFF">
<s:form action="login" method="post">
<br><br><br><br><br><br>
<table border="1" align="center" bgcolor="#AABBCCDD">
<tr>
<td>
<s:textfield name="userName" label="用户名字"
size="16"/>
</td>
</tr>
<tr>
<td>
<s:password name="password" label="用户密码"
size="16"/>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<s:submit value="登录"/>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<s:a href="http://localhost:8084/ch05/register.jsp">注册
</s:a>
</td>
</tr>
</table>
</s:form>
</body>
</html>登录成功页面(success.jsp),代码如例52所示。
【例52】登录成功页面(success.jsp)。<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglibprefix="s" uri="/struts-tags" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><s:text name="基于SH的应用"></s:text></title>
</head>
<body bgcolor="#CCCCFF">
<hr>
<table border="0" align="center" bgcolor="#AABBCCDD">
<tr>
<td>
欢迎${userName},登录成功!
</td>
</tr>
</table>
<hr>
</body>
</html>注册页面(register.jsp)如图511所示,代码如例53所示。
图511注册页面
【例53】注册页面(register.jsp)。<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglibprefix="s" uri="/struts-tags" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><s:text name="基于SH的应用"></s:text></title>
</head>
<body bgcolor="#CCCCFF">
<s:form action="register" method="post">
<br><br><br><br><br><br>