http://blog.csdn.net/slnqnd/article/details/1772910/html
Struts2.0 +Hibernate 3.2 +Spring 2.0java
一. Struts程序员
1.定义web
它是使用 servlet 和 JavaServer Pages 技术的一种 Model-View-Controller 实现, 可帮助您控制Web 项目中的变化并提升专业化水平。“模型-视图-控制 器”(MVC) 就是用来帮助您控制变化的一种设计模式。MVC 减弱了业务逻辑接口和数据接口之间的耦合。Struts 是一种 MVC 实现,它将 Servlet 2.2 和 JSP 1.1 标记(属于 J2EE 规范)用做实现的一部分。(http://www-128.ibm.com/developerworks/cn/java/j-struts/index.html)spring
2.结构sql
在 struts+hibernate+spring 三层结构模型中处于表现层数据库
Struts框架的组件结构图apache
(http://www-128.ibm.com/developerworks/cn/java/l-struts-mvc/index.html)编程
3.业务流程及核心原理设计模式
Struts 对MVC框架提供了对开发MVC系统的底层支持,它采用的主要技术是Servlet,JSP和custom tag library。
(http://www-128.ibm.com/developerworks/cn/java/l-struts-mvc/index.html)
Struts uml 图
做为一个MVC的框架,Struts对Model、View和Controller都提供了对应的实现组件,对应上面的UML图,分别进行介绍,而且看看它们是如何结合在一块儿的。
2. Model: 模型包含应用程序的核心功能。模型封装了应用程序的状态。有时它包含的惟一功能就是状态。它对视图 或控制器一无所知。MVC系统中的Model部分从概念上能够分为两类--系统的内部状态,和改变系统状态的动做。Struts为Model部分提供了 Action和ActionForm对象:全部的Action处理器对象都是开发者从Struts的Action类派生的子类。Action处理器对象封 装了具体的处理逻辑,调用业务逻辑模块,而且把响应提交到合适的View组件以产生响应。Struts提供的ActionForm组件对象,它能够经过定 义属性描述客户端表单数据。开发者能够从它派生子类对象,利用它和Struts提供的自定义标记库结合能够实现对客户端的表单数据的良好封装和支 持,Action处理器对象能够直接对它进行读写,而再也不须要和request、response对象进行数据交互。经过ActionForm组件对象实 现了对View和Model之间交互的支持。Struts一般建议使用一组JavaBean表示系统的内部状态,根据系统的复杂度也可使用像 Entity EJB 和 Session EJB等组件来实现系统状态。Struts建议在实现时把"作什么"(Action)和"如何作"(业务逻辑)分离。这样能够实现业务逻辑的重用。
3.View:视图提供模型的表示。它是应用程序的 外观。视图能够访问模型的读方法,但不能访问写 方法。此外,它对控制器一无所知。当更改模型时,视图应获得通知。 Struts应用中的View部分是经过JSP技术实现的。Struts提供了自定义 的标记库可使用,经过这些自定义标记能够很是好地和系统的Model部分交互,经过使用这些自定义标记建立的JSP表单,能够实现和Model部分中的 ActionForm的映射,完成对用户数据的封装,同时这些自定义标记还提供了像模板定制等多种显示功能。
Struts框架的处理流程清楚的体现了MVC系统的特色,简单的Struts组件结构。Struts Controller ActionServlet处理客户请求,利用配置的ActionMapping对象把请求映射到Action处理器对象进行处理。Action处理对象 访问ActionForm中的数据,处理和响应客户请求,它还调用后台的Bean组件,这些组件封装了具体的业务逻辑。Action处理器对象根据处理结 果通知Controller,Controller进行下一步的处理。
总结一下各种:
(http://www-128.ibm.com/developerworks/cn/java/j-struts/index.html)
Command (ActionServlet) 与 Model (Action & ActionForm) 之间的关系的 UML 图
ActionServlet 类
Struts 的控制器是将事件(事件一般是 HTTP post)映射到类的一个 servlet。控制器使用配置文件以使您没必要对这些值进行硬编码。ActionServlet 是该 MVC 实现 的 Command 部分,它是这一框架的核心。 ActionServlet (Command) 建立并使 用 Action 、 ActionForm 和ActionForward 。如前所述, struts-config.xml 文件配置 该 Command。在建立 Web 项目时,您将扩展 Action 和 ActionForm 来解决特定的问题。文件 struts- config.xml 指示ActionServlet 如何使用这些扩展的类。这种方法有几个优势:
能够经过扩展 ActionServlet 来添加 Command 功能。
ActionForm 类
ActionForm 维护 Web 应用程序的会话状态。 ActionForm 是一个抽象类,必须为每一个输入表单模型建立该类的子类。当我说 输入表单模型 时,是指 ActionForm 表示的是由 HTML 表单设置或更新的通常意义上的数据。例如,您可能有一个由 HTML 表单设置的 UserActionForm。Struts 框架将执行如下操做:
注:
Action 类
Action 类是业务逻辑的一个包装。 Action 类的用途是将 HttpServletRequest 转换为业务逻辑。要使用 Action ,请建立它的子类并覆盖 process() 方法。
ActionServlet (Command) 使用 perform() 方法将参数化的类传递 给 ActionForm 。仍然没有太多讨厌的 request.getParameter() 调用。当事件进展到这一步时,输入表单数据(或 HTML 表单数据)已被从请求流中提取出来并转移到 ActionForm 类中。
注:扩展 Action 类时请注意简洁。 Action 类应该控制应用程序的流程,而不该该控制应用程序的逻辑。经过将业务逻辑放在单独的包或 EJB 中,咱们就能够提供更大的灵活性和可重用性。
考虑 Action 类的另外一种方式是 Adapter 设计模式。 Action 的用途是“将类的接口转换为客户机 所需的另外一个接口。Adapter 使类可以协同工做,若是没有 Adapter,则这些类会由于不兼容的接口而没法协同工做。”(摘自 Gof 所著 的 Design Patterns - Elements of Reusable OO Software)。本例中的客户机 是 ActionServlet ,它对咱们的具体业务类接口一无所知。所以,Struts 提供了它可以理解的一个业务接口,即 Action 。经过 扩展 Action ,咱们使得咱们的业务接口与Struts 业务接口保持兼容。(一个有趣的发现是, Action 是类而不是接 口)。 Action 开始为一个接口,后来却变成了一个类。真是金无足赤。)
Error 类
UML 图(图 6)还包括 ActionError 和 ActionErrors 。 ActionError 封 装了单个错误消息。 ActionErrors 是 ActionError 类的容器,View 可使用标记访问这些类。 ActionError 是 Struts 保持错误列表的方式。
图 7. Command (ActionServlet) 与 Model (Action) 之间的关系的 UML 图
ActionMapping 类
输入事件一般是在 HTTP 请求表单中发生的,servlet 容器将 HTTP 请求转换为 HttpServletRequest 。控制器查看输入事件并将请求分派给某个 Action 类。 struts-config.xml 确 定 Controller 调用哪一个 Action 类。 struts-config.xml 配置信息被转换为一组 ActionMapping , 然后者又被放入 ActionMappings 容器中。(您可能还没有注意到这一点,以 s结尾的类就是容器)
ActionMapping 包含有关特定事件如何映射到特定 Action 的信 息。 ActionServlet(Command) 经过 perform() 方法将 ActionMapping 传递给 Action 类。这样 就使 Action可访问用于控制流程的信息。
ActionMappings
ActionMappings 是 ActionMapping 对象的一个集合。
4.利用Struts框架开发MVC系统要作的工做
(http://www-128.ibm.com/developerworks/cn/java/l-struts-mvc/index.html)
因为Struts已经为咱们提供了一个很是好的MVC框架,咱们利用Struts开发MVC系统时能够大大加快开发的速度。在开发时能够采用的一个开发流程以下:
具体在使用Struts框架时,对应各个部分的开发工做主要包括:
下面对这两个配置文件作一些介绍:
web.xml文件的配置:
web应用中的web.xml是第一个要配置的地方,它描述了系统的Controller对象。在web.xml中增长以下标记
<servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>application</param-name> ?????? </servlet> |
说明:这个servlet对象就是Struts提供的Controller,还能够为它指定初始化参数,好比对系统应用属性的支持。
<servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servelt-mapping> |
说明:实现客户请求的url信息和服务器端具体处理的映射关系。
<taglib> <taglib-url>/WEB-INF/struts-bean.tld</taglib-url> <taglib-location>/WEB-INF/struts-bean.tld</taglib-location> </taglib> ??????? |
说明:添加对Struts提供的应用所使用的自定义标记库的引用。
struts-config.xml文件的配置:
struts-config.xml是用于创建Controller和Model之间的关系的。它描述了Controller所使用的把请求对应到具体处理的法则,同时它还描述了客户提供的数据与ActionForm组件的对应映射关系。
在struts-config.xml中增长以下标记
<form-beans> <form-bean name="loginForm" type="loginForm" /> </form-beans> |
说明:<form-bean>标记描述一个具体的ActionForm子类对象,经过它和JSP页面中的自定标记的结合使用能够实现ActionForm和View之间的数据映射。
<action-mappings> <action path="/login" type="loginAction" name="loginForm" input="/login.jsp" ??? /> </action-mappings> |
说明:<action-mappings>标记描述了请求和处理的一对一映射关系。input和path属 性惟一的标记了客户端的一个请求,name属性描述封装客户端的数据的ActionForm子类对象。Type属性描述处理这个请求的Action子类对 象。
经过对两个配置文件的配置,把Struts框架中MVC的各个部分联系起来,实现一个真正的MVC系统。
5. Struts 的优势(http://www-128.ibm.com/developerworks/cn/java/j-struts/index.html)
l JSP 标记机制的使用
标记特性从 JSP 文件得到可重用代码和抽象 Java 代码。这个特性能很好地集成到基于 JSP的开发工具中,这些工具容许用标记编写代码。
l 标记库
为何要另发明一种轮子,或标记库呢?若是您在库中找不到您所要的标记,那就本身定义吧。此外,若是您正在学习 JSP 标记技术,则 Struts 为您提供了一个起点。
l 开放源码
您能够得到开放源码的所有优势,好比能够查看代码并让使用库的每一个人检查代码。许多人均可以进行很好的代码检查。
l MVC 实现样例
若是您但愿建立您本身的 MVC 实现,则 Struts 可增长您的见识。
l 管理问题空间
分治是解决问题并使问题可管理的极好方法。固然,这是一把双刃剑。问题愈来愈复杂,而且须要愈来愈多的管理。
6.Struts的缺点(http://www-128.ibm.com/developerworks/cn/java/j-struts/index.html)
二. Hibernate
1.定义
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了很是轻量级的对象封装,使得Java程序员能够为所欲为的使用对象编程思惟来操纵数据库。 Hibernate能够应用在任何使用JDBC的场合,既能够在Java的客户端程序实用,也能够在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate能够在应用EJB的J2EE架构中取代CMP, 完成数据持久化的重任。Hibernate 框架就容许Java中的对象-关系的持久性和查询服务。Hibernate 对已经熟悉了SQL 和JDBC API的Java开发者来或具备中度的学习曲线。Hibernate 的持久对象基于POJO和Java 群集(collections)。
2.Hibernate的体系结构及工做原理
(http://blog.csdn.net/hina1115/archive/2005/10/18/508717.aspx)
1.Hibernate 的初始化.
读取Hibernate 的配置信息-〉建立Session Factory
1)建立Configeration类的实例。
它的构造方法:将配置信息(Hibernate config.xml)读入到内存。
一个Configeration 实例表明Hibernate 全部Java类到Sql数据库映射的集合。
2)建立SessionFactory实例
把Configeration 对象中的全部配置信息拷贝到SessionFactory的缓存中。
SessionFactory的实例表明一个数据库存储员源,建立后再也不与Configeration 对象关联。
缓存(cache):指Java对象的属性(一般是一些集合类型的属性--占用内存空间。
SessionFactory的缓存中:Hibernate 配置信息。O/R映射元数据。
缓存-大:重量级对象 小:轻量级对象
3)调用SessionFactory建立Session的方法
a.用户自行提供JDBC链接。
Connection con=dataSource.getConnection();
Session s=sessionFactory.openSession(con);
b.让SessionFactory提供链接
Session s=sessionFactory.openSession();
4)经过Session 接口提供的各类方法来操纵数据库访问。
3.Hibernate 的缓存体系
一级缓存:
Session 有一个内置的缓存,其中存放了被当前工做单元加载的对象。
每一个Session 都有本身独立的缓存,且只能被当前工做单元访问。
二级缓存:
SessionFactory的外置的可插拔的缓存插件。其中的数据可被多个Session共享访问。
SessionFactory的内置缓存:存放了映射元数据,预约义的Sql语句。
4. Hibernate 中Java对象的状态
1.临时状态 (transient)
特征:
a.不处于Session 缓存中
b.数据库中没有对象记录
Java如何进入临时状态
a.经过new语句刚建立一个对象时
b.当调用Session 的delete()方法,从Session 缓存中删除一个对象时。
2.持久化状态(persisted)
特征:
a.处于Session 缓存中
b.持久化对象数据库中设有对象记录
c.Session 在特定时刻会保持两者同步
Java如何进入持久化状态
a.Session 的save()把临时-》持久化状态
b.Session 的load(),get()方法返回的对象
c.Session 的find()返回的list集合中存放的对象
d.Session 的update(),saveOrupdate()使游离-》持久化
3.游离状态(detached)
特征:
a.再也不位于Session 缓存中
b.游离对象由持久化状态转变而来,数据库中可能还有对应记录。
Java如何进入持久化状态-》游离状态
a.Session 的close()方法
b.Session 的evict()方法,从缓存中删除一个对象。提升性能。少用。
5. Hibernate的优势
(http://www.ibm.com/developerworks/cn/opensource/os-lightweight6/)
Hibernate 有一个灵活的映射机制。一些场景比其余场景付出更多的努力来映射,可是若是您能在一个关系模式中表 示它,那么也许在 Hibernate 中有一种方法来映射到它。Hibernate 的性能比大多数的框架要好并且还在不断提高。文档很优秀,收 购 JBoss 后,支持也在改善。JBoss 小组也把Hibernate 放置在一个合适的位置以抢在竞争者以前实现 JSR 200 持久性标准。
对 Hibernate 来讲,与其余开放源码框架和商业框架的集成比其余的替代框架要好。通常来讲,Spring 与 Hibernate 的集成比与其余任何一个持久性框架的集成要好。
Hibernate 是一个创新的框架。在推进与 SQL 的集成上,它比大多数其余的框架走的更远。它具备一些其余框架不支持的特性,好比会话过滤。还有一支强大的公共和商业开发人员团队为其工做。
6. Hibernate的缺点
因为其灵活性,相同的问题能够有多种解决方案,没法决定选择何种方案。
Hibernate 比替代框架更加难以管理。
最后,Hibernate 不像一些持久性框架那么专业。例如,对于一些边缘状况,好比管理懒散加载,Kodo JDO 有很是好的错误信息和更加可预测的行为。
三.Spring
1. 定义
Spring是轻量级的J2EE应用程序框架。Spring的核心是个轻量级容器(container),实现了IoC(Inversion of Control)模式的容器,Spring的目标是实现一个全方位的整合框架,在Spring框架下实现多个子框架的组合,这些子框架之间彼此能够独立, 也可使用其它的框架方案加以替代,Spring但愿提供one-stop shop的框架整合方案 。Spring的核心是个轻量级容器(container),实现了IoC(Inversion of Control)模式的容器,Spring的目标是实现一个全方位的整合框架,在Spring框架下实现多个子框架的组合,这些子框架之间彼此能够独立, 也可使用其它的框架方案加以替代,Spring但愿提供one-stop shop的框架整合方案 。
2. Spring框架
(http://www.ibm.com/developerworks/cn/java/wa-spring1/)
Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了建立、配置和管理 bean 的方式,如图 1 所示。
图 1. Spring 框架的 7 个模块
组成 Spring 框架的每一个模块(或组件)均可以单独存在,或者与其余一个或多个模块联合实现。每一个模块的功能以下:
Spring 框架的功能能够用在任何 J2EE 服务器中,大多数功能也适用于不受管理的环境。Spring 的核心 要点是:支持不绑定到特定 J2EE 服务的可重用业务和数据访问对象。毫无疑问,这样的对象能够在不一样 J2EE 环境 (Web 或 EJB)、独立 应用程序、测试环境之间重用。
3. Spring的核心:IOC + AOP
(http://www.ibm.com/developerworks/cn/java/wa-spring1/)
a. IOC
控制反转模式(也称做依赖性介入)的基本概念是:不建立对象,可是描述建立它们的方式。在代码中不直接与对象和服务链接,但在配置文件中描述哪个组件须要哪一项服务。容器 (在 Spring框架中是 IOC 容器) 负责将这些联系在一块儿。
在典型的 IOC 场景中,容器建立了全部对象,并设置必要的属性将它们链接在一块儿,决定什么时间调用方法。下表列出了 IOC 的一个实现模式。
类型1 |
服务须要实现专门的接口,经过接口,由对象提供这些服务,能够从对象查询依赖性(例如,须要的附加服务) |
类型2 |
经过 JavaBean 的属性(例如 setter 方法)分配依赖性 |
类型3 |
依赖性以构造函数的形式提供,不以 JavaBean 属性的形式公开 |
Spring 框架的 IOC 容器采用类型 2 和类型3 实现。
b. AOP
面向方面的编程,即 AOP,是一种编程技术,它容许程序员对横切关注点或横切典型的职责分界线的行为(例如日志和事务管理)进行模块化。AOP 的核心构造是方面,它将那些影响多个类的行为封装到可重用的模块中。
AOP 和 IOC 是补充性的技术,它们都运用模块化方式解决企业应用程序开发中的复杂问题。在典型的面向对象开发方式中,可能要将日志记录语句放在全部方法和 Java 类中才能实现日志功能。在 AOP 方式中,能够反过来将日志服务模块化,并以声明的方式将它们应用到须要日志的组件上。固然,优点就是 Java 类不须要知道日志服务的存在,也不须要考虑相关的代码。因此,用Spring AOP 编写的应用程序代码是松散耦合的。
AOP 的功能彻底集成到了 Spring 事务管理、日志和其余各类特性的上下文中。
Spring 设计的核心是 org.springframework.beans
包,它的设计目标是与 JavaBean 组件一块儿使用。这个包一般不是由用户直接使用,而是由服务器将其用做其余多数功能的底层中介。下一个最高级抽象是 BeanFactory
接口,它是工厂设计模式的实现,容许经过名称建立和检索对象。BeanFactory
也能够管理对象之间的关系。
4. Spring的优势
(http://www.imtinewlife.com/BBS/ShowPost.asp?ThreadID=201)
Spring能有效地组织你的中间层对象,不管你是否选择使用了EJB。若是你仅仅使用了Struts或其余的包含了J2EE特有APIs的framework,你会发现Spring关注了遗留下的问题。
. Spring能消除在许多工程上对Singleton的过多使用。根据个人经验,这是一个主要的问题,它减小了系统的可测试性和面向对象特性。
Spring 能消除使用各类各样格式的属性定制文件的须要,在整个应用和工程中,可经过一种一致的方法来进行配置。曾经感到迷惑,一个特定类要查找 迷幻般的属性关键字或系统属性,为此不得不读Javadoc乃至源编码吗?有了Spring,你可很简单地看到类的JavaBean属性。倒置控制的使用 (在下面讨论)帮助完成这种简化。 Spring能经过接口而不是类促进好的编程习惯,减小编程代价到几乎为零。
. Spring被设计为让使用它建立的应用尽量少的依赖于他的APIs。在Spring应用中的大多数业务对象没有依赖于Spring。
. 使用Spring构建的应用程序易于单元测试。
. Spring能使EJB的使用成为一个实现选择,而不是应用架构的必然选择。你能选择用POJOs或localEJBs来实现业务接口,却不会影响调用代码。
. Spring帮助你解决许多问题而无需使用EJB。Spring能提供一种EJB的替换物,它们适于许多web应用。例如,Spring能使用AOP提供声明性事务而不经过使用EJB容器,若是你仅仅须要与单个的数据库打交道,甚至不须要JTA实现。
. Spring为数据存取提供了一致的框架,不管是使用JDBC或O/Rmapping产品(如Hibernate)。
Spring确实使你能经过最简单可行的解决办法解决你的问题。这些特性是有很大价值的。
5. 总结
Spring的核心便是个IoC/DI的容器,它能够帮程序设计人员完成组件之间的依赖关系注入,使得组件之间的依赖达到最小,进而提升组件的重用 性,Spring是个低侵入性(invasive)的框架,Spring中的组件并不会意识到它正置身于Spring中,这使得组件能够轻易的从框架中脱 离,而几乎不用任何的修改,反过来讲,组件也能够简单的方式加入至框架中,使得组件甚至框架的整合变得容易。
Spring最为人重视的另 一方面是支持AOP(Aspect-Oriented Programming),然而AOP框架只是Spring支持的一个子框架,说Spring框架是AOP框架并非一件适当的描述,人们对于新奇 的 AOP关注映射至Spring上,使得人们对于Spring的关注集中在它的AOP框架上,虽然有所误解,但也突显了Spring的另外一个使人关注的 特点。
Spring也提供MVC Web框架的解決方案,但您也能够将本身所熟悉的MVC Web框架与Spring解合,像是Struts、Webwork等等,均可以与Spring整合而成为进用于本身的解決方案。Spring也提供其它方 面的整合,像是持久层的整合如JDBC、O/R Mapping工具(Hibernate、iBATIS)、事务处理等等,Spring做了对多方面整合的努力,故说Spring是个全方位的应用程序框 架。
四.Struts + Hibernate + Spring的综合应用
Struts: 用来做VC部分,即控制和显示做用;
Spring: 用来做数据库操做的事务处理,在配置文件里配置好就OK了;
Hibernate:用来做DAO处理,在此用了Spring的getHibernateTemplate()方法来操做hsql进行数据增删改等操做。
l 项目中 Sttuts、Hibernate、Spring的基本流程
1. Write your business class:
DTO, FormBean, Action, Service Interface, Service Implementation
2. Write JSP Pages
3. struts-config.xml Configuration : FormBean , Action , Forward pages.
4. applicationContext-service.xml Configuration : add your Service Interface and Service Implementation
5. Add your service factory Get method to ServiceFactory.java
6. Build project and Generate the Description file (*.hbm.xml) of DTO
7. applicationContext.xml Configuation : add *.hbm.xml file to applicationContext for O/R
Mapping.
l 用 Struts+Spring+Hibernate组装WEB应用
(http://java.chinaitlab.com/Struts/39925.html)
表现层咱们将使用Struts;业务层咱们将使用Spring;持久层使用Hibrenate.
图1展现了当这些框架组合在一块儿时从高层看是什么样子。
图1用Struts, Spring, 和 Hibernate框架构建的概览
应用程序的分层
大多数不复杂的web应 用都能被分红至少4个各负其责的层次。这些层次是:表现层、持久层、业务层、领域模型层。每层在应用程序中都有明确的责任,不该该和其它层混淆功能。每一 应用层应该彼此独立但要给他们之间放一个通信接口。让咱们从审视各个层开始,讨论这些层应该提供什么和不该该提供什么。
表现层
在一个典型的web应用的一端是表现层。不少Java开发者也理解Struts所提供的。然而,太常见的是,他们把像业务逻辑之类的耦合的代码放进了一个org.apache.struts.Action。因此,让咱们在像Struts这样一个框架应该提供什么上取得一致意见。这儿是Struts负责的:
为用户管理请求和响应;
提供一个控制器代理调用业务逻辑和其它上层处理;
处理从其它层掷出给一个Struts Action的异常;
为显示提供一个模型;
执行用户接口验证。
这儿是一些常常用Struts编写的可是却不该该和Struts表现层相伴的项目:
直接和数据库通信,好比JDBC调用;
业务逻辑和与你的应用程序相关的验证;
事务管理;
在表现层中引入这种代码将致使典型耦合和讨厌的维护。
持久层
在典型web应用的另外一端是持久层。这一般是使事情迅速失控的地方。开发者低估了构建他们本身的持久层框架的挑战性。通常来讲,机构内部本身写的持久层不只须要大量的开发时间,并且还常常缺乏功能和变得难以控制。有几个开源的“对象-关系映射”框架很是解决问题。尤为是,Hibernate框架为java提供了"对象-关系持久化"机制和查询服务。Hibernate对那些已经熟悉了SQL和JDBC API的Java开发者有一个适中的学习曲线。Hibernate持久对象是基于简单旧式Java对象和Java集合。此外,使用Hibernate并不妨碍你正在使用的IDE。下面的列表包含了你该写在一个持久层框架里的代码类型:
查询相关的信息成为对象。Hibernate经过一种叫做HQL的面向对象的查询语言或者使用条件表达式API来作这个事情。 HQL很是相似于SQL-- 只是把SQL里的table和columns用Object和它的fields代替。有一些新的专用的HQL语言成分要学;不过,它们容易理解并且文档作得好。HQL是一种使用来查询对象的天然语言,花很小的代价就能学习它。
保存、更新、删除储存在数据库中的信息。
像Hibernate这样的高级“对象-关系”映射框架提供对大多数主流SQL数据库的支持,它们支持“父/子”关系、事务处理、继承和多态。
这儿是一些应该在持久层里被避免的项目:
业务逻辑应该在你的应用的一个高一些的层次里。持久层里仅仅容许数据存取操做。
你不该该把持久层逻辑和你的表现层逻辑搅在一块儿。避免像JSPs或基于servlet的类这些表现层组件里的逻辑和数据存取直接通信。经过把持久层逻辑隔离进它本身的层,应用程序变得易于修改而不会影响在其它层的代码。例如:Hebernate可以被其它持久层框架或者API代替而不会修改在其它任何层的代码。
业务层
在一个典型的web应 用程序的中间的组件是业务层或服务层。从编码的视角来看,这个服务层是最容易被忽视的一层。不难在用户接口层或者持久层里找到散布在其中的这种类型的代 码。这不是正确的地方,由于这致使了应用程序的紧耦合,这样一来,随着时间推移代码将很难维护。幸亏,针对这一问题有好几种Frameworks存在。在这个领域两个最流行的框架是Spring和PicoContainer,它们叫做微容器,你能够不费力不费神的把你的对象连在一块儿。全部这些框架都工做在一个简单的叫做“依赖注入”(也通称“控制反转”)的概念上。这篇文章将着眼于Spring的为指定的配置参数经过bean属性的setter注入的使用。Spring也提供了一个构建器注入的复杂形式做为setter注入的一个替代。对象们被一个简单的XML文件连在一块儿,这个XML文件含有到像事务管理器、对象工厂、包含业务逻辑的服务对象、和数据存取对象这些对象的引用。
这篇文章的后面将用例子来把Spring使用这些概念的方法说得更清楚一些。业务层应该负责下面这些事情:
处理应用程序的业务逻辑和业务验证;
管理事务;
预留和其它层交互的接口;
管理业务层对象之间的依赖;
增长在表现层和持久层之间的灵活性,使它们互不直接通信;
从表现层中提供一个上下文给业务层得到业务服务;
管理从业务逻辑到持久层的实现。
领域模型层
最后,由于咱们讨论的是一个不是很复杂的、基于web的应用程序,咱们须要一组能在不一样的层之间移动的对象。领域对象层由那些表明现实世界中的业务对象的对象们组成,好比:一份订单、订单项、产品等等。这个层让开发者中止创建和维护没必要要的数据传输对象(或者叫做DTOs),来匹配他们的领域对象。例如,Hibernate容许你把数据库信息读进领域对象的一个对象图,这样你能够在链接断开的状况下把这些数据显示到UI层。那些对象也能被更新和送回到持久层并在数据库里更新。并且,你没必要把对象转化成DTOs,由于DTOs在不一样的应用层间移动,可能在转换中丢失。这个模型使得Java开发者天然地以一种面向对象的风格和对象打交道,没有附加的编码。
既然每一个层是互相做用的,咱们就先来建立domain objects。首先,咱们要在这些Object中要肯定那些是须要持久化的,哪些是提供给business logic,那些是显示接口的设计。 下一步,咱们将配置咱们的持久层而且定义好Hibernate的OR mappings。而后定义好Business Objects。有了这些组成部分以后,咱们将 使用Spring把这些链接起来。 最后,咱们提供给Spring一个持久层,从这个持久层里咱们能够知道它是如何与业务逻辑层(business service layer)通讯的,以及它是怎样处理其余层抛出的异常的。
域对象层(Domain Object Layer)
这层是编码的着手点,咱们的编码就从这层开始。 例子中Order 与OrderItem 是一个One—To—Many的关系。 下面就是Domain Object Layer的两个对象:
· com.meagle.bo.Order.java: 包含了一个Order的概要信息
· com.meagle.bo.OrderLineItem.java: 包含了Order的详细信息
好好考虑怎你的package命名,这反应出了你是怎样分层的。 例如 domain objects在程序中可能打包在com.meagle.bo内。 更详细一点将打包在com. meagle.bo的子目录下面。business logic应该从com.meagle.serice开始打包,而DAO 对象应该位于com.meagle.service.dao.hibernate。反应Forms和Actions的 持久对象(presentation classes) 应该分别放在com.meagle.action和com.meagle.forms包。 准确的给包命名使得你的classes很好分割而且易于维护,而且在你添加新的classes时,能使得程序结构上保持上下一致。
持久层的配置(Persistence Layer Configuration)
创建Hibernate的持久层 须要好几个步骤。 第一步让咱们把BO持久化。 既然Hibernate是经过POJO工做的, 所以Order和 OrderLineItem对象须要给全部的fileds 加上getter,setter方法。 Hibernate经过XML文件来映射(OR)对象,如下两个xml文件分别映射了Order 和OrderItem对象。(这里有个叫XDoclet工具能够自动生成你的XML影射文件)
- Order.hbm.xml
- OrderLineItem.hbm.xml
你能够在WebContent/WEB-INF/classes/com/meagle/bo目录下找到这些xml文件。Hibernate的[urlhttp://www.hibernate.org/hib_docs/api/net/sf/hibernate/SessionFactory.html]SessionFactory [/url]是用来告诉程序 应该与哪一个数据库通讯,该使用哪一个链接池或使用了DataSource, 应该加载哪些持久对象。而Session接口是用来完成Selecting,Saving,Delete和Updating这些操做。 后面的咱们将讲述SessionFactory和Session是怎样设置的。
业务层的配置(Business Layer Configuration)
既然咱们已经有了domain objects,接下来咱们就要business service objects了,用他们来执行程序的logic,调用持久层,获得UI层的requests,处理transactions,而且控制exceptions。 为了将这些链接起来而且易于管理,咱们将使用面向方面的 SpringFramework。 Spring 提供了 控制倒置(inversion of control 0==IoC)和注射依赖设置(setter dependency injection)这些方式(可供选择),用XML文件将对象链接起来。 IoC是一个简单概念(它容许一个对象在上层接受其余对象的建立),用IoC这种方式让你的对象从建立中释放了出来,下降了偶合度。
这里是一个没有使用IoC的对象建立的例子,它有很高偶合度。
图 2.没有使用 IoC. A 建立了 B 和 C
而这里是一个使用IoC的例子,这种方式容许对象在高层能够建立并进入另一个对象,因此这样能够直接被执行。
图 3. 对象使用了 IoC。 A 包含了接受B,C的 setter方法 , 这一样达到了 由A建立B,C的目的。
创建咱们的业务服务对象(Building Our Business Service Objects)
Business Object中的Setter方法接受的是接口,这样咱们能够很松散的定义对象实现,而后注入。 在咱们的案例中,咱们将用一个business service object接收一个DAO,用它来控制domain objects的持久化。 因为在这个例子中使用了Hibernate,咱们能够很方便的用其余持久框架实现 同时通知Spring 有新的DAO可使用了。
在面向接口的编程中,你会明白 “注射依赖”模式是怎样松散耦合你的业务逻辑和持久机制的:)。
下面是一个接口business service object,DAO代码片断:
代码: |
|
注意到这段代码里有一个 setOrderDao(),它就是一个DAO Object设置方法(注射器)。 但这里并无一个getOrderDao的方法,这没必要要,由于你并不会在外部访问这个orderDao。这个DAO Objecte将被调用,和咱们的persistence layer 通讯。咱们将用Spring把DAO Object 和 business service object搭配起来的。由于咱们是面向接口编程的,因此并不须要将实现类紧密的耦合在一块儿。
接下去咱们开始咱们的DAO的实现类进行编码。 既然Spring已经有对Hibernate的支持,那这个例子就直接继承HibernateDaoSupport类了,这个类颇有用,咱们能够参考HibernateTemplate(它主要是针对HibernateDaoSupport的一个用法,译注:具体能够查看Srping 的API)。
下面是这个DAO接口代码:
代码: |
public interface IOrderDAO { |
咱们仍然要给咱们持久层组装不少关联的对象,这里包含了HibernateSessionFactory和TransactionManager。 Spring 提供了一个 HibernateTransactionManager,他用线程捆绑了一个Hibernate Session,用它来支持transactions(请查看ThreadLocal) 。
下面是HibernateSessionFactory 和 HibernateTransactionManager:的配置:
代码: |
<bean id="mySessionFactory" |
能够看出:每一个对象均可以在Spring 配置信息中用<bean>标签引用。在这里,mySessionFactory引用了 HibernateSessionFactory,而myTransactionManager引用了 HibernateTransactionManage。 注意代码中myTransactionManger Bean有个sessionFactory属性。 HibernateTransactionManager有个sessionFactory setter 和 getter方法,这是用来在Spring启动的时候实现“依赖注入” (dependency injection)的。 在sessionFactory 属性里 引用mySessionFactory。这两个对象在Spring容器初始化后就被 组装了起来了。 这样的搭配让你从 单例(singleton objects)和工厂(factories)中解放了出来,下降了代码的维护代价。mySessionFactory.的两个属性,分别是用来注入 mappingResources 和 hibernatePropertes的。一般,若是你在Spring以外使用Hibernate,这样的设置应 该放在hibernate.cfg.xml中的。 无论怎样,Spring提供了一个便捷的方式-----在Spring内部配置中并入了 Hibernate的配置。 若是要获得更多的信息,能够查阅Spring API。
既然咱们已经组装配置好了Service Beans,就须要把Business Service Object和 DAO也组装起来,并把这些对象配到一个事务管理器(transaction manager)里。
在Spring中的配置信息:
代码: |
|
图4 是咱们对象搭建的一个提纲。 从中能够看出,每一个对象都联系着Spring,而且能经过Spring注入到其余对象。把它与Spring的配置文件比较,观察他们之间的关系
图 4. Spring就是这样基于配置文件,将各个Bean搭建在一块儿。
这 个例子使用一个TransactionProxyFactoryBean,它定义了一个setTransactionManager()。 这对象颇有 用,他能很方便的处理你申明的事物还有Service Object。 你能够经过transactionAttributes属性来定义怎样处理。 想知道更多仍是参考 TransactionAttributeEditor吧。
TransactionProxyFactoryBean 还有个 setter. 这会被咱们 Business service object(orderTarget)引用, orderTarget定义了 业务服务层,而且它还有个属性,由setOrderDAO()引用。这个 属性
Spring 和Bean 的还有一点要注意的: bean能够以用两种方式创造。 这些都在单例模式(Sington)和原型模 式(propotype)中定义了。 默认的方式是singleton,这意味着共享的实例将被束缚。 而原形模式是在Spring用到bean的时候允 许新建实例的。当每一个用户须要获得他们本身Bean的Copy时,你应该仅使用prototype模式。(更多的请参考设计模式中的单例模式和原形模 式)
提供一个服务定位器(Providing a Service Locator)
既 然咱们已经将咱们的Serices和DAO搭配起来了。咱们须要把咱们的Service显示到其余层。 这个一般是在Struts或者Swing这层里编 码。一个简单方法就是用 服务定位器返回给Spring context 。固然,能够经过直接调用Spring中的Bean来作。
下面是一个Struts Actin 中的服务定位器的一个例子。
代码: |
|
UI 层配置 (UI Layer Configuration)
这个例子里UI层 使用了Struts framework. 这里咱们要讲述一下在给程序分层的时候, 哪些是和Struts部分的。咱们就从一个Struts-config.xml文件中的Action的配置信息开始吧。
代码: |
|
SaveNewOrder 这个Action是用来持久化UI层里的表单提交过来Order的。这是Struts中一个很典型的 Action; 注意观察这个Action中exception配置,这些Exceptions也在Spring 配置文件 (applicationContext-hibernate.xml)中配置了(就在 business service object的transactionAttributes属性里)。 当异常在业务层被被抛出时,咱们能够控制他们,并适当的显示给UI层。
第一个异常,OrderException,在持久层保存order对象失败的时候被触发。这将致使事物回滚而且经过BO把异常回传到Struts这一层。
第二个异常,OrderMinimumAmountException也同第一个同样。
搭配整和的最后一步 经过是让你显示层和业务层相结合。这个已经被服务定位器(service locator)实现了(前面讨论过了), 这里服务层做为一个接口提供给咱们的业务逻辑和持久层。
SaveNewOrder Action 在Struts中用一个服务定位器(service locator)来调用执行业务方法的。 方法代码以下:
代码: |
public ActionForward execute( OrderForm oForm = (OrderForm) form; // See the full source code in the sample app. // in BaseAction. } |
总结 这篇文章在技术和构架方面掩盖了不少低层的基础信息, 文章的主要的意图在于让你意识到如何给你应用程序分 层。 分层能够“解耦”你的代码——容许新的组件被添加进来,并且让你的代码易于维护。 这里用到的技术只是专一于把“解偶”作好。 无论怎样,使用这样 的构架可让你用其余技术代替如今的层。 例如,你可能不使用Hibernate实现持久化。既然你在DAO中面向接口的编程的,因此你彻底能够用 iBATIS来代替。或者,你也可能想用Struts外的其余的技术或者框架替换如今的UI层(转换久层,实现层并不该该直接影响到你的业务逻辑和业务服 务层)。 用适当的框架搭建你的Web应用,其实也不是一件烦琐的工做,更主要的是它“解耦”了你程序中的各个层。