Hibernate实战(第2版)学习笔记八

140.OSIV(Open Session In View)模式背后的动机在于,视图通过导航从某个脱管对象开始的对象图,从业务对象中拖出信息。视图(即,必须被渲染和显示的页面)访问这个脱管对象,给页面获取内容数据。
在Hibernate应用程序中,可能有未被初始化的关联(代理或者集合),它们必须在渲染视图时被驳回。
如果Hibernate必须延迟加载对象,为什么它不能打开新的会话?Hibernate Session是持久化上下文,是对象同一性的范围。Hibernate保证在持久化上下文中,一个特定的数据库行最多只有一种内存表示法。按需打开Session,幕后也创建了一个新的持久化上下文,并行在这个同一性范围中加载的所有对象,都将可能与在原始的持久化上下文中加载的对象产生冲突。
当对象处于受保护的对象守包含的对象同一性范围之外(即被脱管的时候),你将无法按需加载数据。另一方面,只要对象处于持久化状态中,且由Session管理,那么甚至在原始的事务以及被提交的时候,你都可以加载数据。在这样的场景中,必须启用自动提交模式。
141.将数据访问代码和应用程序逻辑混合,这违背了关注点分离的重点。之所以你应该考虑把Hibernate调用隐藏在facade(即所谓的持久层)之后,有几个原因:
  • 持久层可以给数据操作访问操作提供更高基本的抽象。不用基础的CRUD和查询操作,而是公开更高级别的操作。例如getMaximumBid()方法。这个抽象就是你为什么想要在更大的应用程序中创建持久层的主要原因:支持重用相同的非CRUD操作。
  • 持久层可以有泛型的接口,不公开实际的实现细节。换句话说,可以隐瞒你正在使用Hibernate(或者Java Persistence)从持久层的任何客户端实现数据访问操作的事实。
  • 持久层可以统一数据访问操作。
(1)DAO为与特定的持久化实体相关的持久化操作(CRUD和finder)定义了接口,它建议你把与该实体的持久化相关代码都组合到一起。
142.如果表现层在一个不同的进程中运行,就要把这个进程与运行应用程序的业务层和持久层的层之间的请求减少到最少。这意味着你不能使用前面的延迟方法(必要时它允许视图从领域模型对象中拖取数据)。反之,业务层必须接受抓取后面呈现视图所需的所有数据的责任。
命令模式以命令类的层次结构思想为基础,所有命令类都实现一个简单的Command接口。
特定的Command是动作、事件或者符合类似描述的任何东西的实现。客户端代码创建命令对象,并准备执行它们。CommandHandler是一个可以执行Command对象的接口。客户端把Command对象传递到服务器层中的一个处理器,这个处理器执行它。然后Command对象被返回到客户端。
Command接口有一个execute()方法;任何具体的命令都必须实现这个方法。任何子接口都可以添加在执行Command之前(设置方法)或之后(获取方法)而被调用的额外方法。因此Command给特定的事件组合了输入(input)、控制器(controller)和输出(output);
执行Command对象(即,调用他们的execute()方法)是CommandHandler实现的工作。命令的执行被多态地分派。
命令处理器如何被查找或者实例化,这取决于命令处理器的实现,以及远程的通信如何发生。
命令模式让你能够轻松地实现任何撤销(Undo)功能。每一个命令都可以有一个undo()方法,它可以禁用execute()方法已经完成的任何永久的改变。或者,你可以在客户端排列几个命令对象,并且只在特定的对话完成时,才把它们发送到命令处理器。
143.划分软件测试的种类如下:
验收测试(acceptance testing)——这种测试不是自动化测试必须的,并且通常不是应用程序开发人员和系统设计人员的工作。验收测试是系统测试的最后阶段,由确定系统是否满足项目需求的客户(或者其他任何地方)来执行。这些测试可以包括任何准则,从功能到性能到可用性。
性能测试(performance testing)——压力测试或负载测试使用大量并发的用户对系统进行测试,理想情况下是等于或者高于一旦软件正式运行时所期待的负载。
逻辑单元测试(logic unit testing)——这些测试考虑单项功能,经常只是一个业务方法。如果一个组件作为单个单元进行测试,它就是独立于任何其他的组件进行测试。逻辑单元测试不涉及任何像数据库这样的子系统。
集成单元测试(integration unit testing)——集成测试确定软件组件、服务和子系统之间的交互是否如预期的那样工作。功能单元测试(functional unit testing)——功能测试检验整个用例,以及完成这个特定的用例所需的所有应用程序组件中的公共接口。
首先,可以通过设置hibernate.hbm2ddl.auto为validate来轻松地测试映射。然后当构建SessionFactory时,Hibernate通过把它们与数据库目录元数据进行对比,来验证映射。第二,测试查询与测试对象状态改变一样:编写集成测试方法,并断言所返回的数据的状态。
性能(performance)通常被当作是基于应用程序的请求/响应的反应时间。
可伸缩性(scalability)是系统在更高的负载下合理执行的能力。
144.Seam是一个创新的新框架,用于通过Java EE5.0平台进行的Web应用程序开发。Seam带来了两个新的标准,即JavaServer Faces(JSF)和EJB3.0,通过统一它们的组件和编程模型,使二者关系更加密切。
(1)JSF详解
JSF简化了在Java中对Web用户界面的构建。作为表现框架,JSF提供了以下高级特性:
JSF给可视的组件定义了一个可扩展的组件模型,经常称作小部件(widget)。
JSF给backing bean或者被托管的bean(它们包含应用程序逻辑)定义了组件编程模型。
JSF定义了用户界面和应用程序逻辑之间的交互,并允许你以灵活的方式把两者绑定在一起。
JSF允许你用XML声明性地定义导航规则——也就是说,哪一页显示应用逻辑中的特定结果。
JSF是事件驱动的表现框架。如果单击一个按钮,就会触发JSF ActionEvent,并传递到已注册的监听器。动作事件的监听器还是你在JSF配置中命名的backing bean。然后backing bean可以对该事件做出响应。
(2)EJB3.0详解
EJB3.0是一个给事务的组件定义编程模型的Java EE5.0标准。对于Web应用程序开发人员来说,EJB3.0的下列特性最值得关注。
EJB3.0定义了在简单的Java类中主要基于注解的组件编程模型。
EJB3.0定义了无状态、有状态和消息驱动的组件,以及运行时环境如何管理组件实例的生命周期。
EJB3.0定义了组件如何被连接在一起,如何获得对组件的引用,以及组件如何相互调用。
EJB3.0定义横切关注点如何被处理,例如事务和安全性。也可以编写定制拦截器,并用它们把组件包装起来。
EJB3.0标准化了Java Persistence,以及如何通过自动的和透明的ORM来访问SQL数据库。
145.第一个Seam注解@Name,将这个POJO转变成一个Seam组件。现在每当Seam查找一个名为user的组件,并且Seam上下文都未保存具有该名称的变量时,就会由Seam创建User的一个新的空实例,并将它放到以变量名称user为名的事件上下文中。事件上下文是实体Seam组件的默认上下文(有状态和无状态的bean有着不同的默认上下文)。
@In注解告诉Seam,你想要让一个值分配到这个组件的一个成员变量。这个值由Seam在该组件的方法被调用之前进行分配(Seam拦截每个调用)。
@Out注解告诉Seam,你想要当组件的(任何)方法返回时,将一个值分配给上下文变量。
利用Hibernate Validator 可以轻松地为所有的应用层隔离和封装验证和数据完整性规则。
Hibernate Validator是Hibernate Annotations的一个模块。甚至可以不通过Hibernate和Seam,而只通过类路径的hibernate3.jar和hibernate-annotations.jar,在任何Java应用程序中使用Hibernate Validator。
Hibernate Validator是一组注解,可以将它应用到领域模型来声明性地定义数据验证和完整性规则。可以通过编写自己的注解,用自己的约束来扩展Hibernate Validator。
被应用的这些完整性规则和验证规则可以用于一下对象:
简单的Java——可以在Java代码中的任何位置调用ClassValidator API,并提供需要检查的对象。验证器完成验证,或者返回InvalidValue对象的一个数组。每个InvalidValue都包含关于验证失败的详细信息,例如属性名称和错误消息。
Hibernate——在原生的Hibernate中,可以注册钩入Hibernate持久化操作内部处理的Hibernate Validator事件。通过这些事件,Hibernate可以验证你正在数据库中自动且透明地插入或者更新的任何对象。包含详细信息的InvalidStateException在验证失败时被抛出。
Hibernate EntityM——如果通过Hibernate EntityManager使用JPA,Hibernate Validator事件就被默认为激活状态,并且当你在数据库插入或者更新对象时,所有的实体实例都要根据验证注解进行检查。
SchemaExport——Hibernate的数据库模式生成特性可以创建数据库约束,它影响着SQL DDL中国的完整性规则。SchemaExport(hbm2ddl)工具在领域模型中读取验证注解,并在SQL DDL中呈现它们。每个注解都知道SQL应该是什么样子(或者如果SQL中不存在相当的约束)。如果基于定制的过程SQL约束(触发器等)编写自己的验证注解,这个就特别强大。可以将一个定制的数据库完整性规则封装在单个Java注解中,并用Hibernate Validator在运行时检查被注解类的实例。
Seam——通过Seam,可以将Hibernate Validator与应用程序的表现层和应用程序逻辑整合起来。Seam可以在JSF表单提交时自动调用验证API,并用任何验证错误消息装饰表单。
146.如果让Seam将Entitym注入到会话bean中去,并且如果你让Seam管理持久化上下文,将会得到下列结果:
被扩展的持久化上下文自动绑定和界定到对话——你有一个跨越对话的受保护的同一性范围。一个特定的对话至少有一种特定数据库行的内存表示法。没有脱管对象,你可以轻松地通过双等号比较实体实例。不必实现equals()和hashCode(),并通过业务键比较实体实例。
在一个对话中访问未被初始化的代理或者集合时,再也没有LazyInitializationException了——持久化上下文对于整个对话都是活动的,且持久化引擎始终可以按需抓取数据。Seam提供了一种更加强大且方便的OSIV模式的实现,它不仅在单个请求期间而且在整个对话期间,避免了游离对象。
自动把JSF请求包在几个系统事务中——Seam使用几个事务来封装JSF请求生命周期中的几个阶段。
147.包含着行和列的表,对于任何已经使用过SQL数据库的人来说都是再熟悉不过的了。有时候你会看到表被称作关系(relation),行称作字节组(tuple),列称作属性(attribute)。这是关系数据模型(relational data model)的语言,是SQL数据库(不完全)实现的数学模型。
限制(restriction)是选择符合特定条件的表行的操作。在SQL中,这个条件是发生在where子句中的表达式。
投影(projection)是选择一张表的列、并从结果中消除重复行的操作。在SQL中,要包括的列都列在select子句中。可以通过指定distinct关键字消除重复的行。
笛卡尔积[Cartesian product,也称作交叉联结(cross join)]生成一张新表,它由两张现有的表的行的所有可能的组合构成。在SQL中,通过在from子句中列出表来表达笛卡尔积。

猜你喜欢

转载自bsr1983.iteye.com/blog/2099132
今日推荐