随笔-0  评论-15  文章-10  trackbacks-0
@import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);

首先:我们需要搭建SSH环境,在这里,我们选择使用Myeclipse自带的导航为我们添加框架支持。接下来,我会一步步教大家做。

1.新建一个工程项目


2.添加Hibernate框架支持

A.myeclipse--project capabilities--add Hibernate capabilities


B.在这里,使用Hibernate3.3版本,默认情况下添加核心包和注解包,注意,勾选最下面选项,将jar自动添加到lib目录,方便换了电脑后修改。


C.这一步,按照默认点击next,生成的配置文件,我们可能不会使用到,因为我们整合了Spring。



D.忽略数据库连接的创建


E.不使用Hibernate帮我们创建SessionFactory,Spring会帮助我们创建


到此为止,Hibernate的配置就完成了,下面我们来进行Spring的配置。

3.添加Spring框架支持


A.在这里我们使用Spring2.5的版本,所添加的jar包括以下5个(截图为4个,还有一个为Spring2.5 web libray)别忘记把jar添加到lib目录。


B.创建的Spring配置文件applicationContext.xml一般不用改名字,但目录建议改为webroot/WEB-INF下,因为Spring加载配置文件默认从那里开始


C.接下来一步,一般不需要选择,我们自己编写代码来创建SessionFactory

到目前为止,我们基本上把Spring也配置完成了,观察我们的包结构,会发现多了一些标记,如‘S’等,意味着我们已经成功添加了Spring框架。接下来我们添加Struts框架支持,myeclipse没有为我们提供导航,你可以下载相关插件,但也不必要因为配置Struts的框架比较简单,手动添加就可以了。

4.添加Struts框架支持。

A.导入Struts2.2相关架包,注意不要忘记Struts2=Spring-plugin.jar这个包,它是框架整合需要用到的。


B.创建一个Struts的配置文件Struts.xml,可以直接拷贝之前项目的。(截图略)

C.配置Struts的启动参数,在web.xml配置相关信息,如下:


D.同时,我们注册Spring的监听器,一样是在web.xml文件下

<!-- 配置Spring监听器 -->

<listener>

<listener-class>

org.springframework.web.context.ContextLoaderListener

</listener-class>

</listener>

有同学要问为什么不配置Spring配置文件的加载路径,因为之前我们已经修改过路径为Spring默认的加载路径,所以在这里我们不需要指定,但是如果你自定义了配置文件在src目录下,你需要配置如下信息:

<!-- 指定spring的配置文件,默认从web根目录寻找配置文件,我们可以通过spring提供的classpath:前缀指定从类路径下寻找 -->

<context-param>

   <param-name>contextConfigLocation</param-name>

   <param-value>classpath:beans.xml</param-value>

</context-param>

到目前为止,我们已经成功的为我们的项目添加了SSH的框架支持,接下来我们可以加载一遍服务器,启动服务器,运行一下我们的这个小系统,看是否能跑起来。(截图略)如果没有异常,表示大功告成。

5.配置Spring的applicationContext.xml文件

在配置之前,必要说明一点:在这里我们使用的是sql server 2005作为后台数据库,所以要加入相关的驱动,我们在这里选用jtds驱动,当然你可以使用其它,比如jdbc等,此时我们还需要导入jtds的架包:jtds-1.2.jar.

A.在Spring的配置文件中,我们首先配置数据源:

<!-- 

  配置数据源  

    驱动:jtds

    数据库:sql server 2005

 username : sa

 password : 123

-->

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

<property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver"></property>

<property name="url" value="jdbc:jtds:sqlserver://localhost:1433/oa;characterEncoding=UTF-8"></property>

<property name="username" value="sa"></property>

<property name="password" value="123"></property>

<property name="maxActive" value="100"></property>

<property name="maxIdle" value="30"></property>

<property name="maxWait" value="500"></property>

<property name="defaultAutoCommit" value="true"></property>

</bean>

B.然后我们配置会话工厂SessionFactory:相关属性不做介绍,在这里主要mappingResource这个属性,我们填写的就是我们要操作的实体对象,在这里我们要对一个User对象进行操作,所以我们需要创建一个User类,把这个对象映射到数据库当中。

<!-- 会话工厂 -->

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

<property name="dataSource" ref="dataSource"></property>

<property name="hibernateProperties">

<props>

<!-- 数据库方言  -->

<prop key="hibernate.dialect">org.hibernate.dialect.SybaseDialect</prop>

<!-- 显示sql语言 -->

<prop key="hibernate.show_sql">true</prop>

</props>

</property>

<!-- 映射文件  -->

<property name="mappingResources">

<list>

<value>cn/zbvc/bean/User.hbm.xml</value>

</list>

</property>

</bean>

6..现在,我们的Spring配置文件先配置到这里,接下来,我们来创建我们的实体映射类User和他的实体映射文件User.hbm.xml:

在User类中,增加相关属性,id,name,.age即可以,然后增加其set和get方法,这里就省略了。

然后我们创建其实体映射文件User.hbm.xml,要求和User类是在同一个包下:在这里注意一点,就是id的生成策略,在这里我们使用native,如果改为increment自增的话会出现一些问题,具体网上有解释,可参考http://blog.sina.com.cn/s/blog_57554ed50100e3cu.html

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<class name="cn.zbvc.bean.User" table="users">

<id name="id">

<generator class="native"></generator>

</id>

<property name="name"/>

<property name="age"/>

</class>

</hibernate-mapping>

7.下面我们来完成第一个功能,增加一个用户的操作(注:保证数据库已经有了我们需要使用数据库oa),在写增加操作之前我们需要明白一个流程,即SSH是如何运行的,他们的流程是什么?

首先客户端提交需要保存的信息到filter,filter根据不同的需求转发给不同的Action,Action调用业务逻辑层Service方法,Service层再调用持久层方法,持久层直接对数据库进行操作,最后再一步步的返回相应到Action,到客户端。所以在写我们的CRUD之前,我们还需要做一步就是建立我们的业务逻辑层和持久层还有Action表现层。


通过这个截图图,我们可以看到我们的相关类和接口已经创建完成了,在这里我要说明的是,我们的Action可能会有好几个,因为在这里我们只是写一个demo,所以方便大家看,我们为各自的功能分别增加一个Action,另外,对于业务逻辑层,在这里它的功能和持久层一致,因为这是一个demo,没有太多复杂的业务,但为了养成良好的习惯我们还是强制的加上这个业务逻辑层。

(1)下面我们首先编写DAO层的相关具体操作:

package cn.zbvc.dao;

import java.util.List;

import cn.zbvc.bean.User;

public interface UserDAO {

/**

 * 保存用户

 * @param user

 */

public void saveUser(User user);

/**

 * 删除用户

 * @param id

 */

public void deleteUser(int id);

/**

 * 根据id找到某个用户

 * @param id

 */

public User findUserById(int id);

/**

 * 查询所有的用户

 * @param user

 * return List<User>

 */

public List<User> findAllUsers();

/**

 * 更新用户

 * @param user

 */

public void updateUser(User user);

}

(2)具体实现类:

在具体实现类里我们需要注意,我们继承了一个HibernateDaoSupport,这个类是Spring给我们提供的用于操作数据库的类,使用非常简单。具体代码如下:

package cn.zbvc.dao.impl;

import java.util.List;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import cn.zbvc.bean.User;

import cn.zbvc.dao.UserDAO;

public class UserDAOImpl extends HibernateDaoSupport implements UserDAO {

public void deleteUser(int id) {

User user = findUserById(id);

if(user != null){

this.getHibernateTemplate().delete(user);

}

}

@SuppressWarnings("unchecked")

public List<User> findAllUsers() {

String hql = "from User";

return (List<User>)this.getHibernateTemplate().find(hql);

}

public User findUserById(int id) {

return (User)this.getHibernateTemplate().get(User.class, id);

}

public void saveUser(User user) {

this.getHibernateTemplate().save(user);

}

public void updateUser(User user) {

this.getHibernateTemplate().update(user);

}

}

接下来拷贝相关代码到业务逻辑层,注意:在业务逻辑层需要创建一个持久层的对象来调用持久层的方法,这个持久层对象我们使用Spring为我们创建,具体代码如下:首先在业务层定义这样一个持久层对象userDao.,同时我们Action还需要定义个业务逻辑层的对象,所以其创建也在配置文件中写到。

<!-- 创建持久层Dao对象  依赖注入sessionFactory-->

<bean id="userDao" class="cn.zbvc.dao.impl.UserDAOImpl" scope="singleton">

  <property name="sessionFactory" ref="sessionFactory"/>

</bean>

<!-- 创建业务逻辑层Service对象   依赖注入其持久层对象属性-->

<bean id="userService" class="cn.zbvc.service.impl.UserServiceImpl">

  <property name="userDao" ref="userDao" />

</bean>

再往下继续,我们需要编写我们的Action了,第一个Action:SaveUserAction.java:保存用户信息,以往的做法是添加这个用户的属性字段,实例化User对象,调用其set方法封装信息到User对象中,然后调用相关方法。但是假设属性字段比较多的时候这个方法不可取,现在我们使用模型驱动的方式获取我们的表单信息,首先,我们编写一个网页,叫做save.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<%@ taglib prefix="s" uri="/struts-tags"%>

<html>

  <head>

    <title>Save User</title>

  </head>

  

  <body>

    <h1><font color="red">保存用户</font></h1>

    <s:form action="saveUser">

     <!-- 注意name = 对象名.属性名  -->

     <s:textfield name="user.name" label="%{getText('name')}"></s:textfield>

     <s:textfield name="user.age" label="%{getText('age')}"></s:textfield>

   <s:submit value="提交"></s:submit>

    </s:form>

  </body>

</html>

然后我们需要配置Struts.xml相关信息:在这里我们看到我们的class是一个别名,也就是说我们对于Action的实例,也让Spring托管了。另外当返回结果为success的时候我们使其重定向为listUser.action,这个action的目的是为了显示所有用户信息的列表。具体代码如下:

<!-- 保存用户的Action -->

<action name="saveUser" class="saveUserAction">

  <result name="success" type="redirect">listUser.action</result>

  <result name="input">/save.jsp</result>

</action>

<!-- 显示所有用户的Action -->

<action name="listUser" class="listUserAction">

  <result name="success">/listUser.jsp</result>

</action>

     <!-- 创建控制层SaveUserAction的对象 依赖注入其业务层对象属性  -->

<bean id="saveUserAction" class="cn.zbvc.action.user.SaveUserAction"  scope="prototype">

   <property name="service" ref="userService" />

</bean>

<!-- 创建ListUserAction的对象  依赖注入其业务逻辑层对象属性-->

<bean id="listUserAction" class="cn.zbvc.action.user.ListUserAction"  scope="prototype">

   <property name="service" ref="userService" />

</bean>

SaveUserAction.java的具体代码如下:

package cn.zbvc.action.user;

import cn.zbvc.bean.User;

import cn.zbvc.service.UserService;

import com.opensymphony.xwork2.ActionSupport;

/**

 * 控制层Action

 * @author 吕鹏

 */

public class SaveUserAction extends ActionSupport {

private User user;

private UserService service;//通过Spring创建业务层对象  使用set方法依赖注入

public void setService(UserService service) {

this.service = service;

}

public User getUser() {

return user;

}

public void setUser(User user) {

this.user = user;

}

@Override

public String execute() throws Exception {

this.service.save(this.user);

return SUCCESS;

}

}

下面我们来进行一下测试,看我们能否保存数据到数据库当中,在这之前,请再次检查一下相关配置,Struts.xml文件的配置,applicationContext.xml的配置等是否已经都正确,然后加载服务器,启动服务器,进入save.jsp页面;



许多同学可能不知道listUser.jsp的页面是如何显示的。下面拷贝一下代码:

 <body> 

    <center>

    <h1><font color="red">用户列表</font></h1>

    

    <table border="1" width="450">

      <tr>

        <td>序号</td>

        <td>姓名</td>

        <td>年龄</td>

        <td>是否删除</td>

        <td>是否更新</td>

      </tr>

  <s:iterator value="listUser">

  <tr>

        <td><s:property value="id"/></td>

        <td><s:property value="name"/></td>

        <td><s:property value="age"/></td>

        <td><a href='<s:url action="deleteUser.action"><s:param name="user.id" value="id"/></s:url>' onclick="return del()">删除</a></td>

        <td><a href='<s:url action="findUser.action"><s:param name="user.id" value="id"/></s:url>'>更新</a></td>

      </tr> 

  </s:iterator>

    </table>

    </center>

  </body>

从代码中可以看到我们使用了Struts2的标签库,其中迭代器的使用是比较方便的。刚才,我们完成了增加和查询所有信息的操作,接着往下看,我们要对数据进行删除和修改操作,先做删除,删除的话,我们要传递给DeleteAction一个id值,根据id值删除我们在数据库中的记录,我们可以在Action里面写这样一个字段id,添加其set和get方法,在网页上写这样的传递语句:(参考语句)

<td align="center"><a href="deleteUser.action?id=<s:property value="id"/>">删除</a></td>

但是这样的写法有一个问题,没有使用到我们之前的模型驱动,我们既然已经定义了User的对象,我们使用Struts2的标签就可以简化代码为:

<td><a href='<s:url action="deleteUser.action"><s:param name="user.id" value="id"/></s:url>' onclick="return del()">删除</a></td>

这样写的好处就是在Action中就没必要再增加id这个字段和其方法了。

然后我们还需要写相关的删除和修改的Action,在struts.xml文件中进行配置,在applicationContext文件中进行Action的配置,代码如下:

<!-- 删除用户的Action -->

<action name="deleteUser" class="deleteUserAction">

  <result name="success" type="redirect">listUser.action</result>

</action>

<!-- 查询用户的Action -->

<action name="findUser" class="findUserAction">

  <result name="success">/update.jsp</result>

</action>

<!-- 更新用户的Action -->

<action name="updateUser" class="updateUserAction">

  <result name="success" type="redirect">listUser.action</result>

  <result name="input">update.jsp</result>

</action>

在这里,可能你有一个问题不明白,为什么还有一个findUser的Action,因为是这样的,当我们进行修改操作的时候,必要要传递一个id值,根据id值查到相关的信息,进入一个修改页面,在修改页面中需要显示这个User的信息,所以这个过程需要用到findUser这个Action。

接下来是applicationContext.xml

<!-- 创建deleteUserAction的对象  依赖注入其业务逻辑层对象属性-->

<bean id="deleteUserAction" class="cn.zbvc.action.user.DeleteUserAction" scope="prototype">

  <property name="service" ref="userService" />

</bean>

<!-- 创建findUserAction的对象  依赖注入其业务逻辑层对象属性-->

<bean id="findUserAction" class="cn.zbvc.action.user.FindUserAction" scope="prototype">

  <property name="service" ref="userService" />

</bean>

<!-- 创建UpdateUserAction的对象  依赖注入其业务逻辑层对象属性-->

<bean id="updateUserAction" class="cn.zbvc.action.user.UpdateUserAction" scope="prototype">

  <property name="service" ref="userService" />

</bean>

在这些Action的配置中,你会发现多了一个参数,即scope="prototype"为什么要加这样一个参数,具体原因请浏览:http://blog.sina.com.cn/s/blog_5f12739d0100cre0.html

这样,我们基本上就完成了CRUD的相关配置和代码编写,下面我们再次进行测试,看是否可以完成这些操作:

Index.jsp:


Save.jsp:


listUser.jsp:(非功能截图)


Update.jsp:

显示要修改的用户


修改


修改成功


Delete.action:


这个对话框是使用js技术实现的,具体代码如下:

<SCRIPT type="text/javascript">

      function del()

      {

        var result = confirm("你确定删除吗?");

        if(result)

        {

          return true;

        }

        else

        {

          return false;

        }

      }

</SCRIPT>

删除成功(截图略)

以上就是一个简单的SSH整合的CRUD操作。

我们简单的回顾一下:

(1)首先,我们分别使用导航配置了Hibernate和Spring的框架

(2)创建了实体映射类和实体映射文件User.hbm.xml

(3)然后我们导入了Struts2.2的相关包,配置了Struts.xml文件

(4)然后我们又配置了applicationContext.xml文件和web.xml文件

(5)最后编写我们的Action,DAO,Service等

(6)最后编写相关操作网页等

讲解当中,我重点讲解了一些重点,还希望大家回顾的时候好好看,我推荐的一些网站,也都是很重要的。

下面我们针对这个CRUD系统,做一下扩展:

(1)国际化问题

在我们的表单里,默认语言为中文,所以显示的label都是汉字,当我们的默认语言设置为英文的情况下,显示的依旧是中文,这样是不健全的,所以我们需要使用Struts2国际化修改我们的jsp页面,这里只做一个简单的例子,将Save页面的label国际化:

大家都知道,国际化要在struts.xml文件中加一句

<constant name="struts.custom.i18n.resources" value="globalMessages" />

这里我们使用另外一种方式,和这个道理是一样的,我们建议资源文件:struts.properties,在文件中写:

struts.custom.i18n.resources=globalMessages

然后我们再建立关于中文或者英文的相关资源文件:


以中文为例,要注意不可以保存中文字符,所以要利用一些工具进行操作:

id=\u5E8F\u53F7

name=\u59D3\u540D

age=\u5E74\u9F84

做完这些操作以后,我们需要在我们的页面进行一下修改:

<s:form action="saveUser">

     <!-- 注意label处调用的getText方法  -->

     <s:textfield name="user.name" label="%{getText('name')}"></s:textfield>

     <s:textfield name="user.age" label="%{getText('age')}"></s:textfield>

   <s:submit value="提交"></s:submit>

    </s:form>

然后我们把浏览器默认字符改成en  英文:


效果:


还有一个文件globalMessages.properties.这个文件的作用也是处理国际化问题,它还有一个作用是处理age的校验,当age字段接受的值为非数字的时候,将会出现文件的提示信息:

xwork.default.invalid.fieldvalue={0} \u683C\u5F0F\u4E0D\u6B63\u786E

国际化问题就讲到这里。

(2)校验问题

我们在保存用户和修改修护的时候并没有对其字段进行校验,在这里我们扩展一下校验:

大家所知道的校验方式有这么两三种,客户端校验和服务器的校验,服务器的校验又分重写valdate方法,和校验框架,对于客户端校验在这里就不写了,对于validate方法这里也省略,我们来写一下校验框架,校验框架就是字段校验,代码很简单,拷贝一下:

<!-- 模型字段校验方式 -->

<validators>

<field name="user.name">

<field-validator type="requiredstring">

<message>姓名不能为空</message>

</field-validator>

</field>

<field name="user.age">

<field-validator type="required">

<message>required age</message>

</field-validator>

<field-validator type="int">

<param name="min">1</param>

<param name="max">150</param>

<message>年龄应该保持在 ${min} 到 ${max}</message>

</field-validator>

</field>

</validators>

我们讲这种校验方式叫做   模型字段校验方式,使用起来也比较容易理解,下面我们介绍另外一种校验方式,visitor方式:

<!--visitor校验方式-->

<validators>

<!-- 要校验的属性  -->

<field name="user">

<!-- 校验类型  -->

<field-validator type="visitor">

<!-- 上下文:具体的检验文件名字在这里指定 -->

<param name="context">user</param>

<!-- 附加前缀 比如:'用户的'  -->

<param name="appendPrefix">true</param>

<!-- 附加前缀内容  -->

<message>用户的 </message>

</field-validator>

</field>

</validators>

我们发现我们的代码明显少了很多,看具体代码,都有注释,也容易理解。既然我们说使用这种校验方式,可是我们并没有看到具体的校验代码,原因是因为我们把校验的代码放到了别的地方,我们应该放在什么地方呢?Action是不断变化的,我们放在User对象所在的包下就可以了:

首先我们在User类所在包下建立这样一个文件User-user-validation.xml这个文件的命名是有一定讲究的,第一个User是要校验的类,第二个user是这个文件的真实名字,这个名字在前面的配置文件中出现过。。。里面的具体代码如下:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">

<validators>

<field name="name">

<field-validator type="requiredstring">

<message>姓名不能为空</message>

</field-validator>

</field>

<field name="age">

<field-validator type="required">

<message>required age</message>

</field-validator>

<field-validator type="int">

<param name="min">1</param>

<param name="max">150</param>

<message>年龄应该保持在 ${min} 到 ${max}</message>

</field-validator>

</field>

</validators>

我们看一下效果:当什么都不输入的时候:


好,以上就是对这样一个SSH整合的CRUD的扩展,这节就到这里,接下来,我还会陆续的整理一些关于框架整合的案例,以此巩固框架的整合,慢慢的提升能力。下节课,我们在本节课的基础上再次的扩展,内容如下:

当我们查看数据库的信息的时候,数据库过大的情况下,我们需要采用分页,分页机制在开发中是一件繁琐而又复杂的事。下节课,我们来整理这样一个分页机制,帮助大家理解分页功能的实现。

posted on 2011-07-10 09:50 吕鹏-Roc 阅读(5000) 评论(8)  编辑  收藏 所属分类: SSH

评论:
# re: Struts2.2+Hibernate3.3+Spring2.5.6整合 一个简单的CRUD案例 2011-12-13 17:09 |
学习了“Struts2.2+Hibernate3.3+Spring2.5.6整合 一个简单的CRUD案例”很受启发。谢谢你的文章。
能不能把“Struts2.2+Hibernate3.3+Spring2.5.6整合 一个简单的CRUD案例”中得完整代码发给我。
daiyuanq@sina.com
  回复  更多评论
  
# re: Struts2.2+Hibernate3.3+Spring2.5.6整合 一个简单的CRUD案例 2011-12-14 08:53 |
我的QQ951173450
我在武汉,是个高校教师。不知你在哪个城市?
能不能加我?
向你学习!



  回复  更多评论
  
# re: Struts2.2+Hibernate3.3+Spring2.5.6整合 一个简单的CRUD案例[未登录] 2012-02-23 10:39 | yuan
楼主你的service和serviceimpl呢?  回复  更多评论
  
# re: Struts2.2+Hibernate3.3+Spring2.5.6整合 一个简单的CRUD案例 2012-05-27 11:18 | 龙腾
楼主可以把源码发给我吗?谢谢!zzu_dyf@163.com
这个没service和serviceimpl呀!  回复  更多评论
  
# re: Struts2.2+Hibernate3.3+Spring2.5.6整合 一个简单的CRUD案例 2012-08-17 10:59 | susan
请问吕老师可以发源码给我吗?想看源代码学习一下。谢谢您。
annie123sue.student@sina.com  回复  更多评论
  
# re: Struts2.2+Hibernate3.3+Spring2.5.6整合 一个简单的CRUD案例 2012-09-09 16:10 | 暗暗
如果可以给我发下源代码,有些看不明白,314706221@qq.com  回复  更多评论
  
# re: Struts2.2+Hibernate3.3+Spring2.5.6整合 一个简单的CRUD案例 2012-10-09 15:16 |
我按照您的步骤写到了保存用户,然后运行总是出现这样一个错误,严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is java.io.FileNotFoundException: class path resource [com/ljy/pojo/User.hbm.xml] cannot be opened because it does not exist 请问这是哪里出错了,我得怎样改才对呢?  回复  更多评论
  
# re: Struts2.2+Hibernate3.3+Spring2.5.6整合 一个简单的CRUD案例 2013-04-10 22:03 | liansong
调试总是出错,不知可否方便把源码发我,330868432@qq.com.  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: