struts+hibernate+spring


尚学堂 手把手教程 授课:王勇 版权所有:尚学堂科技 Struts+Hibernate+Spring Struts+Hibernate+Spring Web开发流行架构 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 课程总体目标  我们的目标是:能够熟练运用当前流行的java开源框架:Struts、 Hibernate以及Spring来构建灵活、易于扩展的多层Web应用程序。 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 多层架构概述  C/S:以数据库为中心  B/S:多层架构才是真正的目的  B/S多层架构将显示、业务运算、数据库等功能完全分离,杜绝彼此的耦 合与影响,从而实现松耦合和良好的可维护性。  呈现层(UI Layer/Presentation Layer)  struts  业务逻辑层(Business Layer)  spring  持久化层(Persistence Layer)  hibernate 尚学堂 手把手教程 授课:王勇 版权所有:尚学堂科技 Struts+Hibernate+Spring Struts 开源MVC框架 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Struts课程目标  深入理解MVC模式  掌握Struts体系架构  掌握Struts开发流程  熟练掌握Struts的配置方法 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 从Servlet说开去  什么是Servlet?  如何编写Servlet?  如何映射Servlet?  相对路径与绝对路径的基本概念  如何基于Servlet编程?  JavaBeans  JavaBean是一种java类  JavaBean必须是具体的和公共的,并且具备无参构造器  JavaBean通过提供符合一致性设计模式的公共方法将内部域暴露称为属性  JavaBean提供两种方法来访问Bean的内部状态:  访问器(getters)用来读JavaBean状态 – 以小写get前缀开始,后跟属性名,属性 名的第一个字母必须大写,返回值必须匹配相应修改器的方法的参数;如果访问 器返回boolean值,则使用is前缀开始,后跟属性名,属性名第一个字母必须大写。  修改器(setters)用来改变JavaBean状态 – 以小写set前缀开始,后跟属性名,属 性名的第一个字母必须大写,修改器的返回值通常为void 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Struts是什么? Struts的目标是提供一个开发Web应用的开源框架。Struts鼓励基于M2模式(即MVC 设计模式)来开发程序。 - Model - View - Controller 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Model1与Model2设计模式简介  以JSP为中心的开发模型,称为Model1(JSP+JAVABEAN)  业务逻辑与表示逻辑混和,不利维护与重用  HTML中嵌入了大量的JAVA代码  验证、流程控制、更新程序的状态全部在JSP中完成  基于MVC模式的框架  MVC将问题进行分解  模型包含应用程序的核心功能。模型封装了应用程序的状态。它对视 图或控制器一无所知。  视图提供模型的表示。它是应用程序的 外观。视图可以访问模型的 读方法,但不能访问写方法。此外,它对控制器一无所知。  控制器对用户的输入作出反应。它创建并设置模型。 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Model2 Browser Controller Model View Http Request (Get, Post) 调用 Forward 获取Http Response 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Struts框架概览 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Struts框架概览  浏览器  web容器将对来自HTTP的每个请求创建一个request对象,并用一个 response对象作出响应  控制器  控制器接收来自浏览器的请求,在struts中,是由一个servlet来充当 控制器的角色,struts-config.xml文件配置控制器  模型  在struts中,由Action类充当业务逻辑的包装器,ActionForm是程序 的状态  视图  JSP文件 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Struts框架组件  ActionServlet类控制导航流  ActionServlet根据URI来决定哪个Action类 被用于处理请求,Action可以校验输入,并访 问业务层以便从数据库检索信息  Action需要知道页面提交了哪些内容,所以 由ActionServlet根据请求URI来决定将请求 参数绑定到哪个ActionForm中,并传入Action  Action在完成业务逻辑后,返回一个ActionForward 对象,ActionServlet根据ActionForward对象中的路径来调用页面完成响应  Struts将这些信息绑定在一个ActionMapping对象中,一个ActionMapping对应一个请求URI,当 请求路径到达的时候,ActionServlet就会查询ActionMapping对象,ActionMapping对象将告 诉ActionServlet哪个Action类会被调用、哪个ActionForm类被用于传递页面数据以及哪些 ActionForward将被用于转向  有关Action、ActionForm、ActionForward等信息,Struts通过一个配置文件:struts- config.xml文件来定义。 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Struts1.X 和Struts2.X  Struts1.X 与Struts2.X 的差异较大  Struts1.X 应用更加广泛  Struts2.X 实际上是另外一个框架Webwork发展而来的  后续课程将会有对webwork/Struts2.X的介绍以及实例操作 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 快速开始一个Struts项目  第一个项目,实现用户登录操作  用户将看到一个登录页面,要求用户输入用户名以及密码  如果用户名以及密码都是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映射配置 (转下一页) 手把手教程 版权所有:尚学堂科技 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.java  struts-config.xml文件  三个页面  登录页面 – login.jsp  登录成功提示页面 – login_success.jsp  登录失败提示页面 – login_error.jsp  就这些!没别的了!! 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 创建LoginActionForm.java  ActionForm是一个JavaBean,需继承 org.apache.struts.action.ActionForm类, 它捕获通过HTTP请求传送的参数  ActionForm针对每个HTML表单中的字段 具有一个对应的属性  ActionServlet匹配请求中的参数和 ActionForm中的属性,并调用ActionForm 中的setter方法,将参数传入ActionForm  我们的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 LoginActionForm 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 username. */ public String getUsername() { return username; } /** * @param username The username to set. */ public void setUsername(String username) { this.username = username; } } 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 创建LoginAction.java  Action是一个Java类,需继承 org.apache.struts.action.Action类  ActionServlet将会组装ActionForm,并将它传 递给Action  Action 通常负责: 输入校验 调用业务逻辑类执行业务逻辑操作 决定返回哪个ActionForward  我们的LoginAction做了如下事情,这些是一个 Action通常都会做的最典型的事情: 将输入的ActionForm强制转换为 LoginActionForm 从LoginActionForm对象中获取用户名以及密 码的数据信息 执行用户名及密码的逻辑判断操作(在通常 的情况下,要将这些业务逻辑交给专门的类去 处理,这里这样做是为了演示的需要) 根据业务逻辑执行的结果,决定返回哪个 ActionForward,我们在这里使用success这个 标识来表示登录成功页面,用error标识来表示 登录失败页面 public class LoginAction extends Action { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { //将ActionForm强制转换为LoginActionForm LoginActionForm loginForm = (LoginActionForm)form; //从LoginActionForm中提取从页面表单传递过来的参数 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 尚学堂 创建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-config.xml文件中,在标签的内部,添加如下 配置: 标签内部可以包含多个标签  标签必须指定name和type属性  name属性是给此ActionForm一个标识名称  type属性指定了此ActionForm是哪个类,必须是全路径的类名 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 添加Action配置,配置LoginAction  我们在struts-config.xml文件中,紧接着 标签的下面,添加对 LoginAction的配置  标签可以配置的重要属性包括: path-从页面上通过一个什么样的URL 路径来访问Action(不包含.do) type – 访问这个URL的时候,调用哪 个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来处理这个表单的请求  添加输入域username,这个 username的表单字段,必须跟 LoginActionForm中的属性一致  添加密码输入域password <%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%> 请登录
请输入用户名:
请输入密码:
手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 创建login_success.jsp和login_error.jsp  login_success.jsp <%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%> 登录成功 欢迎您,您已经成功登录!您创建的第一个 Struts应用程序已成功运行!!!  login_error.jsp <%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%> 登录失败 您的登录失败了,可能原因是用户名或密码不 正确,请返回重新输入 返回登录页面 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+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-Test/login.do,Tomcat将会根据web.xml的配 置,将这个请求发送给相应的Servlet,在我们的应用中,Tomcat将会把 这个请求发送给org.apache.struts.action.ActionServlet这个类(请参看 web.xml的配置)  然后ActionServlet根据struts-config.xml的配置信息,调用LoginAction对 象去处理这个请求,在此之前,它会将页面表单的请求数据封装到 LoginActionForm对象中,并传递给LoginAction  LoginAction返回一个ActionForward对象,包含了将要转向的路径信息  ActionServlet根据这个ActionForward对象所包含的路径信息,调用相应 的页面去执行响应  流程图请参考下一页 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 LoginAction应用程序的流程图 login.jsp ActionServlet login_success.jsp login_error.jsp LoginActionForm.class LoginAction.class struts-cofig.xml 读取配置文件 提交表单 响应response 响应response 创建对象并调用 创建对象并设值 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Struts项目架构图 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Struts工作流程图 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Struts与MVC  视图(View)  在使用Struts框架的web应用程序中,JSP以及相关的技术(如Taglib) 等共同组成视图层,这一层的主要职责是显示用户界面。Struts提供 了很多机制让我们能更加轻松地创建视图  控制器(Controller)  Struts中,ActionServlet是控制器层组件  模型(Model)  模型包括:系统的内部状态以及改变系统状态的动作  Struts中的Action和ActionForm是模型的一部分  Struts建议把‖做什么‖(Action)和‖如何做‖(业务逻辑)相分离 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 创建业务逻辑处理类(Model)  使用单例模式(Singleton)来创建 业务逻辑处理类  创建UserManager业务逻辑处理 类  创建validate方法  创建UserNotFoundException  创建PasswordErrorException package com.bjsxt.strutstest; public class UserManager { private static UserManager userManager; private UserManager(){ } public static synchronized UserManager getInstance(){ if(userManager == null){ userManager = new UserManager(); } return userManager; } public void validate(String username,String password) throws UserNotFoundException,PasswordErrorException { if(!"admin".equals(username)){ throw new UserNotFoundException(); } if(!"admin".equals(password)){ throw new PasswordErrorException(); } } } 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Action中如何调用业务逻辑处理类?  我们看下面的代码: 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+Hibernate+Spring 尚学堂 页面之间数据的传递  如何将数据从Action中传递到下一个JSP页面?  一般使用request.setAttribute方法:  在Action中,使用request.setAttribute(String name,Object data)方法 往request中设置参数  在JSP中,使用request.getAttribute(String name)来获取相应的参数  在原来LoginAction的基础上编写相应的代码,测试页面数据传递  传递登录成功者的帐号信息到成功页面,并显示 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 进一步理解Struts控制流 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 细节:所有的页面请求由容器接收  Struts的核心组件是ActionServlet,像其它所有Servlet一样,它是生存在 容器中的,比如Tomcat、WebLogic等,当容器启动的时候,它会读取 web.xml文件(部署描述符),告诉容器它会装入哪些Servlet  一个标准的Servlet是通过servlet-mapping来设定,哪些请求,将会被提 交到哪些servlet中  Struts的servlet-mapping配置一般是: action *.do  这样配置的意思是:任何以.do结尾的URL请求,都会被发送到 ActionServlet进行处理 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 小结  MVC基本结构  Struts的主要组成部分  如何编写ActionForm  如何编写Action  如何在配置文件中定义映射URL、Action以及ActionForm  如何获取从页面传递到Action的数据  如何将数据从Action传递到下一个页面  如何将业务逻辑与表示层分离  需牢记原则:不要在Action中进行业务逻辑的处理,业务逻辑应交给 专门的Model层去做  在业务逻辑层抛出异常,并在Action中捕捉和处理 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Struts Taglib  易于使用,能代替直接在页面上写JAVA脚本  便于重用  用Struts Taglib实现成功页面  在以后的开发中,将逐步介绍一些常用的Taglib 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 尝试简单的tag lib使用  在JSP文件的头部添加如下声明:  <%@ taglib prefix="bean" uri="http://struts.apache.org/tags-bean" %>  <%@ taglib prefix="logic" uri="http://struts.apache.org/tags-logic" %>  <%@ taglib prefix="html" uri="http://struts.apache.org/tags-html" %>  关于struts tag lib的说明,可以查看相关的参考文档  常用的struts tag lib  手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 JSTL  简介:SUN的标准Taglib库  JSP标准标签库(JSP Standard Tag Library,JSTL )  迭代和条件判断  数据管理格式化  XML 操作  数据库访问  函数标签库  表达式语言(EL)  EL隐式对象  存取器  运算符 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 在项目中使用JSTL  拷贝jstl.jar和standard.jar到WEB-INF/lib目录下  在JSP中添加伪指令 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>  常用JSTL标记  手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 进一步理解ActionForm  ActionForm的要求  必须扩展自org.apache.struts.action.ActionForm  如果要获取表单的值,必须定义一个public属性  如果要求在将ActionForm传递到Action之前进行校验,必须实现 validate方法  如果想要在组装前初始化属性,必须实现reset方法  DynaActionForm  举例说明DynaActionForm的配置  DynaActionForm的使用 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 ActionForm作为表单字段收集器  通过HTTP提交表单数据  通过HTTP上传文件  通过例子演示文件上传的简易方法  通过HTTP提交空字段  修改原来的JSP文件,提交空字段 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 ActionForm作为类型转换器  所有从表单提交到后台的数据均为字符串类型  如何利用ActionForm自动转换int数据类型  举例说明  如何利用ActionForm自动转换boolean数据类型  举例说明  如何利用ActionForm自动转换Date类型  定义Converter  注册Converter  举例说明  如何利用ActionForm自动转换Double类型  举例说明 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 ActionForm作为传输对象  ActionForm 可以被其它bean或者过程作为数据载体。  Transfer 对象 (也称为值对象(value object) )用来通过发送粗糙—规整 的数据视图来交换精细规整的数据。  ActionForm 的各个属性都必须是可变的。  提示:  使用粗糙—规整 ActionForm来减小类维护。  应用中的表单一般共享属性  创建一个基本的 ActionForm,具有表单需要的所有属性 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 ActionForward  ActionForward能做什么?  在Action中,经常问的问题是:“OK,操作成功了,然后呢?”  ActionForward会回传给ActionServlet  ActionForward中的路径,可以是一个带参数的URI  ActionForward的属性  name  path  redirect  className  转发(forward)与重定向(redirect)  全局ActionForward与局部ActionForward 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 动态创建ActionForward  将ActionForward定义在一个Struts 配置文件中是个好的选择  但也可以在Action中动态创建ActionForward,而不需要在配置文件中指 定  如下所示:  ActionForward forward = new ActionForward("/do/itemEdit?action=edit");  举例说明 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 ActionMapping  理解ActionMapping  path  forward  type  name  scope  validate  input  parameter  unknow ActionMapping 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Scope属性  在Action映射配置中,Scope属性可以取值为:request或session  Scope属性表示:Struts框架在将ActionForm对象(与目标Action匹配的 ActionForm)传送到Action之前,会将ActionForm对象保存的位置  如:scope=―request‖配置,将指示struts调用 request.setAttribute(―ActionForm名称”,ActionForm对象)方法,将 ActionForm对象保存到request。  其中,ActionForm名称与struts-config.xml配置中的ActionForm名称 一致,如:,其中 uploadForm就是其名称。  我们明白scope属性的意义之后,就可以利用struts的这些特性,来解决开 发过程中的某些常见问题 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 常见问题:如何在程序出现异常的时候返回录入界面重新录入  假设现在要在一个页面上输入用户的信息(可能会有十几个属性值需要输 入),用户不小心输入了一个重复的帐号,而帐号是不允许重复的,这个 时候,系统应该提示用户有关帐号重复的信息,同时让用户重新选择一个 帐号。  这种情况下,我们需要返回用户录入界面,让用户修改帐号字段。  现在的问题是:如何在返回这个录入界面的时候,将用户输入的其它信息 保持住? 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 搞定Action对象  如果应用需要保存一个记录到数据库中,典型的过程可能是  ActionForward提供一个链接到输入页面  ActionForm捕获输入  ActionMapping配置Action  Action将输入送到数据库中(通常会将这一步操作委托给业务逻辑类 去实现)  J2EE是一个多线程的环境,服务器针对每个请求启动一个线程来处理。 所以有可能会有多个线程同时访问一个Servlet实例的情况  在Struts里面也是一样的,有可能会有多个线程同时访问一个Action实 例的情况  所以必须保证Action类中的方法具有“可重入性”,即不能在Action的 方法里改变实例变量的值 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Action的主要职责  校验输入数据  调用业务逻辑方法  检测处理异常  根据逻辑进行转向操作 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 I18N问题  什么是I18N问题?  在英文中, 国际化(Internationalization)被缩写为I18N, 即只取首 尾两个字母, 中间字母为18个  问题在哪里?  页面字符串硬编码  异常消息的硬编码  提示信息的硬编码 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Java如何支持I18N?  一个简单的例子  不支持I18N的例子 – 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的编码过程总结  1、创建属性文件(可能要用native2ascii工具转换)  2、定义Locale对象  3、创建一个ResourceBundle对象  ResourceBundle对象用于分离跟本地相关的数据  如果找不到相应语言或国家代码的属性文件,将使用默认的属性文件(即没 有标识语言和国家代码的属性文件:MessagesBundle.properties)  其创建方式如下: message = ResourceBundle.getBundle("MessagesBundle", currentLocale);  第一个参数,表示要从哪些资源属性文件中 (MessagesBundle_XX.properties)获取数据  第二个参数,是一个Locale对象,表示要选择哪个资源属性文件  4、从ResourceBundle对象中获取数据 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Locale对象  我们通过指定一个语言代码和国家代码来创建一个Locale对象  国家代码是可选的  语言代码是小写字母;国家代码是大写字母  Locale.getDefault()可以获得系统当前的Locale  Java都支持哪些语言代码和国家代码?  DateFormat.getAvailableLocales()  语言代码标准:http://ftp.ics.uci.edu/pub/ietf/http/related/iso639.txt  国家代码标准:http://userpage.chemie.fu- berlin.de/diverse/doc/ISO_3166.html  与Locale相关的数据:  消息文本(带参数?)  日期(时间)  货币(数字)  等等。。。 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Struts如何支持I18N  1、需要在struts配置文件中指定资源属性文件的位置和名称,如  2、在相应的位置放置相应的文件  3、在JSP页面中使用来输出文本,以 避免硬编码  以登录页面的国际化作为例子讲解  创建相应的资源属性文件  用标签替换登录页面的硬编码文本  测试(更改网页显示语言,以便测试不同的版本) 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 关于message-resources 配置中parameter的值  parameter的值,可以指定资源文件的位置和名称  举例:   表示在类路径根目录(WEB-INF/classes目录)下有 MessageResources_XX_XX.properties文件(注意:国家代码可以 省略,跟java中对资源属性文件的处理一样)   表示在类路径根目录下,有一个resources目录,在这个resources目 录中存放着所有的application_XX_XX.properties资源属性文件 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 如何用程序切换网页显示的语言  struts利用在session中存放一个Locale对象来达到设置当前语言的目的  默认的情况下,struts根据网页向后台提交时所包含的语言编码信息来提 供缺省的Locale对象,这就是我们为什么可以通过更改网页显示语言设置, 就能显示不同的语言文字的原因。  struts在session中存放的这个Locale对象,取名为: Globals.LOCALE_KEY 的值,Globals是struts框架提供的一个对象  利用这个原理,我们可以用编程的方式来手工切换整个应用系统的语言。  举例说明  ChangeLanguageAction 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Struts消息处理  为什么需要消息处理?  比如登录成功的提示  比如创建失败的提示  等等……总之,程序总是要通过界面来跟用户交互,所以,在交互的 过程中,就产生了众多的消息文本  struts提供了专门的处理机制,来将这些消息文本国际化,避免消息文本 的硬编码  消息处理,就是在Action和JSP之间传递的消息文本的处理(区别于JSP 页面硬编码文本的消息,JSP页面消息可以使用标签来 处理)  Struts交互消息,是通过ActionMessages等对象,以及相应的 标签来处理的 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 如何创建消息对象?  ActionMessages与ActionMessage对象  ActionMessages对象是ActionMessage对象的集合  一个ActionMessage对象,代表一个国际化消息文本(字符串)  如何创建ActionMessages对象?  ActionMessages messages = new ActionMessages();  如何创建ActionMessage对象?  ActionMessage msg = new ActionMessage(―key‖);  其构造方法带的参数,就是一个在资源属性文件中的key,所以,它 能表示一个国际化消息文本  如何将ActionMessage对象添加到ActionMessages对象中?  messages.add(―message_id‖,msg);  第一个参数(message_id)表示本ActionMessage对象在 ActionMessages对象中区别于其它ActionMessage对象的标识符 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 如何将消息对象从Action中传递到下一个页面(JSP)?  首先我们要决定的是,我们要传递的消息是普通消息还是错误消息?  普通消息:即普通的消息文本  错误消息:即提示错误的消息文本  本质上,这两种消息没有什么区别,都是消息文本,但是如果一个页面同时 需要显示普通的消息文本和错误消息文本的时候,就需要进行区分了,比如 不同类型的消息文本可能要用不同的样式来显示  通过一句简单的代码,将ActionMessages对象保存到HttpServletRequest对象中  保存普通消息:this.saveMessages(request,messages);  保存错误消息:this.saveErrors(request,messages);  这就是调用父类(Action)所提供的方法saveMessages()/saveErrors()来保 存消息对象  实际上,父类的saveMessages()方法,将消息对象保存在了request中,并 命名为Globals.MESSAGE_KEY  saveErrors()方法,将消息对象保存在了request中,并命名为 Globals.ERROR_KEY 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 如何在JSP中使用消息对象?  使用标签来显示消息  标签既可以显示普通消息,也可以显示错误消息  标签的重要属性:  name – 消息对象的名称,如果我们调用saveMessages/saveErrors方法来传 递消息,那么这个名字不需要标识(struts使用缺省的名称,即 Globals.MESSAGE_KEY 或Globals.ERROR_KEY )  id – (这是必需的属性)因为我们传递的是ActionMessages对象,而不是 ActionMessage对象,ActionMessages对象相当于一个集合,我们需要在 JSP上依次输出它所包含的消息,因此需要一个id标识一个变量来临时存放 其每条消息(与标签的id属性的意义是一样的)  property – 我们传递的ActionMessages对象,包含了多条消息文本,如果我 们只需要显示其中一条,则可以通过property属性来指定显示哪条消息  message – 可以取值为true或false,如果取值为true,将显示普通消息,如 果取值为false,将显示错误消息 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 标签  标签只显示错误消息  标签与标签类似,但无id属性  标签通过提供header/footer属性以及prefix/suffix属性来定制每条消 息的显示格式  header/footer – 定义整个错误消息显示之前(之后)要显示的内容,这些内 容也是在资源属性文件中定义的一些key值,默认的情况下,它们的取值分 别为:errors.header和errors.footer  prefix/suffix – 定义每条错误消息显示之前(之后)要显示的内容,这些内容 也是在资源属性文件中定义的一些key值,默认的情况下,它们的取值分别 为:errors.prefix和errors.suffix  举例如下: errors.header=
    errors.prefix=
  • errors.suffix=
  • errors.footer=
手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Struts的异常自动处理机制  编程式异常处理  即我们在Action中调用业务逻辑层对象的方法时,用try{ }catch的方 式来截获异常之后,手工对异常进行处理  我们以前的开发过程中,都是使用编程式的异常处理  在编程式异常处理的时候,我们可以使用struts的消息处理机制(前 面所讲的内容)来对这些异常信息进行处理  自动异常处理机制  即在Action中不捕捉异常,而是将异常抛出给struts框架处理  我们需要在配置文件中指示struts如何处理这些被抛出的异常  使用元素来定义自动异常处理 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 元素的配置及使用  元素的配置,指示了struts如何处理异常的方式  在通常的情况下,我们得到异常以后,需要将页面导航到一个错误提示的 页面,提示错误信息  元素配置的关键属性是:  key – 即这个异常所对应的错误提示消息文本的key,这个key的值, 需要在资源属性文件中进行定义  type – 即定义需要处理哪种类型的Exception  path – 定义一旦出现异常,需要转向哪个页面来进行提示,如果不定 义path属性,默认情况下,将使用Action配置中的input属性的值来作 为转向的页面  如何显示错误消息?  在JSP页面中,使用标签,即可将其异常对应的错误消 息文本进行显示(测试login.jsp页面) 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 标准Action  Struts框架缺省提供了一些Action,来完成一些常见的功能  ForwardAction - ForwardAction仅仅简单的转发控制到其他资源  为什么需要ForwardAction?  目的是发出一个RequestDispatcher 转发  ForwardAction 的绝大多数使用是作为Action的占位符  ForwardAction 创建一个请求分派器,并根据ActionMapping提供的上下文相 关的URI转发控制  许多 Struts 开发人员避免从一个页面直接连接到其他地方而是通过Action 或 者 ActionForward来传递控制。这保证了工作流在Struts 配置的控制之下, 在这里可以进行集中管理。  然而,许多页面并不需要特殊的预处理(至少还不需要)。如果为这些页面创 建ActionMapping ,你可以使用ForwardAction ,来仅进行路由控制。如果 以后,需求改变,又需要进行预处理,你可以改变mapping 来为那个页面引 用到一个Action。因为链接是引用到mapping, 而不是Action类, 所以你可以 修改Action类而不用改变链接。 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 标准的Base Action  DispatchAction – 避免每个Action创建一个类  DispatchAction的配置方法  添加parameter属性到Action的配置中  unspecified方法  举例说明DispatchAction的使用 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 struts配置中的路径与模式匹配  struts配置中的action,有一个path属性,它表明请求的URI  一般情况下,我们需要在配置文件中明确指定某个特定的URI,如 path=―/user/add‖  在一些大型应用中,如果能够制定一套严格的路径及其操作规范的话,我 们可以利用path的路径模式匹配功能,来简化struts配置文件繁琐的编写 工作量  假设有如下规范: 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 路径匹配规范示例  对user对象的所有处理Action,均需要以如下的路径进行访问:  /user/add.do – 处理用户添加的有关操作  /user/delete.do – 处理用户删除的有关操作  /user/update.do – 处理用户更新的有关操作  …  所有操作(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配置示例 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Action配置解释  所有的/user/*.do请求,都将由UserAction这个类来处理,UserAction类继承 DispatchAction,它将根据传入的method参数的值,来分发到不同的方法来进行 处理  在UserAction类中的任何一个方法,都可以返回index/success/error/input等名称 的ActionForward  根据请求路径的不同,即使调用相同的返回代码,但其转向也将不同,如:  /user/add.do?method=add请求,将被转发给UserAction类的add方法处理, 假设它用mapping.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.do或 /user/test.do),都因为没有传递method参数,而触发调用UserAction的 unspecified方法 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Struts回顾  Struts tag lib的配置和使用  JSTL的配置和使用  错误消息的处理  ActionForm的多种用途  DynaActionForm  ActionForward的主要作用,如何动态创建ActionForward  Action的主要职责和处理过程  如何保证Action的线程安全性  国际化与资源文件的配置、使用  ForwardAction  DispatchAction 尚学堂 手把手教程 授课:王勇 版权所有:尚学堂科技 Struts+Hibernate+Spring Hibernate 开源O/R映射框架 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 课程目标  课程目标:  理解O/R Mapping原理  掌握Hibernate开发的相关知识  能使用Hibernate进行实际项目开发  Hibernate高手进级:性能优化策略 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 目录  什么是Hibernate  快速体验Hibernate的开发步骤  认识Hibernate基本核心接口 Hibernate的对象关系映射  Hibernate查询语句(HQL) 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Hibernate?  直接使用JDBC操作数据库的步骤很繁琐  JDBC操作的是关系型数据库  我们用JAVA开发程序,则使用面向对象的思想  Hibernate正是在这两种不同的模型之间建立关联,Hibernate给我们提供 了利用面向对象的思想来操作关系型数据的接口 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 什么是关系模型(Relational Model)?  关系模型把世界看作是由实体(Entity)和联系(Relationship)构成的。  所谓实体就是指现实世界中具有区分与其它事物的特征或属性并与其它实 体有联系的对象。在关系模型中实体通常是以表的形式来表现的。表的每 一行描述实体的一个实例,表的每一列描述实体的一个特征或属性。  所谓联系就是指实体之间的关系,即实体之间的对应关系。  1:1  1:n  m:n  关系数据库  表  字段  主键  外键 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 什么是面向对象?  面向对象三大特征:封装、继承(一般与特殊)、多态(覆盖与重载)  类  对象  属性  关系  一般与特殊关系(is a)  组成(has a)  关联及其多重性  1:1  1:n  m:n  双向关联与单向关联 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 对象关系映射(Object Relational Mapping,简称ORM)  ORM是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技 术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据, 将java程序中的对象自动持久化到关系数据库中。本质上就是将数据从一 种形式转换到另外一种形式。  Why ORM?  面向对象的开发方法是当今企业级应用开发环境中的主流开发方法  关系数据库是企业级应用环境中永久存放数据的主流数据存储系统  字母O起源于―对象‖(Object),而R则来自于―关系‖(Relational)。几乎所有的 程序里面,都存在对象和关系数据库。在业务逻辑层和呈现层中,我们是 面向对象的。当对象信息发生变化的时候,我们需要把对象的信息保存在 关系数据库中。  当你开发一个应用程序的时候(不使用O/R Mapping),你可能会写不少数据 访问层的代码,用来从数据库保存,删除,读取对象信息,等等。而这些 代码写起来总是重复的。 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 对象-关系映射模式  属性映射  类映射  关联映射  一对一  一对多  多对多 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 什么是Hibernate?  对象/关系映射一直都是数据库技术中的难点,尽管人们提出了许多方案 解决这个问题,但都不能完全做到即便利又高效。EJB的推出让人们看到 了希望,但实践证明实体Bean的效率并不高,并且还十分难于为初学者 理解。由Gavin King创建的Hibernate框架,从某种程序上正在朝着正确 的方向迈走,并且得到越来越多IT从业人员的认可。就像当年的Struts框 架一样,Hibernate也已经在许多项目中得到广泛应用。Hibernate由于投 注了更多的精力在提升效率上,使用起来又十分方便,新版的EJB规范正 在向Hibernate方向靠拢。正是由于得到广泛的认可,Hibernate已经成为 程序员必须掌握的技术之一。 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Hibernate能做什么? - 理解O/R映射  Hibernate能帮助我们利用面向对象的思想,开发基于关系型数据库的应 用程序 第一:将对象数据保存到数据库 第二:将数据库数据读入对象中  基于B/S的典型三层架构 关于分层 × 业务逻辑层和持久化层 绝对不能依赖于展现 层 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Hibernate与O、R之间的关系 Hibernate Session 接口 (Hibernate API) 持久化实体对象 (Persistent Objects) 关 系 数 据 库 应用程序 (业务逻辑操作) 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 快速体验Hibernate – 安装以及创建新的项目  下载Hibernate,并解压缩  使用Eclipse创建新的项目  引入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.Driverrootmysqlorg.hibernate.dialect.MySQLDialect   手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 创建持久化类 User.java  public 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  为了让Hibernate能够处理User对象的持久化,需要将它的映射信息加入 到Hibernate中  加入的方法很简单,在Hibernate配置文件中加入:    ………   …..  手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 hibernate-mapping元素  可以包含的子元素  class – 描述被映射的类  subclass/joined-subclass – 在继承关系的映射中会用到  query – 将查询语句定义在配置文件中  …. 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 class元素  常用属性  name – 实体类的类名  table – 被映射到数据库表的名称  可以包含的常见子元素  id – 主键定义  property – 属性定义  关系映射定义(一对多、多对一等) 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 主键 - id  被映射的类必须要有一个id定义  通常使用逻辑主键  逻辑主键:没有意义的唯一标识符  业务主键:有意义的唯一标识符  Hibernate使用generator类来生成主键  Hibernate自带了很多generator(不同的主键生成策略)  int/long – native  String - uuid  我们也可以定义自己的generator  实现IdentifierGenerator接口  一般情况下不需要实现自己的generator 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 主键生成策略generator  generator 主键生成器,每个主键都必须定义相应的主键生成策略。它用来为持久化类 实例生成唯一的标识。  Hibernate内置的主键生成策略  数据库提供的主键生成机制。identity、sequence(序列) 。  外部程序提供的主键生成机制。increment (递增) ,hilo(高低位) , seqhilo(使用序列的高低位 ),uuid.hex(使用了IP地址+JVM的启动时间 (精确到1/4秒)+系统时间+一个计数器值(在JVM中唯一) ), uuid.string。  其它。native(本地),assigned(手工指定),foreign(外部引用)。 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 普通属性映射 - property   可使用的常见属性如下:  name – 对应类的属性名称  type – 指定属性的类型,一般情况下可以不用指定,由hibernate自 动匹配(可参考文档中的有关说明)  length – 指定长度  column – 指定属性所对应的数据库字段的名称,如果不指定,就是 属性的名称 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 多对一关联映射 - many-to-one  User-Group 多个用户属于某个组  从代码上体现为: public class Group { privte String id; private String name; ….. } public class User{ private 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 table 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 constraint FK285FEBC3D18669 foreign key (groupid) references T_Group (id)  从生成的DDL语句,我们可以知道,实际上是在User表上建立了一个指向 Group表的外键关联 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 重要属性cascade  重要属性 - cascade(级联)  级联的意思是指定两个对象之间的操作联动关系,对一个对象执行了 操作之后,对其指定的级联对象也需要执行相同的操作  总共可以取值为:all、none、save-update、delete  all-代表在所有的情况下都执行级联操作  none-在所有情况下都不执行级联操作  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); session.save(user); 执行结果: 抛出org.hibernate.TransientObjectException异常,以上代码中,group对象 是一个瞬时对象,user对象引用了一个瞬时对象,所以在保存的时候出现 异常 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 无cascade配置时正确的java执行代码  为避免异常,我们可以需要将group对象保存 Group group = new Group(); group.setName("jkjk"); //执行save操作之后,group对象变成持久化对象的状态 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); 可正确执行 cascade配置,使得hibernate在管理对象的时候,对cascade对象执行了级联 操作 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 一对一关联映射 (one-to-one)  两个对象之间是一对一的关系,如Person-IdCard  有两种策略可以实现一对一的关联映射  主键关联:即让两个对象具有相同的主键值,以表明它们之间的一一 对应的关系;数据库表不会有额外的字段来维护它们之间的关系,仅 通过表的主键来关联  唯一外键关联:外键关联,本来是用于多对一的配置,但是如果加上 唯一的限制之后,也可以用来表示一对一关联关系; 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+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 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 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语句,将其相关的对象查询出来  set默认lazy属性的值是true,即hibernate会自动使用懒加载策略,以提高 性能  举例说明 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 关于inverse属性  inverse – 标记由哪一方来维护关联关系(双向关联中会用到)  inverse默认值为false  如果inverse设置为true,表示将由对方维护两者之间的关联关系  举例说明 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 多对多关联映射 (many-to-many)  一般的设计中,多对多关联映射,需要一个中间表  Hibernate会自动生成中间表  Hibernate使用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+Hibernate+Spring 尚学堂 继承  继承实现的三种策略  单表继承。每棵类继承树使用一个表(table per class hierarchy)  具体表继承。每个子类一个表(table per subclass)  类表继承。每个具体类一个表(table per concrete class)(有一些限制) 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 每个类继承树对应一张表  因为类继承树肯定是对应多个类,要把多个类的信息存放在一张表中,必须有某 种机制来区分哪些记录是属于哪个类的。这种机制就是,在表中添加一个字段, 用这个字段的值来进行区分。用hibernate实现这种策略的时候,有如下步骤:  父类用普通的标签定义  在父类中定义一个discriminator,即指定这个区分的字段的名称和类型  如:  子类使用标签定义,在定义subclass的时候,需要注意如下几点:  Subclass标签的name属性是子类的全路径名  在Subclass标签中,用discriminator-value属性来标明本子类的discriminator 字段(用来区分不同类的字段)的值  Subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间 的继承关系),也可以与class标签平行。 当subclass标签的定义与class标 签平行的时候,需要在subclass标签中,添加extends属性,里面的值是父类 的全路径名称。  子类的其它属性,像普通类一样,定义在subclass标签的内部。 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 每个子类一张表(除非将父类定义成抽象的,否则父类也是一张 表)  这种策略是使用joined-subclass标签来定义子类的。父类、子类,每个类都对应 一张数据库表。在父类对应的数据库表中,实际上会存储所有的记录,包括父类 和子类的记录;在子类对应的数据库表中,这个表只定义了子类中所特有的属性 映射的字段。子类与父类,通过相同的主键值来关联。实现这种策略的时候,有 如下步骤:  父类用普通的标签定义即可  父类不再需要定义discriminator字段  子类用标签定义,在定义joined-subclass的时候,需要注意如 下几点:  Joined-subclass标签的name属性是子类的全路径名  Joined-subclass标签需要包含一个key标签,这个标签指定了子类和父类之 间是通过哪个字段来关联的。如:,这 里的column,实际上就是父类的主键对应的映射字段名称。  Joined-subclass标签,既可以被class标签所包含(这种包含关系正是表明了 类之间的继承关系),也可以与class标签平行。 当Joined-subclass标签的 定义与class标签平行的时候,需要在Joined-subclass标签中,添加extends 属性,里面的值是父类的全路径名称。  子类的其它属性,像普通类一样,定义在joined-subclass标签的内部。 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 每个具体子类一张表  这种策略是使用union-subclass标签来定义子类的。每个子类对应一张表,而且这 个表的信息是完备的,即包含了所有从父类继承下来的属性映射的字段(这就是 它跟joined-subclass的不同之处,joined-subclass定义的子类的表,只包含子类 特有属性映射的字段)。实现这种策略的时候,有如下步骤:  父类用普通标签定义即可  子类用标签定义,在定义union-subclass的时候,需要注意如下 几点:  Union-subclass标签不再需要包含key标签(与joined-subclass不同)  Union-subclass标签,既可以被class标签所包含(这种包含关系正是表明了 类之间的继承关系),也可以与class标签平行。 当Union-subclass标签的定 义与class标签平行的时候,需要在Union-subclass标签中,添加extends属 性,里面的值是父类的全路径名称。  子类的其它属性,像普通类一样,定义在Union-subclass标签的内部。这个 时候,虽然在union-subclass里面定义的只有子类的属性,但是因为它继承 了父类,所以,不需要定义其它的属性,在映射到数据库表的时候,依然包 含了父类的所有属性的映射字段。 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 双向关联  概念:双向关联允许通过关联的任一端访问另外一端。在Hibernate中, 支持两种类型的双向关联。  一对多(one-to-many),Set或者bag值在一端, 单独值(非集合)在另外一 端 。  多对多(many-to-many),两端都是set或bag值。 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 例子(双向关联):group-user 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 例子:从Java代码看group-user双向关联的inverse  概念:inverse用来标识双向关联的关联关系由哪一端维护。默认inverse 的值为false,由主动方负责维护关联关系;如果设为true,则由反向一端 维护关联关系。  用例:我们假设已经有一个Group类的实例:adminGroup,现在我们要 新增一个用户,并且将用户分配到adminGroup中。  inverse=“false”,由主动方Group负责维护group-user的关联关系. User user = new User(―Jak‖); adminGroup.getUsers.add(user); session.save(user); session.update(group);  inverse=“true”,由Group的反向段User负责维护关联关系。 User user = new User(―Jak‖); user .setGroup(adminGroup); session.save(user); 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Hibernate查询  概述:数据查询与检索是Hibernate中的一个亮点。相对其他ORM实现 而言,Hibernate提供了灵活多样的查询机制。  标准化对象查询(Criteria Query):以对象的方式进行查询,将查询语句 封装为对象操作。优点:可读性好,符合Java 程序员的编码习惯。缺点: 不够成熟,不支持投影(projection)或统计函数(aggregation)  Hibernate语言查询(Hibernate Query Language,HQL):它是完全面 向对象的查询语句,查询功能非常强大,具备多态、关联等特性 。 Hibernate官方推荐使用HQL进行查询。  Native SQL Queries(原生SQL查询):直接使用标准SQL语言或跟特 定数据库相关的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 Language,HQL)  HQL用面向对象的方式生成SQL  以类和属性来代替表和数据列  支持多态  支持各种关联  减少了SQL的冗余  HQL支持所有的关系数据库操作  连接(joins,包括Inner/outer/full joins),笛卡尔积(cartesian products)  投影(projection)  聚合(Aggregation,max, avg)和分组(group)  排序(Ordering)  子查询(Subqueries)  SQL函数(SQL function calls) 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+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=‗admin’”); 如果用传统的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高级话题:性能优化策略的配置与使用  本节包括如下主题:  一级缓存  二级缓存  查询缓存  批量抓取  批量更新 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 一级缓存  即session级别的缓存,随着session的关闭而消失,load/iterator操作,会 从一级缓存中查找数据,如果找不到,再到数据库里面查找。Query.list 操作,如果没有配置查询缓存,将直接从数据库中获取数据。 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 二级缓存(1)  首先要打开二级缓存  默认情况下,二级缓存是打开的,可以通过配置:  false  来关闭二级缓存。  使用:  org.hibernate.cache.EhCacheP rovider  来指定缓存提供商。即有谁来提供缓存的功能。  Ehcache配置  可以看例子,里面有非常清楚的说明。 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 二级缓存(2)  要在映射文件中指定缓存策略  在hbm文件中加入:  <cache usage="read-only"/>  这个缓存策略的配置一定要加上,否则便不会有缓存的作用,Load/list/iterator等 操作的结果将都不会缓存。  注意,在hbm的class配置中添加配置,表示的是类缓存,如果把这个配 置删除,将只缓存ID,不缓存整个对象。(这个时候对list操作,也可能有n+1查 询问题)  当然,也可以选择在标签里面嵌套定义这样的标签:   来代替直接将定义嵌套入标签的内部。  缓存策略  缓存有几种形式,可以在映射文件中配置:read-only(只读,适用于很少变更的静 态数据/历史数据),nonstrict-read-write(不严格读写缓存,如果基本不会发生有 两个事务同时修改一个数据的时候,比read-write的性能要好),read-write(比较 普遍的形式,效率一般),transactional(JTA中,且支持的缓存产品较少) 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 二级缓存(3)  Session如何与二级缓存交互?  Session接口通过CacheMode来定制与二级缓存之间的交互方法 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 查询缓存  默认情况下关闭,需要打开。查询缓存,对list/iterator这样的操作会起作 用。。。。  可以使用:  true  来打开查询缓存,默认的情况下是关闭的。  所谓查询缓存,即让hibernate缓存list、iterator、createQuery等方法的查 询结果集。如果没有打开查询缓存,hibernate将只缓存load方法获得的单 个持久化对象。  在打开了查询缓存之后,需要注意,调用query.list()操作之前,必须显式 调用query.setCachable(true)来标识某个查询使用缓存。 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 单端代理的批量抓取  实例A引用实例B,B如果是代理的话(比如多对一关联中):  如果遍历A的查询结果集(假设有10条记录),在遍历A的时候,访问B变量,将 会导致n次查询语句的发出!这个时候,如果在B一端的class上配置batch-size, Hibernate将会减少SQL语句的数量。  Hibernate可以充分有效的使用批量抓取,也就是说,如果仅一个访问代理(或集 合),那么Hibernate将不载入其他未实例化的代理。 批量抓取是延迟查询抓取的 优化方案,你可以在两种批量抓取方案之间进行选择:在类级别和集合级别。  类/实体级别的批量抓取很容易理解。假设你在运行时将需要面对下面的问题:你 在一个Session中载入了25个 Cat实例,每个Cat实例都拥有一个引用成员owner, 其指向Person,而Person类是代理,同时lazy="true"。 如果你必须遍历整个cats 集合,对每个元素调用getOwner()方法,Hibernate将会默认的执行25次SELECT 查询, 得到其owner的代理对象。这时,你可以通过在映射文件的Person属性, 显式声明batch-size,改变其行为:  ...随之,Hibernate将只需要执 行三次查询,分别为10、10、 5。 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 集合代理的批量抓取  你也可以在集合级别定义批量抓取。例如,如果每个Person都拥有一个 延迟载入的Cats集合, 现在,Sesssion中载入了10个person对象,遍历 person集合将会引起10次SELECT查询, 每次查询都会调用getCats()方 法。如果你在Person的映射定义部分,允许对cats批量抓取, 那么, Hibernate将可以预先抓取整个集合。请看例子:  ... 如果整个的batch-size是3,那么Hibernate将会分四次执 行SELECT查询, 按照3、3、3、1的大小分别载入数据。 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 批量更新  Jdbc fetch size:  每次取多少条数据,需要JDBC和底层数据库的支持。不会一次性把 全部数据读入内存,而是按照一定的数量来批量读取相应的数据。  Fetch size建议值是50  hibernate.jdbc.fetch_size  Jdbc batch size  批量更新  建议取值30  hibernate.jdbc.batch_size 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Hibernate最佳实践(Best Practices) 1、使用Configuration装载映射文件时,不要使用绝对路径装载。最好的方式 是通过getResourceAsStream()装载映射文件,这样Hibernate会从 classpath中寻找已配置的映射文件。 2、SessionFactory的创建非常消耗资源,整个应用一般只要一个 SessionFactory就够了,只有多个数据库的时候才会使用多个 SessionFactory。 3、在整个应用中,Session和事务应该能够统一管理。(Spring为Hibernate 提供了非常好的支持) 4、将所有的集合属性配置设置为懒加载(lazy=‖true‖)。在hibernate2.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子句本身大小写无关,但是其中出现的类名和属性名必须注意大小写 区分。 8、在非分布式架构中,不需要使用DTO来向上层传输数据。直接使用POJO 的Entity就可以了。 9、如果要精通Hibernate,熟练掌握关系数据库理论和SQL是前提条件。 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Hibernate资源  官方网站:http://www.hibernate.org  国内网站:http://www.hibernate.org.cn  Java新视线论坛:http://forum.hibernate.org  《Hibernate 中文开发指南》作者夏昕(http://www.redsaga.com/)  《深入浅出Hibernate》作者:夏昕 曹晓钢 唐勇 (http://www.china-pub.com/computers/common/info.asp?id=24500)  《Hibernate in Action》 作者:Christian Bauer and Gavin King (http://www.javafan.net/可下载)  《Hibernate: A Developer's Notebook》作者:James Elliott 尚学堂 手把手教程 授课:王勇 版权所有:尚学堂科技 Struts+Hibernate+Spring Spring 轻量级容器架构 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Spring最常用的特性  利用Spring来创建对象(JavaBean工厂)  利用Spring构建业务逻辑层  管理依赖关系  适应需求变更  利用Spring创建数据访问对象(DAO)  利用Spring进行事务处理 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Spring的安装  下载并解压  http://www.springframework.org/  将相应的jar包加入类路径  spring.jar  配置Spring  ApplicationContext.xml  体验Spring的最基本特性-BeanFactory 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 创建Sample类及其Spring配置文件  Sample.java public class Sample { public int compute(int i,int j){ return i + j; } }  ApplicationContext.xml 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 创建测试程序ClientTest.java public class ClientTest { /** * @param args */ public static void main(String[] args) { //获取BeanFactory BeanFactory beanFactory = new ClassPathXmlApplicationContext("applicationContext.xml"); //从容器中获取Sample对象 Sample sample = (Sample)beanFactory.getBean("sample"); //调用Sample对象的方法 int result = sample.compute(3,4); System.out.println(result); } } 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 针对接口编程的原则  重要的设计原则:针对接口编程,而不要针对实现编程 思考:compute方法功能需求变更 ?  针对接口编程的目的:降低耦合度,增强应用程序的稳定性  让Sample类变成接口 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Sample接口及其实现  接口定义 public interface Sample{ public int compute(int i,int j); }  接口的实现一 public class SampleImpl1 implements Sample { public int compute(int i,int j){ return i + j; } }  接口的实现二 public class SampleImpl2 implements Sample { public int compute(int i,int j){ return i * j; } }  ClientTest.java无需改动  只需改动ApplicationContext.xml 的配置,即可实现实际功能的切 换 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 第二个例子  我们已经确定,基于接口编程,是OOD中的重要原则  一个层次的实现代码,不应该依赖于另外一个层次的实现代码  下面是第二个例子:BookLister,这个例子包括如下几个类:  实体类:Book,有名称、作者等属性  BookFinder接口,定义了findAll()方法  BookLister接口,定义了findBooks(String name)方法,以书名作为 参数,并返回Book[]数组作为查找的结果  以及一个测试客户端BookClient,调用BookLister,来获取所需要的 数据 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Book.java public class Book { private String name; private String author; /** * @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 尚学堂 BookFinder  BookFinder接口 public interface BookFinder { public List findAll(); }  SimpleBookFinderImpl public class SimpleBookFinderImpl implements BookFinder{ /** * @see com.bjsxt.spring.BookFinder#findAll() */ public List findAll() { List books = new ArrayList(); for(int i=0; i<20; i++){ Book book = new Book(); book.setName("book"+i); book.setAuthor("author"+i); books.add(book); } return books; } } 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 BookLister  BookList接口 public interface BookLister{ public Book[] findBooks(String name); }  BookListerImpl实现代码 public class BookListerImpl implements BookLister { BookFinder finder; public BookListerImpl() { finder = new SimpleBookFinderImpl(); } public Book[] findBooks(String 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 Book[books.size()]); } 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Spring配置:ApplicationContext.xml及客户调用代码  Spring配置:  以上配置,即指定了BookListerImpl和FileBookFinderImpl之间的依赖关 系,这种依赖关系,被放到了配置文件中,这样,只要需求有变更,只需 要修改这种依赖关系即可,java代码本身不用任何变更 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 热门词汇:IOC/DI  控制反转(Inversion of Control,IoC)与依赖注入(Dependency Injection)  由容器来管理对象之间的依赖关系(而不是对象本身来管理),就 叫“控制反转”或“依赖注入”  以上代码,已清楚阐述IOC/DI出现的原因,以及IOC的基本原理  Spring框架的基本思想就是IOC/DI  Spring就是一个IOC容器  IOC与DI,说的是一回事,但DI这个名词更能表达这种设计模式的 思想 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 依赖注入的类型  构造器注入  通过类的构造方法注入依赖关系  设值方法注入  通过类的setter方法注入依赖关系  第三种:接口注入(不常用)  定义一个注入接口,在需要注入的类中实现此接口,由于这种方法具 有侵入性,所以不常用 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Spring的依赖注入  Spring是一个Java Bean容器,它维护着一系列Java Bean的示例  通过Spring所提供的依赖注入的方法,我们可以管理这些Java Bean之间 的引用关系 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 更多的例子  我们可以通过构造器来将实现依赖进行注入  示例  我们可以通过setter方法,实现类的配置  将易于变动的部分转移到配置文件中  示例:给FileBookListerImpl加上path和name的配置 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 通过setter方法注入依赖(属性)  类代码示例  Spring配置示例 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Spring架构 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 DAO设计模式  什么是DAO?  Data Access Object(数据访问对象)  最重要的核心J2EE模式之一  为什么需要DAO?  屏蔽业务逻辑对数据持久化的依赖  一定需要DAO吗?  如果业务逻辑比较简单(比如只有简单的数据存取操作),完全可以 取消DAO  是否需要DAO,完全取决于业务需求,没有固定的说法 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Spring与Hibernate的集成  从例子入手  安装Hibernate  创建User实体类  创建User映射文件  创建Hibernate配置文件  创建DAO对象  创建Manager对象  SessionFactory配置  声明式事务配置  DAO定义  Manager定义 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 创建可以支持Hibernate的DAO对象  HibernateDaoSupport  这是Spring提供的集成Hibernate的基类,所有的DAO,均需要继承 它  从这个类中,可以获取Hibernate的各种核心接口,如Session、 SessionFactory等  HibernateTemplate  HibernateTemplate是Spring封装的Hibernate操作接口,类似于 Session接口  可以调用HibernateDaoSupport提供的getHibernateTemplate()方法 获取HibernateTemplate对象 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 创建Manager对象  Manager对象没有任何特殊之处,它就是普通的接口和实现类 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 在Spring中声明SessionFactory  一种简单的配置方式,即指定Hibernate配置文件的路径所在即可 classpath:hibernate.cfg.xml 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 在Spring中配置事务管理  大多数的应用程序,事务管理被分配到业务逻辑方法上,即每个业务逻 辑方法是一个事务  在Spring中,所有的业务逻辑对象,均是普通的POJO  Spring最强大的功能在于,它可以在普通的POJO上面实现声明式的事务 管理(它使用AOP来完成这样的任务)  可插入的事务策略  步骤如下:  定义一个事务管理器  定义一个事务代理基类 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 事务管理器的定义 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 事务管理的AOP配置 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 正确的配置DAO  Dao的配置示例  必须注入sessionFactory的定义 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 简单配置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.ContextLoaderListener 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 修改Struts的Action类  我们在原来的Action配置中,type属性,直接指向我们的Action类(即Action类的 全路径)  现在我们需要将这些Action类的创建,交给Spring去完成  所以,我们需要修改两个地方:  Action配置中type属性,由原来的Action类,改为: org.springframework.web.struts.DelegatingActionProxy  在Spring配置文件中,添加对Action类的定义,如: 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 建立测试J2EE项目  建立一个web项目  在web项目中安装Struts  安装Spring  配置web.xml  配置Action  配置Spring 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 Struts+Hibernate+Spring  Hibernate与Spring的集成  Struts与Spring的集成  Struts+Hibernate+Spring的集成  没有更多的东西,前面已经分别将它们集成起来了  注意使用OpenSessionInView模式,这是使用Hibernate的web项目 最需要注意的一个问题,Spring为此提供了专门的解决方案 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+Spring 尚学堂 OpenSessionInViewFilter  这是为了避免Hibernate的懒加载异常而创建的解决方案  它是一个过滤器,能够让Session在请求解释完成之后再关闭(所以才能够避免懒 加载异常)  配置方式是,在web.xml中定义过滤器即可: hibernateFilter org.springframework.orm.hibernate3.support.OpenSessionInViewFilter hibernateFilter /* 手把手教程 版权所有:尚学堂科技 Struts+Hibernate+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.org  Spring中文网  http://spring.jactiongroup.net (有中文参考手册下载)
还剩187页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

4323236

贡献于2016-05-11

下载需要 10 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf