首页
会员中心
到顶部
到尾部
计算机

Hibernate的实践与应用

时间:2020/10/14 13:37:51  作者:  来源:  查看:0  评论:0
内容摘要: Hibernate的实践与应用检索对象 从数据库中检索对象是使用Hibernate最有趣(也是最复杂)的部分。Hibernate 提供下列方式 从数据库中提取对象: ●导航对象图,从一个已经装载的对象开始,通过像aUser.getA...
Hibernate的实践与应用

检索对象 
从数据库中检索对象是使用Hibernate最有趣(也是最复杂)的部分。Hibernate 提供下列方式 从数据库中提取对象: 
●导航对象图,从一个已经装载的对象开始,通过像aUser.getAddress().getCity()的属性访问器方法访问相关的对象。如果Session是打开的,当你导航图时,Hibernate会自动装载图的节点。 
●当对象的唯一标识符值是已知的时候,通过标识符检索是最方便最有性能的方法。使用Hibernate查询语言(HQL),它是完全面向对象的查询语言。 
●使用Hibernate 条件API,它提供了类型安全的面向对象的方式执行查询而不需要操纵字符串。这种便利性包括基于例子对象的查询。 
●使用本地SQL查询,这种查询Hibernate只关心把JDBC 结果集映射到持久对象图。在Hibernate 应用程序中,将结合使用这几种技术。每一种检索方法可能使用不同的抓取策略—那就是定义持久对象图的哪个部分应该检索的策略。目标是在你的应用程序中为每个使用场合发现最好的检索方法和抓取策略,同时最小化查询语句的数量以获得最好的性能。在这一节我们不仔细讨论每个检索方法,相反,我们将集中于基本的抓取策略和怎样调整Hibernate 映射文件以便对所有的方法达到最好的默认抓取性能。在看抓取策略之前,我们将给出检索方法的概述。(我们提到Hibernate缓存系统但是将在下一章完全研究它。)让我们开始最简单的例子,通过给定的标识符值检索对象(导航对象图不加以说明了)。 
在这一章的前半部分你已经看过一个简单的通过标识符检索的例子,但是还有许多需要知道。 
根据标识符检索对象 
下面的Hibernate 代码片断从数据库中检索User对象: User user =(User)session.get(User.class, userID); get()方法很特别,因为标识符唯一地标识类的单个实例。因此,应用程序通常使用标识符方便地处理持久对象。当用标识符检索对象时可以使用缓存,如果对象已经缓存了可以避免数据库碰撞(hit)。 
Hibernate也提供了load()方法: 
User user = (User) session.load(User.class, userID); load()方法是旧的,因为用户的请求已经把get()方法加入到Hibernate API。
不同之处微不足道: 
●如果load()方法不能在缓存或数据库中找到对象会抛出异常。load()方法从不返回null。如果对象没找到get()方法返回null。 
●load()方法返回代理而不是真正的持久实例。代理是一个占位符,当第一次调用它时才装载真正的对象。我们将在本节的后半部分讨论代理。另一方面,get()方法从不返回代理。在get()和load()之间选择很简单:如果你能确定持久实例存在,不存在将会认为是异常,那么load()是很好的选择。如果你不能确定给定的标识符是否有一个实例,使用get()测试返回值,看它是否为null。使用load()有更深的含义:应用程序可能检索一个对持久实例的引用(代理)而不会强制数据库检索它的持久状态。因此,在缓存或数据库中不能找到持久对象时load()不能抛出异常。异常会在以后抛出,当代理被访问的时候。 
当然,使用标识符检索对象没有使用任意的查询复杂。 
介绍HQL 
Hibernate 查询语言是与其相似的关系型查询语言SQL 的面向对象方言。HQL与ODMGOQL和EJB-QL很相像,但是不像OQL,它是用于SQL数据库的,并且比EJB-QL更强大更优秀(然而,EJB-QL3.0 将会与HQL非常相似。)只要有SQL基础HQL非常容易学。HQL不是像SQL这样的数据操纵语言。它只能用来检索对象,不能更新、插入或删除数据。对象状态同步是持久管理器的工作,而不是开发者的工作。 
大部分时间你仅仅需要检索特定类的对象,并且受那个类的属性的约束。例如,下面的查询根据姓来检索用户: 
Query q = session.createQuery("from User u where u.firstname = :fname"); q.setString("fname", "Max"); List result = q.list();准备查询q 之后,我们把标识符值绑定到命名参数fname 上。User 对象的List 作为结果返回。HQL功能非常强大,虽然你不会一直使用其高级特征,但是你将会需要它们来解决一些复杂问题。例如,HQL支持下面这些功能: 
●通过引用或持有集合(使用查询语言导航对象图)把限制条件应用到相关的关联对象的属性上的能力。
●在事务范围仅仅检索一个或多个实体的属性而不是装载整个实体的能力。有时把它称为report query,更正确的说法是projection。 
●排列查询结果的能力。 
●分页查询的能力。 
●使用group、having及统计函数(如sum、min和max)进行统计。 
●当在一行中检索多个对象时使用外联接。 
●调用用户自定义的SQL函数的能力。 
●子查询(嵌套查询)。 
通过条件查询 
Hibernate的通过条件查询(query by criteria(QBC))API允许你在运行时通过操纵查询对象来建立查询。这种方法允许动态的指定约束而不是直接操纵字符串,但是,它也丢掉了许多HQL的复杂性或强大功能。另一方面,以条件表示的查询比以HQL表示的查询可读性差。 
通过名字检索用户使用查询对象更简单: 
Criteria criteria = session.createCriteria(User.class); criteria.add( Expression.like("firstname", "Max")); List result = criteria.list(); 
Criteria 是一个Criterion 实例树。Expression 类提供返回Criterion 实例的静态工厂方法。 一旦建立了想要的查询树,就会对数据库执行。许多开发者喜欢QBC,把它认为是更复杂的面向对象方法。他们也喜欢查询语法在编译时解释和验证的事实,而HQL只有在运行时才解释。 
关于Hibernate Criteria API最好的方面是Criterion框架。这个框架允许用户对其进行扩展,像HQL这样的查询语言却很困难。 
通过例子查询 
作为QBC便利性的一部分,Hibernate支持通过例子查询(QBE)。使用QBE的前提条件是应用程序支持具有某种属性值集合(非默认值)的查询类实例。查询返回所有的匹配属性值的持久实例。QBE 不是特别强大的方法,但是对一些应用程序却很方便。下面的代码片断演示Hibernate的QBE: 
User exampleUser = new User(); exampleUser.setFirstname("Max");
QBE 的典型用例是允许用户指定属性值范围的查找屏幕,指定属性值范围用来匹配返回的结果集。这种功能在查询语言中很难清晰地表达,操纵字符串需要指定动态的约束集。QBC API和这种查询机制的例子将在第七章详细讨论。现在你知道Hibernate中基本的检索选项。我们在本节的剩余部分关注对象图的抓取策略。抓取策略定义了用查询或装载操作检索对象图(或子图)的哪一部分。 
抓取策略 
传统的关系数据访问利用内连接和外连接检索相关的实体,用单个SQL查询抓取对某个计算所需要的所有数据。一些原始的ORM实现分开抓取数据,多次请求小块的数据,应用程序作为响应也会多次导航持久对象图。这种方法不能有效利用关系数据库的连接能力。实际上,这种数据访问策略将来很难扩展。ORM中的一个最困难的问题—可能是最困难的—是提供对关系数据库的有效访问,鉴于应用程序喜欢把数据当成对象图看待。 
对于我们经常开发的多种应用程序(多用户,分布式,web 和企业应用),检索对象时多次往返于数据库是不可取的。因此,我们讨论的工具比传统的工具更强调ORM中的R(关系)。有效地抓取对象图的问题已经通过在关联映射的元数据中指定关联级抓取策略解决了。 
这种方法存在的问题是每段代码使用一个需要不同集合的相关对象的实体。但是这是不够的我们需要的是支持细粒度的运行时关联抓取策略。Hibernate 两者都支持,允许在映射文件中指定默认的抓取策略,然后在代码运行时重载。 
Hibernate对于任何关联允许在四种抓取策略中选择,在关联元数据和运行时: 
●立即抓取—立即抓取关联的对象,使用连续的数据库读(或缓存查找)。 
●延迟抓取—当第一次访问时,“延迟”抓取相关的对象或集合。这个结果在对数据库的新请求中(除非缓存了相关的对象)。 
●提前抓取—相关的对象或集合同拥有它们的对象一起抓取,使用SQL外连接,不需要额外的数据库请求。 
●批量抓取—在访问延迟关联时,这种方法通过检索一批对象或集合来提高延迟抓取的性能(批量抓取也用来提高立即抓取的性能。)让我们仔细看看每种抓取策略。
立即抓取 
立即的关联抓取发生在从数据库中检索实体然后立即在下一个对数据库或缓存的请求中检索另一个(或一些)相关的实体的时候。立即抓取通常不是有效的抓取策略除非希望关联的实体一直被缓存。
延迟抓取 
当客户请求数据库中的实体及其相关的对象图时,通常不必检索每个(非直接的)关联对象的整个对象图。你不希望立即把整个数据库装载到内存中,例如,装载单个Category 不应该触发装载这个目录的所有Item。延迟抓取能够让你决定第一次访问数据库时装载多少对象图,并且与其关联的对象只有在第一次访问时才装载。延迟抓取是对象持久化中的基本内容,而且是取得可接受性能的第一步。 
我们推荐在开始的时候把映射文档中所有的关联映射为延迟(或可能是批量延迟)抓取。 
这种策略然后被强制提前抓取发生的查询重载。
提前(外连接)抓取 
延迟关联抓取能够帮助减少数据库装载,而且通常是一种好的默认策略。然而,这在性能优化发生前有点盲目猜测。 
提前抓取让你显式地指定哪些关联的对象应该同引用它们的对象一起装载。Hibernate 然后在单个数据库请求中使用SQL的OUTER JOIN 返回关联的对象。Hibernate的性能优化通常包括针对某些事务明智地使用提前抓取。因此,即使在映射文件中声明了默认的抓取策略,在运行时对于某个HQL或条件查询指定使用这种策略更普遍。 
批量抓取 
批量抓取不是严格的关联抓取策略,它是帮助提高延迟(或立即)抓取性能的一种技术。通常,当装载对象或集合的时候,SQL的WHERE 子句指定对象的标识符或拥有集合的对象。 
如果开启了批量抓取,Hibernate看起来知道什么会在当前session 中引用其它代理实例或未初 始化的集合,尽量通过在WHERE 子句中指定多个标识符值来同时装载这些对象。我们不是这种方法的热心者,提前抓取几乎一直是更快的。批量抓取对那些希望用Hibernate 达到可接受的性能而不用想太多关于要执行的SQL 的经验不足的用户很有用。(注意,你可能很熟悉批量抓取,因为它已经被许多EJB2 引擎使用)。 
现在我们在映射元数据中对一些关联声明抓取策略。
Struts——一种开源MVC的实现
这篇文章介绍 Struts,一个使用 servlet 和 JavaServer Pages 技术的一种 Model-View-Controller 的实现。Struts 可以帮助你控制 Web 项目中的变化并提高专业化。即使你可能永远不会用 Struts实现一个系统,你可以获得一些想法用于你未来的 servlet 和 JSP 网页的实现中。
1、简介
在小学校园里的小孩子们都可以在因特网上发布 HTML 网页。然而,有一个重大的不同在一个小学生和一个专业人士开发的网站之间。网页设计师(或者 HTML开发人员)必须理解颜色、用户、生产流程、网页布局、浏览器兼容性、图像创建、JavaScript 等等。设计漂亮的网站需要做大量的工作,大多数 Java 开发人员更注重创建优美的对象接口,而不是用户界面。JavaServer Pages (JSP) 技术为网页设计人员和 Java 开发人员提供了一种联系钮带。
如果你开发过大型 Web 应用程序,你就理解“变化”这个词语。“模型-视图-控制器”(MVC) 就是用来帮助你控制变化的一种设计模式。MVC 减弱了业务逻辑接口和数据接口之间的耦合。Struts 是一种 MVC 实现,它将 Servlet 2.2 和 JSP 1.1 标记(属于 J2EE 规范)用作实现的一部分。你可能永远不会用 Struts 实现一个系统,但了解一下 Struts 或许使你能将其中的一些思想用于你以后的 Servlet和 JSP 实现中。
2、模型-视图-控制器 (MVC)
JSP标签只解决了我们问题中的一部分。我们依然有验证、流控制、以及更新应用程序结构的问题。这就是MVC从哪儿来以及来干嘛的。MVC通过把问题分成三类来帮助解决一些与单模块相关的问题:
Model(模型)
模块包括应用程序功能的核心。模型封装着应用程序的各个结构。有时它所包含的唯一功能就是结构。它对于视图或者控制器一无所知。
 View(视图)
视图提供了模型的演示。它是应用程序的外表。视图可以进入模型获得者,第 1 页共 8 页
中北大学2014届毕业设计英文文献译文
但是它对于设置者一无所知。除此之外,它对于控制器也是一无所知。视图仅仅当模型发生改变的时候才被通知。
Controller(控制器)
控制器对于用户的输入做出反应。它创造和设置模型。

Struts 详细资料
ActionServlet 类
你还记得使用函数映射的日子吗?你会映射一些输入时间到一个函数的一个指针。如果你很老练,你可以把这些配置信息放进一个文件里并且在运行时加载该文件。函数指针装扮了在C语言结构化程序设计中的旧时光。
现在日子好过多了,自从我们有了Java技术、XML、J2EE等等之后。Struts控制器是一个映射事件(事件通常是一个HTTP post)到类的一个 servlet。猜猜怎么着-- 控制器用一个配置文件以致于你不必非硬编码这些值。生活变了,但方法依然如此。
ActionServlet 是 MVC 实现的命令部分并且它是框架的核心。
ActionServlet (Command) 创建并使用 Action 、 ActionForm 和
ActionForward 。正如前面所提及的, struts-config.xml 文件配置Command。在Web 工程创建期间, Action 和 ActionForm被扩展用来解决特殊的问题空间。文件 struts-config.xml 指导 ActionServlet 如何扩展这些类。这种方法有几个优点:
应用程序的整个逻辑流程处于分层文本文件中。这使得更容易查看和理解,特别是在大型应用程序中。页面设计人员不必通过Java代码来了解应用程序的流程。
Java开发人员在进行流程更改时不需要重新编译代码。
可以通过扩展ActionServlet来添加命令功能。

  


相关评论
广告联系QQ:45157718 点击这里给我发消息 电话:13516821613 杭州余杭东港路118号雷恩国际科技创新园  网站技术支持:黄菊华互联网工作室 浙ICP备06056032号