最新完整的SSH例子PPT课件

上传人:M****1 文档编号:568246625 上传时间:2024-07-23 格式:PPT 页数:189 大小:971.50KB
返回 下载 相关 举报
最新完整的SSH例子PPT课件_第1页
第1页 / 共189页
最新完整的SSH例子PPT课件_第2页
第2页 / 共189页
最新完整的SSH例子PPT课件_第3页
第3页 / 共189页
最新完整的SSH例子PPT课件_第4页
第4页 / 共189页
最新完整的SSH例子PPT课件_第5页
第5页 / 共189页
点击查看更多>>
资源描述

《最新完整的SSH例子PPT课件》由会员分享,可在线阅读,更多相关《最新完整的SSH例子PPT课件(189页珍藏版)》请在金锄头文库上搜索。

1、完整的完整的SSHSSH例子例子手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂课程总体目标我们的目标是:能够熟练运用当前流行的java开源框架:Struts、Hibernate以及Spring来构建灵活、易于扩展的多层Web应用程序。手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂尚学堂 手把手教程授课:王勇授课:王勇版权所有:尚学堂科技Struts+Hibernate+Spring手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂手把手教程版权所有:尚学堂科技Struts+Hibernate

2、+Spring尚学堂手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Model2手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Struts框架概览手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Struts框架概览浏览器web容器将对来自HTTP的每个请求创建一个request对象,并用一个response对象作出响应控制器控制器

3、接收来自浏览器的请求,在struts中,是由一个servlet来充当控制器的角色,struts-config.xml文件配置控制器模型在struts中,由Action类充当业务逻辑的包装器,ActionForm是程序的状态视图JSP文件手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Struts框架组件ActionServlet类控制导航流ActionServlet根据URI来决定哪个Action类被用于处理请求,Action可以校验输入,并访问业务层以便从数据库检索信息Action需要知道页面提交了哪些内容,所以由ActionServlet根据请求URI来决

4、定将请求参数绑定到哪个ActionForm中,并传入ActionAction在完成业务逻辑后,返回一个ActionForward对象,ActionServlet根据ActionForward对象中的路径来调用页面完成响应Struts将这些信息绑定在一个ActionMapping对象中,一个ActionMapping对应一个请求URI,当请求路径到达的时候,ActionServlet就会查询ActionMapping对象,ActionMapping对象将告诉ActionServlet哪个Action类会被调用、哪个ActionForm类被用于传递页面数据以及哪些ActionForward将被用于

5、转向有关Action、ActionForm、ActionForward等信息,Struts通过一个配置文件:struts-config.xml文件来定义。手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Struts1.X 和Struts2.XStruts1.X 与Struts2.X 的差异较大Struts1.X 应用更加广泛Struts2.X 实际上是另外一个框架Webwork发展而来的后续课程将会有对webwork/Struts2.X的介绍以及实例操作手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂快速开始一个Struts项

6、目第一个项目,实现用户登录操作用户将看到一个登录页面,要求用户输入用户名以及密码如果用户名以及密码都是admin,提示登录成功否则提示登录失败1、用Eclipse创建一个J2EE Web应用项目,如右图所示2、下载并解压Struts项目*从Apache网站下载struts最新版*将压缩包解压到一个目录,此目录为STRUTS_HOME目录3、将STRUTS_HOME/lib目录下的所有.jar文件拷贝到刚创建的web项目的WebContent/WEB-INF/lib目录下4、配置ActionServlet:修改web项目的web.xml文件,添加如下Servlet映射配置(转下一页)手把手教程版

7、权所有:尚学堂科技Struts+Hibernate+Spring尚学堂web.xml 的配置 action org.apache.struts.action.ActionServlet config /WEB-INF/struts-config.xml 2 action *.do 手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂我们将需要创建如下文件一个ActionForm LoginActionForm.java一个Action LoginAction.javastruts-config.xml文件三个页面登录页面 login.jsp登录成功提示页面 log

8、in_success.jsp登录失败提示页面 login_error.jsp就这些!没别的了!手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂创建LoginActionForm.javaActionForm是一个JavaBean,需继承org.apache.struts.action.ActionForm类,它捕获通过HTTP请求传送的参数ActionForm针对每个HTML表单中的字段具有一个对应的属性ActionServlet匹配请求中的参数和ActionForm中的属性,并调用ActionForm中的setter方法,将参数传入ActionForm我们的

9、login.jsp有username和password两个表单字段(下面将会看到),所以,我们需要定义ActionForm中相应的setter方法:setUsername和setPassword方法ActionForm中的getter/setter方法,可以通过Eclipse集成环境,自动生成ActionForm中的内部属性全部定义为私有的(private),并通过公共(public)的getter/setter方法来访问package com.bjsxt.strutstest;import org.apache.struts.action.ActionForm;public class Lo

10、ginActionForm extends ActionForm private String username;private String password;/* * return Returns the password. */public String getPassword() return password;/* * param password The password to set. */public void setPassword(String password) this.password = password;/* * return Returns the userna

11、me. */public String getUsername() return username;/* * param username The username to set. */public void setUsername(String username) this.username = username;手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂创建LoginAction.javaAction是一个Java类,需继承org.apache.struts.action.Action类ActionServlet将会组装ActionForm,并将它传

12、递给ActionAction 通常负责:输入校验调用业务逻辑类执行业务逻辑操作决定返回哪个ActionForward我们的LoginAction做了如下事情,这些是一个Action通常都会做的最典型的事情:将输入的ActionForm强制转换为LoginActionForm从LoginActionForm对象中获取用户名以及密码的数据信息执行用户名及密码的逻辑判断操作(在通常的情况下,要将这些业务逻辑交给专门的类去处理,这里这样做是为了演示的需要)根据业务逻辑执行的结果,决定返回哪个ActionForward,我们在这里使用success这个标识来表示登录成功页面,用error标识来表示登录失

13、败页面public class LoginAction extends Action public ActionForward execute(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) throws Exception /将ActionForm强制转换为LoginActionFormLoginActionForm loginForm = (LoginActionForm)form;/从LoginActionForm中提取从页面表单传递过来的参数

14、String username = loginForm.getUsername();String password = loginForm.getPassword();/根据这些参数,执行业务逻辑操作if(admin.equals(username) & admin.equals(password)/如果用户名和密码均为admin,则转向登录成功页面return mapping.findForward(success);else/否则转向登录失败页面return mapping.findForward(error);手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚

15、学堂创建Struts配置文件struts-config.xml在WebContent/WEB-INF目录下创建struts-config.xml文件并添加如下内容(空白的struts-config.xml),紧接着,我们将往这个空白的配置文件中添加其它配置信息struts-config.xml文件,是由ActionServlet读取的配置文件,它定义了所有关于Action、ActionForm、ActionForward等的详细信息手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂添加ActionForm配置,配置LoginActionForm我们在struts

16、-config.xml文件中,在标签的内部,添加如下配置:标签内部可以包含多个标签标签必须指定name和type属性name属性是给此ActionForm一个标识名称type属性指定了此ActionForm是哪个类,必须是全路径的类名手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂添加Action配置,配置LoginAction我们在struts-config.xml文件中,紧接着标签的下面,添加对LoginAction的配置标签可以配置的重要属性包括:path-从页面上通过一个什么样的URL路径来访问Action(不包含.do)type 访问这个URL的时候

17、,调用哪个Action类,这是Action的全路径类名name 这个属性用来标识哪个ActionForm将被创建,并将提交的表单组件给它scope FormBean的作用域范围,可以取值为session和request,一般取值都是request手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂创建login.jsp在WebContent目录下创建login.jsp文件,如右边所示添加一个表单,action为login.do,这个login.do的意思,将会告诉struts的ActionServlet,它将需要调用哪个Action来处理这个表单的请求添加输入域u

18、sername,这个username的表单字段,必须跟LoginActionForm中的属性一致添加密码输入域password请登录请输入用户名: 请输入密码: 手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂创建login_success.jsp和login_error.jsplogin_success.jsp登录成功欢迎您,您已经成功登录!您创建的第一个Struts应用程序已成功运行!login_error.jsp登录失败您的登录失败了,可能原因是用户名或密码不正确,请返回重新输入 返回登录页面手把手教程版权所有:尚学堂科技Struts+Hibernate

19、+Spring尚学堂启动Tomcat并运行login.jsp运行login.jsp之后,能看到如下所示的登录表单输入用户名admin和密码admin,将能看到登录成功的界面输入其它用户名或密码,将能看到登录失败的界面手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂在这个简单的应用程序背后发生了什么?当你从浏览器输入地址:http:/localhost:8088/Struts-Test/login.jsp,Tomcat将按通常情况来处理这个JSP并返回浏览器当你提交表单,实际上是提交到了这样一个URL地址:http:/localhost:8088/Struts-

20、Test/login.do,Tomcat将会根据web.xml的配置,将这个请求发送给相应的Servlet,在我们的应用中,Tomcat将会把这个请求发送给org.apache.struts.action.ActionServlet这个类(请参看web.xml的配置)然后ActionServlet根据struts-config.xml的配置信息,调用LoginAction对象去处理这个请求,在此之前,它会将页面表单的请求数据封装到LoginActionForm对象中,并传递给LoginActionLoginAction返回一个ActionForward对象,包含了将要转向的路径信息Action

21、Servlet根据这个ActionForward对象所包含的路径信息,调用相应的页面去执行响应流程图请参考下一页手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂LoginAction应用程序的流程图手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Struts项目架构图手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Struts工作流程图手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Struts与MVC视图(View)在使用Struts框架的web应用程序中,

22、JSP以及相关的技术(如Taglib)等共同组成视图层,这一层的主要职责是显示用户界面。Struts提供了很多机制让我们能更加轻松地创建视图控制器(Controller)Struts中,ActionServlet是控制器层组件模型(Model)模型包括:系统的内部状态以及改变系统状态的动作Struts中的Action和ActionForm是模型的一部分Struts建议把”做什么”(Action)和”如何做”(业务逻辑)相分离手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂创建业务逻辑处理类(Model)使用单例模式(Singleton)来创建业务逻辑处理类创建

23、UserManager业务逻辑处理类创建validate方法创建UserNotFoundException创建PasswordErrorExceptionpackage com.bjsxt.strutstest;public class UserManager private static UserManager userManager; private UserManager() public static synchronized UserManager getInstance()if(userManager = null)userManager = new UserManager();r

24、eturn userManager; public void validate(String username,String password)throws UserNotFoundException,PasswordErrorExceptionif(!admin.equals(username)throw new UserNotFoundException();if(!admin.equals(password)throw new PasswordErrorException();手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Action中如何调用业务逻辑

25、处理类?我们看下面的代码:try UserManager.getInstance().validate(username,password);return mapping.findForward(success); catch (UserNotFoundException e) e.printStackTrace(); catch (PasswordErrorException e) e.printStackTrace();return mapping.findForward(error);通过添加业务逻辑处理类,我们将验证逻辑转移到了业务逻辑处理层手把手教程版权所有:尚学堂科技Struts+

26、Hibernate+Spring尚学堂页面之间数据的传递如何将数据从Action中传递到下一个JSP页面?一般使用request.setAttribute方法:在Action中,使用request.setAttribute(String name,Object data)方法往request中设置参数在JSP中,使用request.getAttribute(String name)来获取相应的参数在原来LoginAction的基础上编写相应的代码,测试页面数据传递传递登录成功者的帐号信息到成功页面,并显示手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂进一步理

27、解Struts控制流手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂细节:所有的页面请求由容器接收Struts的核心组件是ActionServlet,像其它所有Servlet一样,它是生存在容器中的,比如Tomcat、WebLogic等,当容器启动的时候,它会读取web.xml文件(部署描述符),告诉容器它会装入哪些Servlet一个标准的Servlet是通过servlet-mapping来设定,哪些请求,将会被提交到哪些servlet中Struts的servlet-mapping配置一般是: action *.do 这样配置的意思是:任何以.do结尾的URL

28、请求,都会被发送到ActionServlet进行处理手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂小结MVC基本结构Struts的主要组成部分如何编写ActionForm如何编写Action如何在配置文件中定义映射URL、Action以及ActionForm如何获取从页面传递到Action的数据如何将数据从Action传递到下一个页面如何将业务逻辑与表示层分离需牢记原则:不要在Action中进行业务逻辑的处理,业务逻辑应交给专门的Model层去做在业务逻辑层抛出异常,并在Action中捕捉和处理手把手教程版权所有:尚学堂科技Struts+Hibernate+

29、Spring尚学堂Struts Taglib易于使用,能代替直接在页面上写JAVA脚本便于重用用Struts Taglib实现成功页面在以后的开发中,将逐步介绍一些常用的Taglib手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂尝试简单的tag lib使用在JSP文件的头部添加如下声明:关于struts tag lib的说明,可以查看相关的参考文档常用的struts tag lib和和手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂JSTL简介:SUN的标准Taglib库JSP标准标签库(JSP Standard Tag L

30、ibrary,JSTL )迭代和条件判断 数据管理格式化 XML 操作 数据库访问 函数标签库表达式语言(EL)EL隐式对象存取器运算符手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂在项目中使用JSTL拷贝jstl.jar和standard.jar到WEB-INF/lib目录下在JSP中添加伪指令常用JSTL标记、和手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂进一步理解ActionFormActionForm的要求必须扩展自org.apache.struts.action.ActionForm如果要获取表单的值,必须定义

31、一个public属性如果要求在将ActionForm传递到Action之前进行校验,必须实现validate方法如果想要在组装前初始化属性,必须实现reset方法DynaActionForm举例说明DynaActionForm的配置DynaActionForm的使用手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂ActionForm作为表单字段收集器通过HTTP提交表单数据通过HTTP上传文件通过例子演示文件上传的简易方法通过HTTP提交空字段修改原来的JSP文件,提交空字段手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Ac

32、tionForm作为类型转换器所有从表单提交到后台的数据均为字符串类型如何利用ActionForm自动转换int数据类型举例说明如何利用ActionForm自动转换boolean数据类型举例说明如何利用ActionForm自动转换Date类型定义Converter注册Converter举例说明如何利用ActionForm自动转换Double类型举例说明手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂ActionForm作为传输对象ActionForm 可以被其它bean或者过程作为数据载体。Transfer 对象 (也称为值对象(value object) )

33、用来通过发送粗糙规整的数据视图来交换精细规整的数据。ActionForm 的各个属性都必须是可变的。提示:使用粗糙规整 ActionForm来减小类维护。应用中的表单一般共享属性创建一个基本的 ActionForm,具有表单需要的所有属性手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂ActionForwardActionForward能做什么?在Action中,经常问的问题是:“OK,操作成功了,然后呢?”ActionForward会回传给ActionServletActionForward中的路径,可以是一个带参数的URIActionForward的属性n

34、amepathredirectclassName转发(forward)与重定向(redirect)全局ActionForward与局部ActionForward手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂动态创建ActionForward将ActionForward定义在一个Struts 配置文件中是个好的选择但也可以在Action中动态创建ActionForward,而不需要在配置文件中指定如下所示:ActionForward forward = new ActionForward(/do/itemEdit?action=edit);举例说明手把手教程版

35、权所有:尚学堂科技Struts+Hibernate+Spring尚学堂ActionMapping理解ActionMappingpathforwardtypenamescopevalidateinputparameterunknow ActionMapping手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Scope属性在Action映射配置中,Scope属性可以取值为:request或sessionScope属性表示:Struts框架在将ActionForm对象(与目标Action匹配的ActionForm)传送到Action之前,会将ActionForm对象

36、保存的位置如:scope=“request”配置,将指示struts调用request.setAttribute(“ActionForm名称”,ActionForm对象)方法,将ActionForm对象保存到request。其中,ActionForm名称与struts-config.xml配置中的ActionForm名称一致,如:,其中uploadForm就是其名称。我们明白scope属性的意义之后,就可以利用struts的这些特性,来解决开发过程中的某些常见问题手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂常见问题:如何在程序出现异常的时候返回录入界面重新

37、录入假设现在要在一个页面上输入用户的信息(可能会有十几个属性值需要输入),用户不小心输入了一个重复的帐号,而帐号是不允许重复的,这个时候,系统应该提示用户有关帐号重复的信息,同时让用户重新选择一个帐号。这种情况下,我们需要返回用户录入界面,让用户修改帐号字段。现在的问题是:如何在返回这个录入界面的时候,将用户输入的其它信息保持住?手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂搞定Action对象如果应用需要保存一个记录到数据库中,典型的过程可能是ActionForward提供一个链接到输入页面ActionForm捕获输入ActionMapping配置Acti

38、onAction将输入送到数据库中(通常会将这一步操作委托给业务逻辑类去实现)J2EE是一个多线程的环境,服务器针对每个请求启动一个线程来处理。是一个多线程的环境,服务器针对每个请求启动一个线程来处理。所以有可能会有多个线程同时访问一个所以有可能会有多个线程同时访问一个Servlet实例的情况实例的情况在在Struts里面也是一样的,有可能会有多个线程同时访问一个里面也是一样的,有可能会有多个线程同时访问一个Action实例实例的情况的情况所以必须保证所以必须保证Action类中的方法具有类中的方法具有“可重入性可重入性”,即不能在,即不能在Action的的方法里改变实例变量的值方法里改变实例

39、变量的值手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Action的主要职责校验输入数据调用业务逻辑方法检测处理异常根据逻辑进行转向操作手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂I18N问题什么是I18N问题?在英文中, 国际化(Internationalization)被缩写为I18N, 即只取首尾两个字母, 中间字母为18个 问题在哪里?页面字符串硬编码异常消息的硬编码提示信息的硬编码手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Java如何支持I18N?一个简单的例子不支持I1

40、8N的例子 NoI18NSample.java支持I18N的例子我们需要将硬编码文本转移到外部的资源文件编写MessagesBundle.properties编写MessagesBundle_zh_CN.properties编写MessagesBundle_en_US.properties编写I18NSample.java运行I18NSample.java乱码?因为资源文件必须是Latin-1或Unicode编码(如udddd)的字符使用native2ascii工具,将中文资源文件进行转换手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Java支持I18N的编

41、码过程总结1、创建属性文件(可能要用native2ascii工具转换)2、定义Locale对象3、创建一个ResourceBundle对象ResourceBundle对象用于分离跟本地相关的数据如果找不到相应语言或国家代码的属性文件,将使用默认的属性文件(即没有标识语言和国家代码的属性文件:MessagesBundle.properties)其创建方式如下:message = ResourceBundle.getBundle(MessagesBundle, currentLocale); 第一个参数,表示要从哪些资源属性文件中(MessagesBundle_XX.properties)获取数据

42、第二个参数,是一个Locale对象,表示要选择哪个资源属性文件4、从ResourceBundle对象中获取数据手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Locale对象我们通过指定一个语言代码和国家代码来创建一个Locale对象国家代码是可选的语言代码是小写字母;国家代码是大写字母语言代码是小写字母;国家代码是大写字母Locale.getDefault()可以获得系统当前的LocaleJava都支持哪些语言代码和国家代码?DateFormat.getAvailableLocales() 语言代码标准:http:/ftp.ics.uci.edu/pub/i

43、etf/http/related/iso639.txt国家代码标准:http:/userpage.chemie.fu-berlin.de/diverse/doc/ISO_3166.html与Locale相关的数据:消息文本(带参数?)日期(时间)货币(数字)等等。手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Struts如何支持I18N1、需要在struts配置文件中指定资源属性文件的位置和名称,如2、在相应的位置放置相应的文件3、在JSP页面中使用来输出文本,以避免硬编码以登录页面的国际化作为例子讲解创建相应的资源属性文件用标签替换登录页面的硬编码文本测试

44、(更改网页显示语言,以便测试不同的版本)手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂关于message-resources 配置中parameter的值parameter的值,可以指定资源文件的位置和名称举例:表示在类路径根目录(WEB-INF/classes目录)下有MessageResources_XX_XX.properties文件(注意:国家代码可以省略,跟java中对资源属性文件的处理一样) 表示在类路径根目录下,有一个resources目录,在这个resources目录中存放着所有的application_XX_XX.properties资源属

45、性文件手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂如何用程序切换网页显示的语言struts利用在session中存放一个Locale对象来达到设置当前语言的目的默认的情况下,struts根据网页向后台提交时所包含的语言编码信息来提供缺省的Locale对象,这就是我们为什么可以通过更改网页显示语言设置,就能显示不同的语言文字的原因。struts在session中存放的这个Locale对象,取名为:Globals.LOCALE_KEY 的值,Globals是struts框架提供的一个对象利用这个原理,我们可以用编程的方式来手工切换整个应用系统的语言。举例说明C

46、hangeLanguageAction手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Struts消息处理为什么需要消息处理?比如登录成功的提示比如创建失败的提示等等总之,程序总是要通过界面来跟用户交互,所以,在交互的在交互的过程中过程中,就产生了众多的消息文本struts提供了专门的处理机制,来将这些消息文本国际化,避免消息文本的硬编码消息处理,就是在Action和JSP之间传递的消息文本的处理(区别于JSP页面硬编码文本的消息,JSP页面消息可以使用标签来处理)Struts交互消息,是通过ActionMessages等对象,以及相应的标签来处理的手把手教程

47、版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂 如何创建消息对象?ActionMessages与ActionMessage对象ActionMessages对象是ActionMessage对象的集合一个ActionMessage对象,代表一个国际化消息文本(字符串)如何创建ActionMessages对象?ActionMessages messages = new ActionMessages();如何创建ActionMessage对象?ActionMessage msg = new ActionMessage(“key”);其构造方法带的参数,就是一个在资源属性文件中

48、的key,所以,它能表示一个国际化消息文本如何将ActionMessage对象添加到ActionMessages对象中?messages.add(“message_id”,msg);第一个参数(message_id)表示本ActionMessage对象在ActionMessages对象中区别于其它ActionMessage对象的标识符手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂如何将消息对象从Action中传递到下一个页面(JSP)?首先我们要决定的是,我们要传递的消息是普通消息普通消息还是错误消息错误消息?普通消息:即普通的消息文本错误消息:即提示错误的

49、消息文本本质上,这两种消息没有什么区别,都是消息文本,但是如果一个页面同时需要显示普通的消息文本和错误消息文本的时候,就需要进行区分了,比如不同类型的消息文本可能要用不同的样式来显示通过一句简单的代码,将ActionMessages对象保存到HttpServletRequest对象中保存普通消息:保存普通消息:this.saveMessages(request,messages);保存错误消息:保存错误消息:this.saveErrors(request,messages);这就是调用父类(Action)所提供的方法saveMessages()/saveErrors()来保存消息对象实际上,父

50、类的saveMessages()方法,将消息对象保存在了request中,并命名为Globals.MESSAGE_KEY saveErrors()方法,将消息对象保存在了request中,并命名为Globals.ERROR_KEY 手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂如何在JSP中使用消息对象?使用标签来显示消息标签既可以显示普通消息,也可以显示错误消息标签的重要属性:name 消息对象的名称,如果我们调用saveMessages/saveErrors方法来传递消息,那么这个名字不需要标识(struts使用缺省的名称,即Globals.MESSAG

51、E_KEY 或Globals.ERROR_KEY )id (这是必需的属性这是必需的属性)因为我们传递的是ActionMessages对象,而不是ActionMessage对象,ActionMessages对象相当于一个集合,我们需要在JSP上依次输出它所包含的消息,因此需要一个id标识一个变量来临时存放其每条消息(与与标签的标签的id属性的意义是一样的属性的意义是一样的)property 我们传递的ActionMessages对象,包含了多条消息文本,如果我们只需要显示其中一条,则可以通过property属性来指定显示哪条消息message 可以取值为true或false,如果取值为true

52、,将显示普通消息,如果取值为false,将显示错误消息手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂标签标签只显示错误消息标签与标签类似,但无id属性标签通过提供header/footer属性以及prefix/suffix属性来定制每条消息的显示格式header/footer 定义整个错误消息显示之前(之后)要显示的内容,这些内容也是在资源属性文件中定义的一些key值,默认的情况下,它们的取值分别为:errors.header和errors.footerprefix/suffix 定义每条错误消息显示之前(之后)要显示的内容,这些内容也是在资源属性文件中定义

53、的一些key值,默认的情况下,它们的取值分别为:errors.prefix和errors.suffix举例如下:errors.header=errors.prefix=errors.suffix=errors.footer=手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Struts的异常自动处理机制编程式异常处理即我们在Action中调用业务逻辑层对象的方法时,用try catch的方式来截获异常之后,手工对异常进行处理我们以前的开发过程中,都是使用编程式的异常处理在编程式异常处理的时候,我们可以使用struts的消息处理机制(前面所讲的内容)来对这些异常信

54、息进行处理自动异常处理机制即在Action中不捕捉异常,而是将异常抛出给struts框架处理我们需要在配置文件中指示struts如何处理这些被抛出的异常使用元素来定义自动异常处理手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂元素的配置及使用元素的配置,指示了struts如何处理异常的方式在通常的情况下,我们得到异常以后,需要将页面导航到一个错误提示的页面,提示错误信息元素配置的关键属性是:key 即这个异常所对应的错误提示消息文本的key,这个key的值,需要在资源属性文件中进行定义type 即定义需要处理哪种类型的Exceptionpath 定义一旦出现异

55、常,需要转向哪个页面来进行提示,如果不定义path属性,默认情况下,将使用Action配置中的input属性的值来作为转向的页面如何显示错误消息?在JSP页面中,使用标签,即可将其异常对应的错误消息文本进行显示(测试login.jsp页面)手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂标准ActionStruts框架缺省提供了一些Action,来完成一些常见的功能ForwardAction - ForwardAction仅仅简单的转发控制到其他资源为什么需要ForwardAction?目的是发出一个RequestDispatcher 转发ForwardAct

56、ion 的绝大多数使用是作为Action的占位符ForwardAction 创建一个请求分派器,并根据ActionMapping提供的上下文相关的URI转发控制许多 Struts 开发人员避免从一个页面直接连接到其他地方而是通过Action 或者 ActionForward来传递控制。这保证了工作流在Struts 配置的控制之下,在这里可以进行集中管理。然而,许多页面并不需要特殊的预处理(至少还不需要)。如果为这些页面创建ActionMapping ,你可以使用ForwardAction ,来仅进行路由控制。如果以后,需求改变,又需要进行预处理,你可以改变mapping 来为那个页面引用到一个

57、Action。因为链接是引用到mapping, 而不是Action类, 所以你可以修改Action类而不用改变链接。手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂标准的Base ActionDispatchAction 避免每个Action创建一个类DispatchAction的配置方法添加parameter属性到Action的配置中unspecified方法举例说明DispatchAction的使用手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂struts配置中的路径与模式匹配struts配置中的action,有一个pa

58、th属性,它表明请求的URI一般情况下,我们需要在配置文件中明确指定某个特定的URI,如path=“/user/add”在一些大型应用中,如果能够制定一套严格的路径及其操作规范的话,我们可以利用path的路径模式匹配功能,来简化struts配置文件繁琐的编写工作量假设有如下规范:手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂路径匹配规范示例对user对象的所有处理Action,均需要以如下的路径进行访问:/user/add.do 处理用户添加的有关操作/user/delete.do 处理用户删除的有关操作/user/update.do 处理用户更新的有关操作

59、所有操作(Action)对应的JSP如下:所有操作成功(失败)之后的转向页面,有如下命名规范:/user/add.do - /user/add_success.jsp或/user/add_error.jsp/user/delete.do - /user/delete_success.jsp或/user/delete_error.jsp所有操作的输入界面有如下命名规范:添加操作 - /user/add_input.jsp更新操作 - /user/update_input.jsp手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Action配置示例手把手教程版权所有

60、:尚学堂科技Struts+Hibernate+Spring尚学堂Action配置解释所有的/user/*.do请求,都将由UserAction这个类来处理,UserAction类继承DispatchAction,它将根据传入的method参数的值,来分发到不同的方法来进行处理在UserAction类中的任何一个方法,都可以返回index/success/error/input等名称的ActionForward根据请求路径的不同,即使调用相同的返回代码,但其转向也将不同,如:/user/add.do?method=add请求,将被转发给UserAction类的add方法处理,假设它用mappin

61、g.findForward(“success”);来返回成功页面,这将转向的实际JSP页面是:/user/add_success.jsp而/user/delete.do?method=delete请求,将被转发给UserAction类的delete方法处理,假设它用mapping.findForward(“success”);来返回到删除成功页面,这将转向的实际JSP页面是:/user/delete_success.jsp,所以,不同不同URI请求的相同名称的返回页面将是不同的请求的相同名称的返回页面将是不同的。而/user/index.do请求(或者任何一个其它请求,如/user/abcd.

62、do或/user/test.do),都因为没有传递method参数,而触发调用UserAction的unspecified方法手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Struts回顾Struts tag lib的配置和使用JSTL的配置和使用错误消息的处理ActionForm的多种用途DynaActionFormActionForward的主要作用,如何动态创建ActionForwardAction的主要职责和处理过程如何保证Action的线程安全性国际化与资源文件的配置、使用ForwardActionDispatchAction尚学堂 手把手教程授课

63、:王勇授课:王勇版权所有:尚学堂科技Struts+Hibernate+SpringHibernate开源O/R映射框架手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂课程目标q课程目标:课程目标:q理解O/R Mapping原理q掌握Hibernate开发的相关知识q能使用Hibernate进行实际项目开发qHibernate高手进级:性能优化策略手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂目录什么是Hibernate快速体验Hibernate的开发步骤认识Hibernate基本核心接口Hibernate的对象关系映射Hi

64、bernate查询语句(HQL)手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Hibernate?直接使用JDBC操作数据库的步骤很繁琐JDBC操作的是关系型数据库我们用JAVA开发程序,则使用面向对象的思想Hibernate正是在这两种不同的模型之间建立关联,Hibernate给我们提供了利用面向对象的思想来操作关系型数据的接口手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂什么是关系模型(Relational Model)?关系模型把世界看作是由实体(Entity)和联系(Relationship)构成的。 所谓实体就是

65、指现实世界中具有区分与其它事物的特征或属性并与其它实体有联系的对象。在关系模型中实体通常是以表的形式来表现的。表的每一行描述实体的一个实例,表的每一列描述实体的一个特征或属性。 所谓联系就是指实体之间的关系,即实体之间的对应关系。 1:1 1:nm:n 关系数据库表字段主键外键手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂什么是面向对象?面向对象三大特征:封装、继承(一般与特殊)、多态(覆盖与重载)类对象属性关系一般与特殊关系(is a)组成(has a)关联及其多重性1:11:nm:n双向关联与单向关联手把手教程版权所有:尚学堂科技Struts+Hiber

66、nate+Spring尚学堂对象关系映射(Object Relational Mapping,简称ORM) ORM是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将java程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。 Why ORM?面向对象的开发方法是当今企业级应用开发环境中的主流开发方法 关系数据库是企业级应用环境中永久存放数据的主流数据存储系统 字母O起源于“对象”(Object),而R则来自于“关系”(Relational)。几乎所有的程序里面,都存在对象和关系数据库。在业

67、务逻辑层和呈现层中,我们是面向对象的。当对象信息发生变化的时候,我们需要把对象的信息保存在关系数据库中。 当你开发一个应用程序的时候(不使用O/R Mapping),你可能会写不少数据访问层的代码,用来从数据库保存,删除,读取对象信息,等等。而这些代码写起来总是重复的。 手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂对象关系映射模式属性映射类映射关联映射一对一一对多多对多手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂什么是Hibernate?对象/关系映射一直都是数据库技术中的难点,尽管人们提出了许多方案解决这个问题,但都

68、不能完全做到即便利又高效。EJB的推出让人们看到了希望,但实践证明实体Bean的效率并不高,并且还十分难于为初学者理解。由Gavin King创建的Hibernate框架,从某种程序上正在朝着正确的方向迈走,并且得到越来越多IT从业人员的认可。就像当年的Struts框架一样,Hibernate也已经在许多项目中得到广泛应用。Hibernate由于投注了更多的精力在提升效率上,使用起来又十分方便,新版的EJB规范正在向Hibernate方向靠拢。正是由于得到广泛的认可,Hibernate已经成为程序员必须掌握的技术之一。手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring

69、尚学堂Hibernate能做什么? - 理解O/R映射Hibernate能帮助我们利用面向对象面向对象的思想,开发基于关系型数据库基于关系型数据库的应用程序第一:将对象数据保存到数据库第二:将数据库数据读入对象中基于B/S的典型三层架构关于分关于分层 业务逻辑层和持久化层绝对不能依赖于展现层手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Hibernate与O、R之间的关系手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂快速体验Hibernate 安装以及创建新的项目下载Hibernate,并解压缩使用Eclipse创建新的项

70、目引入Hibernate及其依赖库(jar包)引入mysql数据库驱动包打开mysql控制台,创建测试数据库”hibernate”Create database hibernate;Use hibernate手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂创建Hibernate配置文件 hibernate.cfg.xml jdbc:mysql:/127.0.0.1/hibernatecom.mysql.jdbc.Driverrootmysql org.hibernate.dialect.MySQLDialect 手把手教程版权所有:尚学堂科技Struts+Hi

71、bernate+Spring尚学堂创建持久化类 User.javapublic class User private String id;private String name;private String password;private Date createTime;private Date expireTime;.getters/setters手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂创建类的映射文件 User.hbm.xml 手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂将类的映射文件加入Hibernate为

72、了让Hibernate能够处理User对象的持久化,需要将它的映射信息加入到Hibernate中加入的方法很简单,在Hibernate配置文件中加入:即可resource属性指定了映射文件的位置和名称手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂创建数据库表 利用SchemaExport工具类利用Hibernate提供的工具类来创建数据库表创建ExportToDB类public class ExportToDB public static void main(String args) throws Exception/读取配置文件Configuration

73、cfg = new Configuration().configure();/创建SchemaExport对象SchemaExport export = new SchemaExport(cfg);/创建数据库表export.create(true,true);手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂将对象保存到数据库 UserTest1.javapublic static void main(String args) throws ExceptionConfiguration cfg = new Configuration().configure()

74、;SessionFactory factory = cfg.buildSessionFactory();Session session = factory.openSession();session.beginTransaction();User user = new User();user.setName(管理员);user.setPassword(admin);user.setCreateTime(new Date();user.setExpireTime(new Date();session.save(user);session.getTransaction().commit();if(

75、session.isOpen()session.close();手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂实际操作体验Hibernate开发步骤按照上面的步骤,先快速体验一下Hibernate实际所做的事情Hibernate开发步骤实体类(持久化类)的设计实体类与关系数据库的映射应用的开发手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂认识Hibernate的基本组件实体类实体类映射文件重点学习的部分Hibernate配置文件辅助工具手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Hib

76、ernate核心接口手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Configuration概述:概述:Configuration 类负责管理Hibernate 的配置信息。它包括如下内容:qHibernate运行的底层信息:数据库的URL、用户名、密码、JDBC驱动类,数据库Dialect,数据库连接池等。qHibernate映射文件(*.hbm.xml)。Hibernate配置的两种方法:配置的两种方法:q属性文件(hibernate.properties)。调用代码:Configuration cfg = new Configuration(); qX

77、ml文件(hibernate.cfg.xml)。调用代码:Configuration cfg = new Configuration().configure();手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂SessionFactory概述:概述:应用程序从SessionFactory(会话工厂)里获得Session(会话)实例。它在多个应用线程间进行共享。通常情况下,整个应用只有唯一的一个会话工厂例如在应用初始化时被创建。然而,如果你使用Hibernate访问多个数据库,你需要对每一个数据库使用一个会话工厂。 会话工厂缓存了生成的SQL语句和Hiberna

78、te在运行时使用的映射元数据。调用代码:调用代码:SessionFactory sessionFactory = cfg.buildSessionFactory();说明:SessionFactory由Configuration对象创建,所以每个Hibernate配置文件,实际上是对SessionFactory的配置手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Session(会话)概述:概述:qSession不是线程安全的,它代表与数据库之间的一次操作,它的概念介于Connection和Transaction之间。q Session也称为持久化管理器,因为

79、它是与持久化有关的操作接口。q Session通过SessionFactory打开,在所有的工作完成后,需要关闭。q它与Web层的HttpSession没有任何关系。调用代码调用代码Session session = sessionFactory.openSession();手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂持久化对象的状态瞬时对象瞬时对象(TransientObjects):使用new 操作符初始化的对象不是立刻就持久的。它们的状态是瞬时的,也就是说它们没有任何跟数据库表相关联的行为,只要应用不再引用这些对象(不再被任何其它对象所引用),它们的

80、状态将会丢失,并由垃圾回收机制回收。 持久化对象持久化对象(PersistObjects):持久实例是任何具有数据库标识的实例。它有持久化管理器Session统一管理,持久实例是在事务中进行操作的它们的状态在事务结束时同数据库进行同步。当事务提交时,通过执行SQL的INSERT、UPDATE和DELETE语句把内存中的状态同步到数据库中。离线对象离线对象(DetachedObjects):Session关闭之后,持久化对象就变为离线对象。离线表示这个对象不能再与数据库保持同步,它们不再受Hibernate管理。手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂持

81、久化对象的生命周期(lifecycle)手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Transaction(事务)概述:概述: 它将应用代码从底层的事务实现中抽象出来这可能是一个JDBC事务,一个JTA用户事务或者甚至是一个公共对象请求代理结构(CORBA)允许应用通过一组一致的API控制事务边界。这有助于保持Hibernate应用在不同类型的执行环境或容器中的可移植性。调用代码:调用代码: Transaction tx = session.beginTransaction();v注:注:使用Hibernate进行操作时必须显式的调用Transaction

82、(默认:autoCommit=false)。手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂从代码中体会Session和TransactionSession session = factory.openSession();session.beginTransaction();User user = new User();user.setName(管理员);user.setPassword(admin);user.setCreateTime(new Date();user.setExpireTime(new Date();session.save(user);s

83、ession.getTransaction().commit();session.beginTransaction();User user1 = new User();user1.setName(jjj);session.save(user1);session.getTransaction().commit();if(session.isOpen()session.close();手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Query概述:概述:Query(查询)接口允许你在数据库上执行查询并控制查询如何执行。查询语句使用HQL或者本地数据库的SQL方言编

84、写。调用代码:调用代码:Query query = session.createQuery(“from User”); 关于HQL,在后续的课程中,将会介绍手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Query举例Configuration cfg = new Configuration().configure();SessionFactory factory = cfg.buildSessionFactory();Session session = factory.openSession();session.beginTransaction();Quer

85、y query = session.createQuery(from User);List users = query.list();for (Iterator iter = users.iterator(); iter.hasNext();) User user = (User) iter.next();System.out.println(user name = +user.getName();session.getTransaction().commit();if(session.isOpen()session.close();手把手教程版权所有:尚学堂科技Struts+Hibernat

86、e+Spring尚学堂Hibernate的对象关系映射映射文件的基本结构举例 . 手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂hibernate-mapping元素可以包含的子元素class 描述被映射的类subclass/joined-subclass 在继承关系的映射中会用到query 将查询语句定义在配置文件中.手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂class元素常用属性name 实体类的类名table 被映射到数据库表的名称可以包含的常见子元素id 主键定义property 属性定义关系映射定义(一对多、

87、多对一等)手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂主键 id被映射的类必须要有一个id定义通常使用逻辑主键逻辑主键:没有意义的唯一标识符业务主键:有意义的唯一标识符Hibernate使用generator类来生成主键Hibernate自带了很多generator(不同的主键生成策略)int/long nativeString - uuid我们也可以定义自己的generator实现IdentifierGenerator接口一般情况下不需要实现自己的generator手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂主键生成

88、策略generatorgenerator主键生成器,每个主键都必须定义相应的主键生成策略。它用来为持久化类实例生成唯一的标识。Hibernate内置的主键生成策略内置的主键生成策略q数据库提供的主键生成机制。identity、sequence(序列) 。q外部程序提供的主键生成机制。increment (递增) ,hilo(高低位) ,seqhilo(使用序列的高低位 ),uuid.hex(使用了IP地址+JVM的启动时间(精确到1/4秒)+系统时间+一个计数器值(在JVM中唯一) ),uuid.string。q其它。native(本地),assigned(手工指定),foreign(外部引用

89、)。手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂普通属性映射 - property可使用的常见属性如下:name 对应类的属性名称type 指定属性的类型,一般情况下可以不用指定,由hibernate自动匹配(可参考文档中的有关说明)length 指定长度column 指定属性所对应的数据库字段的名称,如果不指定,就是属性的名称手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂多对一关联映射 many-to-oneUser-Group 多个用户属于某个组从代码上体现为:public class Group privte St

90、ring id;private String name;.public class Userprivate String id;privte String name; private Group group;public Group getGroup()return group;public void setGroup(Group group)this.group = group; 手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂many-to-one映射的编写many-to-one的映射最常用,也是最容易理解和编写的生成的DDL语句如下create tabl

91、e T_Group (id varchar(255) not null, name varchar(255), primary key (id)create table User (id varchar(255) not null, name varchar(255), password varchar(255), createTime datetime, expireTime datetime, groupid varchar(255), primary key (id)alter table User add index FK285FEBC3D18669 (groupid), add co

92、nstraint FK285FEBC3D18669 foreign key (groupid) references T_Group (id)从生成的DDL语句,我们可以知道,实际上是在User表上建立了一个指向Group表的外键关联外键关联手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂重要属性cascade重要属性 cascade(级联)级联的意思是指定两个对象之间的操作联动关系,对一个对象执行了操作之后,对其指定的级联对象也需要执行相同的操作总共可以取值为:all、none、save-update、deleteall-代表在所有的情况下都执行级联操作no

93、ne-在所有情况下都不执行级联操作save-update-在保存和更新的时候执行级联操作delete-在删除的时候执行级联操作如:编写实际例子测试many-to-one以及cascade属性的配置手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂cascade实际上意味着什么?无cascade配置的User-Group执行代码配置java代码:Group group = new Group();group.setName(jkjk);User user = new User();user.setName(管理员);user.setGroup(group);ses

94、sion.save(user);执行结果:抛出org.hibernate.TransientObjectException异常,以上代码中,group对象是一个瞬时对象,user对象引用了一个瞬时对象,所以在保存的时候出现异常手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂无cascade配置时正确的java执行代码为避免异常,我们可以需要将group对象保存Group group = new Group();group.setName(jkjk);/ /执行执行savesave操作之后,操作之后,groupgroup对象变成持久化对象的状态对象变成持久化对象

95、的状态session.save(group);User user = new User();user.setName(管理员);user.setGroup(group);session.save(user);手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂添加cascade配置下面的代码(最初的代码)Group group = new Group();group.setName(jkjk);User user = new User();user.setName(管理员);user.setGroup(group);session.save(user);可正确执行

96、cascade配置,使得hibernate在管理对象的时候,对cascade对象执行了级联操作手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂一对一关联映射 (one-to-one)两个对象之间是一对一的关系,如Person-IdCard有两种策略可以实现一对一的关联映射主键关联:即让两个对象具有相同的主键值,以表明它们之间的一一对应的关系;数据库表不会有额外的字段来维护它们之间的关系,仅通过表的主键来关联唯一唯一外键关联:外键关联,本来是用于多对一的配置,但是如果加上唯一的限制之后,也可以用来表示一对一关联关系;手把手教程版权所有:尚学堂科技Struts+H

97、ibernate+Spring尚学堂一对一 (主键关联映射)Person类public class Person private int id; private IdCard idCard; .映射文件 idCard . IdCard类public class IdCard private int id; private Person person; 映射文件 . 手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂一对一 (唯一外键关联映射)Mankind类public class Mankind private String id;private String

98、 name;private Nose nose;关联映射 Nose类public class Nose private String id;private Mankind mankind;关联映射 property-ref:在这种情况下,必须指定此属性,它表示本类(Nose)的主键将会与关联类(Mankind)的此属性(nose)相对应手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂一对多关联映射 (one-to-many)在对象模型中,一对多的关联关系,使用集合来表示比如Classes(班级)和Student(学生)之间是一对多的关系public class

99、 Classes private String id;private String name;private Set students;.public class Student private String id;private String name; .手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂一对多关联映射文件Classes映射文件 手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂关于lazy属性lazy 延迟加载(懒加载),一般用于集合的抓取策略,也就是说只在需要用到的情况下,再发出select语句,将其相关的

100、对象查询出来set默认lazy属性的值是true,即hibernate会自动使用懒加载策略,以提高性能举例说明 手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂关于inverse属性inverse 标记由哪一方来维护关联关系(双向关联中会用到)inverse默认值为false如果inverse设置为true,表示将由对方维护两者之间的关联关系举例说明 手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂多对多关联映射 (many-to-many)一般的设计中,多对多关联映射,需要一个中间表Hibernate会自动生成中间表Hibe

101、rnate使用many-to-many标签来表示多对多的关联多对多的关联映射,在实体类中,跟一对多一样,也是用集合来表示的手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂many-to-many(1) column(必需): 中间映射表中,关联目标表的关联字段(2) class (必需): 类名,关联目标类 (1)(1) column(必需):当前表的关联字段手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂例子(many to many):student-trainClass手把手教程版权所有:尚学堂科技Struts+Hibe

102、rnate+Spring尚学堂继承继承实现的三种策略继承实现的三种策略q单表继承。每棵类继承树使用一个表(table per class hierarchy) q具体表继承。每个子类一个表(table per subclass) q类表继承。每个具体类一个表(table per concrete class)(有一些限制)手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂每个类继承树对应一张表因为类继承树肯定是对应多个类,要把多个类的信息存放在一张表中,必须有某种机制来区分哪些记录是属于哪个类的。这种机制就是,在表中添加一个字段,用这个字段的值来进行区分。用hi

103、bernate实现这种策略的时候,有如下步骤:父类用普通的标签定义在父类中定义一个discriminator,即指定这个区分的字段的名称和类型如:子类使用标签定义,在定义subclass的时候,需要注意如下几点:Subclass标签的name属性是子类的全路径名在Subclass标签中,用discriminator-value属性来标明本子类的discriminator字段(用来区分不同类的字段)的值Subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),也可以与class标签平行。 当subclass标签的定义与class标签平行的时候,需要在subcl

104、ass标签中,添加extends属性,里面的值是父类的全路径名称。子类的其它属性,像普通类一样,定义在subclass标签的内部。手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂每个子类一张表(除非将父类定义成抽象的,否则父类也是一张表)这种策略是使用joined-subclass标签来定义子类的。父类、子类,每个类都对应一张数据库表。在父类对应的数据库表中,实际上会存储所有的记录,包括父类在父类对应的数据库表中,实际上会存储所有的记录,包括父类和子类的记录;和子类的记录;在子类对应的数据库表中,这个表只定义了子类中所特有的属性映射的字段。子类与父类,通过相同

105、的主键值来关联。实现这种策略的时候,有如下步骤:父类用普通的标签定义即可父类不再需要定义discriminator字段子类用标签定义,在定义joined-subclass的时候,需要注意如下几点:Joined-subclass标签的name属性是子类的全路径名Joined-subclass标签需要包含一个key标签,这个标签指定了子类和父类之间是通过哪个字段来关联的。如:,这里的column,实际上就是父类的主键对应的映射字段名称。Joined-subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),也可以与class标签平行。 当Joined-subcl

106、ass标签的定义与class标签平行的时候,需要在Joined-subclass标签中,添加extends属性,里面的值是父类的全路径名称。子类的其它属性,像普通类一样,定义在joined-subclass标签的内部。手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂每个具体子类一张表这种策略是使用union-subclass标签来定义子类的。每个子类对应一张表,而且这个表的信息是完备的,即包含了所有从父类继承下来的属性映射的字段(这就是它跟joined-subclass的不同之处,joined-subclass定义的子类的表,只包含子类特有属性映射的字段)。实

107、现这种策略的时候,有如下步骤:父类用普通标签定义即可子类用标签定义,在定义union-subclass的时候,需要注意如下几点:Union-subclass标签不再需要包含key标签(与joined-subclass不同)Union-subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),也可以与class标签平行。 当Union-subclass标签的定义与class标签平行的时候,需要在Union-subclass标签中,添加extends属性,里面的值是父类的全路径名称。子类的其它属性,像普通类一样,定义在Union-subclass标签的内部。这个

108、时候,虽然在union-subclass里面定义的只有子类的属性,但是因为它继承了父类,所以,不需要定义其它的属性,在映射到数据库表的时候,依然包含了父类的所有属性的映射字段。手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂双向关联概念:概念:双向关联允许通过关联的任一端访问另外一端。在Hibernate中, 支持两种类型的双向关联。q一对多(one-to-many),Set或者bag值在一端, 单独值(非集合)在另外一端 。q多对多(many-to-many),两端都是set或bag值。手把手教程版权所有:尚学堂科技Struts+Hibernate+Spri

109、ng尚学堂例子(双向关联):group-user 手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂例子:从Java代码看group-user双向关联的inverse概念概念:inverse用来标识双向关联的关联关系由哪一端维护。默认inverse的值为false,由主动方负责维护关联关系;如果设为true,则由反向一端维护关联关系。用例:用例:我们假设已经有一个Group类的实例:adminGroup,现在我们要新增一个用户,并且将用户分配到adminGroup中。qinverse=“false”,由主动方Group负责维护group-user的关联关系.Us

110、er user = new User(“Jak”);adminGroup.getUsers.add(user);session.save(user);session.update(group);qinverse=“true”,由Group的反向段User负责维护关联关系。User user = new User(“Jak”);user .setGroup(adminGroup);session.save(user);手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Hibernate查询概述:概述:数据查询与检索是Hibernate中的一个亮点。相对其他ORM实

111、现而言,Hibernate提供了灵活多样的查询机制。q标准化对象查询标准化对象查询(CriteriaQuery):以对象的方式进行查询,将查询语句封装为对象操作。优点:可读性好,符合Java 程序员的编码习惯。缺点:不够成熟,不支持投影(projection)或统计函数(aggregation)qHibernate语言查询(Hibernate Query Language,HQL):它是完全面向对象的查询语句,查询功能非常强大,具备多态、关联等特性 。Hibernate官方推荐使用HQL进行查询。qNativeSQLQueries(原生原生SQL查询)查询):直接使用标准SQL语言或跟特定数据

112、库相关的SQL进行查询。手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂例子:标准化对象查询(Criteria Query)简单例子:简单例子:查询用户名以“J”开头的所有用户。Criteria criteria = session.createCriteria(User.class); criteria.add(Expression.like(name,J%); List users = criteria.list();手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Hibernate语言查询(Hibernate Query

113、 Language,HQL)HQL用面向对象的方式生成用面向对象的方式生成SQLq以类和属性来代替表和数据列q支持多态q支持各种关联q减少了SQL的冗余HQL支持所有的关系数据库操作支持所有的关系数据库操作q连接(joins,包括Inner/outer/full joins),笛卡尔积(cartesian products)q投影(projection)q聚合(Aggregation,max, avg)和分组(group)q排序(Ordering)q子查询(Subqueries)qSQL函数(SQL function calls)手把手教程版权所有:尚学堂科技Struts+Hibernate+

114、Spring尚学堂例子: Hibernate语言查询(Hibernate Query Language,HQL)简单例子:简单例子:查询用户名以“J”开头的所有用户。Query query = session.createQuery(from User user where user.name like J%); List users = query.list();复杂例子:复杂例子:从User和Group中查找属于“admin”组的所有用户。Query query = session.createQuery(“from User user where user.group.name=admi

115、n”);如果用传统的SQL则查询语句如下:select user.userId as userId, user.name as name, user.groupId as groupId, user.idCardId as idCardId from TBL_USER user, TBL_GROUP group where (group.groupName=admin and user.groupId=group.groupId)手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Hibernate性能优化策略Hibernate高级话题:性能优化策略的配置与使用本

116、节包括如下主题:一级缓存二级缓存查询缓存批量抓取批量更新手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂一级缓存即session级别的缓存,随着session的关闭而消失,load/iterator操作,会从一级缓存中查找数据,如果找不到,再到数据库里面查找。Query.list操作,如果没有配置查询缓存,将直接从数据库中获取数据。手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂二级缓存(1)首先要打开二级缓存首先要打开二级缓存默认情况下,二级缓存是打开的,可以通过配置:false来关闭二级缓存。使用:org.hibernat

117、e.cache.EhCacheProvider来指定缓存提供商。即有谁来提供缓存的功能。Ehcache配置可以看例子,里面有非常清楚的说明。 手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂二级缓存(2)要在映射文件中指定缓存策略要在映射文件中指定缓存策略在hbm文件中加入:cache usage=read-only/这个缓存策略的配置一定要加上,否则便不会有缓存的作用,Load/list/iterator等操作的结果将都不会缓存。注意,注意,在hbm的class配置中添加配置,表示的是类缓存,如果把这个配置删除,将只缓存ID,不缓存整个对象。(这个时候对li

118、st操作,也可能有n+1查询问题)当然,也可以选择在标签里面嵌套定义这样的标签:来代替直接将定义嵌套入标签的内部。缓存策略缓存有几种形式,可以在映射文件中配置:read-only(只读,适用于很少变更的静态数据/历史数据),nonstrict-read-write(不严格读写缓存,如果基本不会发生有两个事务同时修改一个数据的时候,比read-write的性能要好),read-write(比较普遍的形式,效率一般),transactional(JTA中,且支持的缓存产品较少)手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂二级缓存(3)Session如何与二级缓

119、存交互?如何与二级缓存交互?Session接口通过CacheMode来定制与二级缓存之间的交互方法手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂查询缓存默认情况下关闭,需要打开。查询缓存,对list/iterator这样的操作会起作用。可以使用:true来打开查询缓存,默认的情况下是关闭的。所谓查询缓存,即让hibernate缓存list、iterator、createQuery等方法的查询结果集。如果没有打开查询缓存,hibernate将只缓存load方法获得的单个持久化对象。在打开了查询缓存之后,需要注意,调用query.list()操作之前,必须显式调

120、用query.setCachable(true)来标识某个查询使用缓存。手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂单端代理的批量抓取单端代理的批量抓取实例A引用实例B,B如果是代理的话(比如多对一关联中):如果遍历A的查询结果集(假设有10条记录),在遍历A的时候,访问B变量,将会导致n次查询语句的发出!这个时候,如果在B一端的class上配置batch-size,Hibernate将会减少SQL语句的数量。Hibernate可以充分有效的使用批量抓取,也就是说,如果仅一个访问代理(或集合),那么Hibernate将不载入其他未实例化的代理。 批量抓取是

121、延迟查询抓取的优化方案,你可以在两种批量抓取方案之间进行选择:在类级别和集合级别。 类/实体级别的批量抓取很容易理解。假设你在运行时将需要面对下面的问题:你在一个Session中载入了25个 Cat实例,每个Cat实例都拥有一个引用成员owner, 其指向Person,而Person类是代理,同时lazy=true。 如果你必须遍历整个cats集合,对每个元素调用getOwner()方法,Hibernate将会默认的执行25次SELECT查询, 得到其owner的代理对象。这时,你可以通过在映射文件的Person属性,显式声明batch-size,改变其行为: .随之,Hibernate将只需

122、要执行三次查询,分别为10、10、 5。 手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂集合代理的批量抓取集合代理的批量抓取你也可以在集合级别定义批量抓取。例如,如果每个Person都拥有一个延迟载入的Cats集合, 现在,Sesssion中载入了10个person对象,遍历person集合将会引起10次SELECT查询, 每次查询都会调用getCats()方法。如果你在Person的映射定义部分,允许对cats批量抓取, 那么,Hibernate将可以预先抓取整个集合。请看例子: . 如果整个的batch-size是3,那么Hibernate将会分四次执行

123、SELECT查询, 按照3、3、3、1的大小分别载入数据。手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂批量更新批量更新Jdbcfetchsize:每次取多少条数据,需要JDBC和底层数据库的支持。不会一次性把全部数据读入内存,而是按照一定的数量来批量读取相应的数据。Fetch size建议值是50hibernate.jdbc.fetch_size Jdbcbatchsize批量更新建议取值30hibernate.jdbc.batch_size 手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Hibernate最佳实践(Be

124、st Practices)1、使用Configuration装载映射文件时,不要使用绝对路径装载。最好的方式是通过getResourceAsStream()装载映射文件,这样Hibernate会从classpath中寻找已配置的映射文件。2、SessionFactory的创建非常消耗资源,整个应用一般只要一个SessionFactory就够了,只有多个数据库的时候才会使用多个SessionFactory。3、在整个应用中,Session和事务应该能够统一管理。(Spring为Hibernate提供了非常好的支持)4、将所有的集合属性配置设置为懒加载(lazy=”true”)。在hibernat

125、e2.x版本中,lazy默认值是“false”,但hibernate3.x已经将lazy的默认改为“true”了。手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Hibernate最佳实践(Best Practices)5、在定义关联关系时,集合首选Set,如果集合中的实体存在重复,则选择List(在定义配置文件时,可以将List定义为bag),数组的性能最差。6、在一对多的双向关联中,一般将集合的inverse属性设置为true,让集合的对方维护关联关系。例如:Group-User,由User来维护Group和User的关联关系。7、HQL子句本身大小写无关

126、,但是其中出现的类名和属性名必须注意大小写区分。8、在非分布式架构中,不需要使用DTO来向上层传输数据。直接使用POJO的Entity就可以了。9、如果要精通Hibernate,熟练掌握关系数据库理论和SQL是前提条件。手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Hibernate资源q官方网站:http:/www.hibernate.orgq国内网站:http:/qJava新视线论坛:http:/forum.hibernate.orgqHibernate 中文开发指南作者夏昕(http:/ 曹晓钢 唐勇(http:/www.china- Hibernat

127、e in Action 作 者 : Christian Bauer and Gavin King(http:/ A Developers Notebook作者:James Elliott 尚学堂 手把手教程授课:王勇授课:王勇版权所有:尚学堂科技Struts+Hibernate+SpringSpring轻量级容器架构手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Spring最常用的特性利用Spring来创建对象(JavaBean工厂)利用Spring构建业务逻辑层管理依赖关系适应需求变更利用Spring创建数据访问对象(DAO)利用Spring进行事务处理手

128、把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Spring的安装下载并解压http:/www.springframework.org/将相应的jar包加入类路径spring.jar配置SpringApplicationContext.xml体验Spring的最基本特性BeanFactory手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂创建Sample类及其Spring配置文件Sample.javapublic class Sample public int compute(int i,int j)return i + j;A

129、pplicationContext.xml手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂创建测试程序ClientTest.javapublic class ClientTest /* * param args */public static void main(String args) /获取BeanFactoryBeanFactory beanFactory = new ClassPathXmlApplicationContext(applicationContext.xml);/从容器中获取Sample对象Sample sample = (Sample)

130、beanFactory.getBean(sample);/调用Sample对象的方法int result = pute(3,4);System.out.println(result);手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂针对接口编程的原则重要的设计原则:针对接口编程,而不要针对实现编程重要的设计原则:针对接口编程,而不要针对实现编程重要的设计原则:针对接口编程,而不要针对实现编程重要的设计原则:针对接口编程,而不要针对实现编程思考:思考:思考:思考:computecompute方法功能需求变更方法功能需求变更方法功能需求变更方法功能需求变更 ?针对

131、接口编程的目的:针对接口编程的目的:针对接口编程的目的:针对接口编程的目的:降低耦合度,增强应用程序的稳定性降低耦合度,增强应用程序的稳定性降低耦合度,增强应用程序的稳定性降低耦合度,增强应用程序的稳定性让Sample类变成接口手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Sample接口及其实现接口定义public interface Samplepublic int compute(int i,int j);接口的实现一public class SampleImpl1 implements Sample public int compute(int i,

132、int j)return i + j;接口的实现二public class SampleImpl2 implements Sample public int compute(int i,int j)return i * j;ClientTest.java无需改动只需改动只需改动ApplicationContext.xmlApplicationContext.xml的配置,即可实现实际功能的切的配置,即可实现实际功能的切换换手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂第二个例子我们已经确定,基于接口编程,是OOD中的重要原则一个层次的实现代码,不应该依赖于另

133、外一个层次的实现代码下面是第二个例子:BookLister,这个例子包括如下几个类:实体类:Book,有名称、作者等属性BookFinder接口,定义了findAll()方法BookLister接口,定义了findBooks(String name)方法,以书名作为参数,并返回Book数组作为查找的结果以及一个测试客户端BookClient,调用BookLister,来获取所需要的数据手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Book.javapublic class Book private String name;private String aut

134、hor; /* * return Returns the author. */public String getAuthor() return author;/* * param author The author to set. */public void setAuthor(String author) this.author = author;/other getters/setters手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂BookFinderBookFinder接口public interface BookFinder public List

135、 findAll();SimpleBookFinderImplpublic class SimpleBookFinderImpl implements BookFinder/* * see com.bjsxt.spring.BookFinder#findAll() */public List findAll() List books = new ArrayList();for(int i=0; i20; i+)Book book = new Book();book.setName(book+i);book.setAuthor(author+i);books.add(book);return b

136、ooks;手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂BookListerBookList接口public interface BookListerpublic Book findBooks(String name);BookListerImpl实现代码public class BookListerImpl implements BookLister BookFinder finder; public BookListerImpl() finder = new SimpleBookFinderImpl();public Book findBooks(Str

137、ing name)List books = finder.findAll();for (Iterator iter = books.iterator(); iter.hasNext();) Book book = (Book) iter.next();if(!book.getName().equals(name)iter.remove();return (Book)books.toArray(new Bookbooks.size();手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Spring配置:ApplicationContext.xml及客户调用代码Sp

138、ring配置:客户调用代码public static void main(String args) BeanFactory beanFactory = new ClassPathXmlApplicationContext(applicationContext.xml);BookLister bl = (BookLister)beanFactory.getBean(bookLister);Book books = bl.findBooks(book3);if(books != null)for(int i=0; ibooks.length; i+)System.out.println(书+boo

139、ksi.getName()+的作者是:+booksi.getAuthor();手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂同样的问题:需求变更?现在,我们需要的不再是一个简单的BookFinder,我们需要的是一个能从本地文件系统中读取文件,并分析其中所包含的Book的内容,将其结果返回因为我们遵守了面向接口编程,所以,我们只需要提供第二个实现即可手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂FileBookFinderImpl 从文件系统读取Book的信息public class FileBookFinderImpl

140、implements BookFinder public List findAll() String file = “d:/test.txt”;List books = new ArrayList();try BufferedReader in = new BufferedReader(new FileReader(file);String line = null;while( (line = in.readLine() != null)String sp = line.split(;);if(sp.length = 2) Book book = new Book();book.setName

141、(sp0);book.setAuthor(sp1);books.add(book); catch (FileNotFoundException e) e.printStackTrace(); catch (IOException e) e.printStackTrace();return books;手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂现在需要做什么?我们的客户代码调用BookListerBookLister如何调用BookFinder?下面是以前初始化BookFinder的代码:public BookListerImpl() finder = n

142、ew SimpleBookFinderImpl();现在,我们必须改动这段代码:public BookListerImpl() finder = new FileBookFinderImpl();看出问题来了吗?手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂严重违反面向对象的设计原则BookListerBookLister接口的实现类严重依赖于接口的实现类严重依赖于接口的实现类严重依赖于接口的实现类严重依赖于BookFinderBookFinder接口的实现类,这就是接口的实现类,这就是接口的实现类,这就是接口的实现类,这就是问题所在!问题所在!问题所在!问

143、题所在!我们必须在BookLister的实现类和BookFinder的实现类之间进行解偶,即解除它们之间的实现类耦合关系(依赖!)我们需实现以下目标:BookLister的实现类BookListerImpl不应该依赖于特定的BookFinder接口的实现类(比如SimpleBookFinderImpl或FileBookFinderImpl)BookLister的实现类,应该仅仅依赖于BookFinder接口,它不应该跟具体的功能需求实现相关(如,是否是从文件读取Book的信息)总之,我们不应该让BookLister和BookFinder的实现类之间互相耦合!手把手教程版权所有:尚学堂科技Str

144、uts+Hibernate+Spring尚学堂Spring让一切变得轻而易举在BookListerImpl中定义一个setter方法public void setFinder(BookFinder finder) this.finder = finder;把BookListerImpl构造器中的new语句注释掉public BookListerImpl() /finder = new FileBookFinderImpl();让Spring去关心那些烦人的依赖关系吧!手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Spring配置文件:ApplicationC

145、ontext.xml添加BookFinder定义修改BookLister定义的配置以上配置,即指定了BookListerImpl和FileBookFinderImpl之间的依赖关系,这种依赖关系,被放到了配置文件中,这样,只要需求有变更,只需要修改这种依赖关系即可,java代码本身不用任何变更手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂热门词汇:IOC/DI控制反转(Inversion of Control,IoC)与依赖注入(Dependency Injection)由容器来管理对象之间的依赖关系(而不是对象本身来管理),就叫“控制反转”或“依赖注入”以

146、上代码,已清楚阐述IOC/DI出现的原因,以及IOC的基本原理Spring框架的基本思想就是IOC/DISpring就是一个IOC容器IOC与DI,说的是一回事,但DI这个名词更能表达这种设计模式的思想手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂依赖注入的类型构造器注入通过类的构造方法注入依赖关系设值方法注入通过类的setter方法注入依赖关系第三种:接口注入(不常用)定义一个注入接口,在需要注入的类中实现此接口,由于这种方法具有侵入性,所以不常用手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Spring的依赖注入Spr

147、ing是一个Java Bean容器,它维护着一系列Java Bean的示例通过Spring所提供的依赖注入的方法,我们可以管理这些Java Bean之间的引用关系手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂更多的例子我们可以通过构造器来将实现依赖进行注入示例我们可以通过setter方法,实现类的配置将易于变动的部分转移到配置文件中示例:给FileBookListerImpl加上path和name的配置手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂通过setter方法注入依赖(属性)类代码示例Spring配置示例手把手教程

148、版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Spring架构手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂DAO设计模式什么是DAO?Data Access Object(数据访问对象)最重要的核心J2EE模式之一为什么需要DAO?屏蔽业务逻辑对数据持久化的依赖一定需要DAO吗?如果业务逻辑比较简单(比如只有简单的数据存取操作),完全可以取消DAO是否需要DAO,完全取决于业务需求,没有固定的说法手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Spring与Hibernate的集成从例子入手安装H

149、ibernate创建User实体类创建User映射文件创建Hibernate配置文件创建DAO对象创建Manager对象SessionFactory配置声明式事务配置DAO定义Manager定义手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂创建可以支持Hibernate的DAO对象HibernateDaoSupport这是Spring提供的集成Hibernate的基类,所有的DAO,均需要继承它从这个类中,可以获取Hibernate的各种核心接口,如Session、SessionFactory等HibernateTemplateHibernateTempla

150、te是Spring封装的Hibernate操作接口,类似于Session接口可以调用HibernateDaoSupport提供的getHibernateTemplate()方法获取HibernateTemplate对象手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂创建Manager对象Manager对象没有任何特殊之处,它就是普通的接口和实现类手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂在Spring中声明SessionFactory一种简单的配置方式,即指定Hibernate配置文件的路径所在即可 classpath:

151、hibernate.cfg.xml 手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂在Spring中配置事务管理大多数的应用程序,事务管理被分配到业务逻辑方法上,即每个业务逻辑大多数的应用程序,事务管理被分配到业务逻辑方法上,即每个业务逻辑大多数的应用程序,事务管理被分配到业务逻辑方法上,即每个业务逻辑大多数的应用程序,事务管理被分配到业务逻辑方法上,即每个业务逻辑方法是一个事务方法是一个事务方法是一个事务方法是一个事务在Spring中,所有的业务逻辑对象,均是普通的POJOSpring最强大的功能在于,它可以在普通的POJO上面实现声明式的事务管理(它使用A

152、OP来完成这样的任务)可插入的事务策略步骤如下:定义一个事务管理器定义一个事务代理基类手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂事务管理器的定义手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂事务管理的AOP配置手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂正确的配置DAODao的配置示例必须注入必须注入必须注入必须注入sessionFactorysessionFactory的定义的定义的定义的定义手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂简单配

153、置Manager手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂好了,让我们来测试一下编写测试代码测试事务特性手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Spring与Struts的集成修改web.xml让Tomcat自动加载Spring,所以需要增加下面的配置 contextConfigLocation /WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml org.springframework.web.context.ContextL

154、oaderListener 手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂修改Struts的Action类我们在原来的Action配置中,type属性,直接指向我们的Action类(即Action类的全路径)现在我们需要将这些Action类的创建,交给Spring去完成所以,我们需要修改两个地方:Action配置中type属性,由原来的Action类,改为:org.springframework.web.struts.DelegatingActionProxy在Spring配置文件中,添加对Action类的定义,如:手把手教程版权所有:尚学堂科技Struts

155、+Hibernate+Spring尚学堂建立测试J2EE项目建立一个web项目在web项目中安装Struts安装Spring配置web.xml配置Action配置Spring手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂Struts+Hibernate+SpringHibernate与Spring的集成Struts与Spring的集成Struts+Hibernate+Spring的集成没有更多的东西,前面已经分别将它们集成起来了注意使用OpenSessionInView模式,这是使用Hibernate的web项目最需要注意的一个问题,Spring为此提供了专

156、门的解决方案手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂OpenSessionInViewFilter这是为了避免Hibernate的懒加载异常而创建的解决方案它是一个过滤器,能够让Session在请求解释完成之后再关闭(所以才能够避免懒加载异常)配置方式是,在web.xml中定义过滤器即可: hibernateFilter org.springframework.orm.hibernate3.support.OpenSessionInViewFilter hibernateFilter /* 手把手教程版权所有:尚学堂科技Struts+Hibernate

157、+Spring尚学堂CharacterEncodingFilter如何提交中文字符?配置web.xml了,Spring提供了专门的针对Encoding的过滤器配置方法如下: Spring character encoding filter org.springframework.web.filter.CharacterEncodingFilter encoding GBK Spring character encoding filter /* 手把手教程版权所有:尚学堂科技Struts+Hibernate+Spring尚学堂更多的资料Spring官方网站http:/www.springframework.orgSpring中文网http:/ (有中文参考手册下载)结束语结束语谢谢大家聆听!谢谢大家聆听!189

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号