第一步:添加Spring4框架,具体步骤如下:
第二步:添加Hibernate4框架,具体步骤如下:
第三步:添加Struts2框架,具体步骤如下:
EmployeeAction类中list()方法的核心代码如下所示:
/**
* 功能一:查询并显示所有员工信息
* 注意事项:
* 1). 在事务作用范围之外访问员工的部门名称可能会出现懒加载异常,采用迫切左外连接查询或使用OpenSessionInViewFilter来实现
* 2). 通过实现RequestAware接口来获取request,将获取的员工信息放入其属性中,即可在显示页面获取并显示
* @return
*/
public String list() {
/**
* System.out.println(employeeService.getAll()); //会出现懒加载异常
* 事务作用的EmployeeService的getAll()方法上,其执行完毕即提交事务,此时打印员工的部门信息即会出现异常
*/
request.put("EMPLOYEES", employeeService.getAll());
return "list";
}
执行删除后需要将返回值设置为redirect类型,并重定向到emp-list;其中,删除时的提示信息和Ajax请求实现的核心代码如下所示:
<script type="text/javascript" src="scripts/jquery-1.7.2.js">script>
<script type="text/javascript">
$(function() {
// 1). 弹出信息提示框
$(".delete").click(function() {
var name = $(this).next(":input").val();
var flag = confirm("确定要删除" + name + "的信息吗?");
if(flag) {
// 2). 删除员工的信息
var $tr = $(this).parent().parent();
// 发送删除请求
var url = this.href;
var args = {"times":new Date()}; //用于禁用缓存
$.post(url, args, function(data) {
if(data == "1") {
alert("恭喜您,删除成功!");
if($tr.siblings().length == 0) {
$tr.parent().parent().remove();
}
$tr.remove();
} else {
alert("对不起,删除失败!");
}
});
}
// 取消超链接的默认行为
return false;
});
});
script>
显示表单页面时,需要先查询出所有的部门信息;需要使用Struts2的ModelDriven和Preparable拦截器;也需要自定义转换器将时间字符串转为日期对象。其中,Ajax校验员工名的核心代码如下所示:
<script type="text/javascript" src="scripts/jquery-1.7.2.js">script>
<script type="text/javascript">
$(function() {
$(":input[name=name]").change(function() {
var nameval = $(this).val();
nameval = $.trim(nameval);
$this = $(this);
if(nameval != "") {
$this.nextAll("font").remove();
var url = "emp-validateName";
var args = {"name":nameval, "time":new Date()};
$.post(url, args, function(data) {
if(data == "1") {
$this.after("恭喜您,员工名可用!");
} else if (data == "0") {
$this.after("对不起,员工名不可用!");
} else {
alert("服务器异常,请重试!");
}
});
} else {
alert("对不起,员工姓名不能为空!");
$(this).val("");
}
});
});
script>
需要回显当前员工的信息,并设置其员工名不可修改。
基于SSH框架的员工增删改查小案例的实现代码下载地址:http://download.csdn.net/download/bingbeichen/9790372。
package com.qiaobc.ssh.actions;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Map;
import org.apache.struts2.interceptor.RequestAware;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;
import com.qiaobc.ssh.entities.Employee;
import com.qiaobc.ssh.service.DepartmentService;
import com.qiaobc.ssh.service.EmployeeService;
public class EmployeeAction extends ActionSupport implements RequestAware, ModelDriven<Employee>, Preparable {
private static final long serialVersionUID = 1L;
private EmployeeService employeeService;
private DepartmentService departmentService;
public void setEmployeeService(EmployeeService employeeService) {
this.employeeService = employeeService;
}
public void setDepartmentService(DepartmentService departmentService) {
this.departmentService = departmentService;
}
/**
* 功能一:查询并显示所有员工信息
* 注意事项:
* 1). 在事务作用范围之外访问员工的部门名称可能会出现懒加载异常,采用迫切左外连接查询
* 2). 通过实现RequestAware接口来获取request,将获取的员工信息放入其属性中,即可在显示页面获取并显示
*
* @return
*/
public String list() {
/**
* System.out.println(employeeService.getAll()); //会出现懒加载异常
* 事务作用的EmployeeService的getAll()方法上,其执行完毕即提交事务,此时打印员工的部门信息即会出现异常
*/
request.put("EMPLOYEES", employeeService.getAll());
return "list";
}
private Map request;
@Override
public void setRequest(Map arg0) {
this.request = arg0;
}
/**
* 功能二-1:正常删除当前员工的信息
* 注意事项:根据员工id删除当前员工信息后需要重定向到emp-list,以防止删除操作的重复提交
*/
/*
* public String delete() { employeeService.delete(id); return "delete"; }
*/
private Integer id;
public void setId(Integer id) {
this.id = id;
}
private InputStream inputStream;
public InputStream getInputStream() {
return inputStream;
}
/**
* 功能二-2:使用Ajax删除当前员工的信息,需要使用jQuery弹出信息提示框
* Ajax的具体使用参见struts-2.3.31/docs/docs/ajax.html,与Struts2的文件下载类似
*/
public String delete() {
try {
employeeService.delete(id);
inputStream = new ByteArrayInputStream("1".getBytes("UTF-8"));
} catch (Exception e) {
e.printStackTrace();
try {
inputStream = new ByteArrayInputStream("0".getBytes("UTF-8"));
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
}
return "ajax-success";
}
/**
* 功能三:添加员工信息
* 1). 显示表单页面:需要先查询所有的部门信息
* 2). 使用Struts2的ModelDriven和Preparable拦截器
* 3). 需要将时间字符串转为日期对象
*/
public String input() {
// 获取所有的部门信息
request.put("DEPARTMENTS", departmentService.getDepartments());
return "input";
}
public void prepareInput() {
if(id != null) {
model = employeeService.get(id);
}
}
@Override
public void prepare() throws Exception {}
private Employee model;
@Override
public Employee getModel() {
return model;
}
public String save() {
if(id == null) {
model.setCreateTime(new Date());
}
employeeService.saveOrUpdate(model);
return "save";
}
/**
* 可以根据id来判断是从数据库获取model还是创建新的model
* @return
*/
public void prepareSave() {
if(id == null) {
model = new Employee();
} else {
model = employeeService.get(id);
}
}
private String name;
public void setName(String name) {
this.name = name;
}
public String validateName() throws UnsupportedEncodingException {
if(employeeService.validateName(name)) {
inputStream = new ByteArrayInputStream("1".getBytes("UTF-8"));
} else {
inputStream = new ByteArrayInputStream("0".getBytes("UTF-8"));
}
return "ajax-success";
}
}
package com.qiaobc.ssh.converters;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import org.apache.struts2.util.StrutsTypeConverter;
public class SSHDateConverters extends StrutsTypeConverter {
private DateFormat dateFormat;
{
dateFormat = new SimpleDateFormat("yyyy-MM-dd");
}
@Override
public Object convertFromString(Map context, String[] values, Class toClass) {
System.out.println("convertFromString");
if(toClass == Date.class) {
try {
return dateFormat.parse(values[0]);
} catch (ParseException e) {
e.printStackTrace();
}
}
return values;
}
@Override
public String convertToString(Map context, Object o) {
System.out.println("convertToString");
if(o instanceof Date) {
return dateFormat.format((Date) o);
}
return null;
}
}
package com.qiaobc.ssh.dao;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
public class BaseDao {
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public Session getSession() {
Session session = this.sessionFactory.getCurrentSession();
return session;
// return this.sessionFactory.getCurrentSession();
}
}
package com.qiaobc.ssh.dao;
import java.util.List;
import com.qiaobc.ssh.entities.Department;
public class DepartmentDao extends BaseDao {
/**
* 查询所有的部门信息
*/
@SuppressWarnings("unchecked")
public List getDepartments() {
String hql = "FROM Department";
return getSession().createQuery(hql).list();
}
}
package com.qiaobc.ssh.dao;
import java.util.List;
import com.qiaobc.ssh.entities.Employee;
public class EmployeeDao extends BaseDao {
@SuppressWarnings("unchecked")
public List getAll() {
// 使用迫切左外连接查询防止出现懒加载异常
String hql = "FROM Employee e LEFT JOIN FETCH e.dept";
return getSession().createQuery(hql).list();
}
public void delete(int id) {
String hql = "DELETE FROM Employee e WHERE e.id = ?";
getSession().createQuery(hql).setInteger(0, id).executeUpdate();
}
public void saveOrUpdate(Employee employee) {
getSession().saveOrUpdate(employee);
}
public Employee validateName(String name) {
String hql = "FROM Employee e WHERE e.name = ?";
return (Employee) getSession().createQuery(hql).setString(0, name).uniqueResult();
}
public Employee get(Integer id) {
return (Employee) getSession().get(Employee.class, id);
}
}
package com.qiaobc.ssh.service;
import java.util.List;
import com.qiaobc.ssh.dao.EmployeeDao;
import com.qiaobc.ssh.entities.Employee;
public class EmployeeService {
private EmployeeDao employeeDao;
public void setEmployeeDao(EmployeeDao employeeDao) {
this.employeeDao = employeeDao;
}
public List getAll() {
List emps = employeeDao.getAll();
return emps;
}
public void delete(int id) {
employeeDao.delete(id);
}
public void saveOrUpdate(Employee employee) {
employeeDao.saveOrUpdate(employee);
}
public boolean validateName(String name) {
return employeeDao.validateName(name) == null;
}
public Employee get(Integer id) {
return employeeDao.get(id);
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<bean id="employeeAction" class="com.qiaobc.ssh.actions.EmployeeAction" scope="prototype">
<property name="employeeService" ref="employeeService">property>
<property name="departmentService" ref="departmentService">property>
bean>
<bean id="employeeDao" class="com.qiaobc.ssh.dao.EmployeeDao">
<property name="sessionFactory" ref="sessionFactory">property>
bean>
<bean id="employeeService" class="com.qiaobc.ssh.service.EmployeeService">
<property name="employeeDao" ref="employeeDao">property>
bean>
<bean id="departmentDao" class="com.qiaobc.ssh.dao.DepartmentDao">
<property name="sessionFactory" ref="sessionFactory">property>
bean>
<bean id="departmentService" class="com.qiaobc.ssh.service.DepartmentService">
<property name="departmentDao" ref="departmentDao">property>
bean>
beans>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.user}">property>
<property name="password" value="${jdbc.password}">property>
<property name="driverClass" value="${jdbc.driverClass}">property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}">property>
<property name="initialPoolSize" value="${jdbc.initialPoolSize}">property>
<property name="maxPoolSize" value="${jdbc.maxPoolSize}">property>
bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource">property>
<property name="configLocation" value="classpath:hibernate.cfg.xml">property>
<property name="mappingLocations" value="classpath:com/qiaobc/ssh/entities/*.hbm.xml">property>
bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory">property>
bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="*"/>
tx:attributes>
tx:advice>
<aop:config>
<aop:pointcut expression="execution(* com.qiaobc.ssh.service.*.*(..))" id="txPointcut"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
aop:config>
beans>
jdbc.user=root
jdbc.password=root
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///spring
jdbc.initialPoolSize=5
jdbc.maxPoolSize=10
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialectproperty>
<property name="hibernate.show_sql">trueproperty>
<property name="hibernate.format_sql">trueproperty>
<property name="hibernate.hbm2ddl.auto">updateproperty>
session-factory>
hibernate-configuration>
<struts>
<package name="ssh-emps" namespace="/" extends="struts-default">
<interceptors>
<interceptor-stack name="sshEmpsStack">
<interceptor-ref name="paramsPrepareParamsStack">
<param name="prepare.alwaysInvokePrepare">falseparam>
interceptor-ref>
interceptor-stack>
interceptors>
<default-interceptor-ref name="sshEmpsStack">default-interceptor-ref>
<action name="emp-*" class="employeeAction" method="{1}">
<result name="list">/WEB-INF/views/emp-list.jspresult>
<result name="delete" type="redirect">/emp-listresult>
<result name="ajax-success" type="stream">
<param name="contentType">text/htmlparam>
<param name="inputName">inputStreamparam>
result>
<result name="input">/WEB-INF/views/emp-input.jspresult>
<result name="save" type="redirect">/emp-listresult>
action>
package>
struts>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
head>
<script type="text/javascript" src="scripts/jquery-1.7.2.js">script>
<script type="text/javascript">
$(function() {
// 1). 弹出信息提示框
$(".delete").click(function() {
var name = $(this).next(":input").val();
var flag = confirm("确定要删除" + name + "的信息吗?");
if(flag) {
// 2). 删除员工的信息
var $tr = $(this).parent().parent();
// 发送删除请求
var url = this.href;
var args = {"times":new Date()}; //用于禁用缓存
$.post(url, args, function(data) {
if(data == "1") {
alert("恭喜您,删除成功!");
if($tr.siblings().length == 0) {
$tr.parent().parent().remove();
}
$tr.remove();
} else {
alert("对不起,删除失败!");
}
});
}
// 取消超链接的默认行为
return false;
});
});
script>
<body>
<s:debug>s:debug>
<br>
<s:if
test="#request.EMPLOYEES == null || #request.EMPLOYEES.size() == 0">
<h4>暂没有任何员工信息...h4>
s:if>
<s:else>
<table border="1" cellpadding="10" cellspacing="0">
<thead>
<tr>
<td>IDtd>
<td>NAMEtd>
<td>EMAILtd>
<td>BIRTHDAYtd>
<td>CREATETIMEtd>
<td>DEPARTMENTtd>
<td>DELETEtd>
<td>EDITtd>
tr>
thead>
<tbody>
<s:iterator value="#request.EMPLOYEES">
<tr>
<td>${id }td>
<td>${name }td>
<td>${email }td>
<td>
<s:date name="birth" format="yyyy-MM-dd"/>
td>
<td>
<s:date name="createTime" format="yyyy-MM-dd hh-mm-ss"/>
td>
<td>${dept.name }td>
<td>
<a href="emp-delete?id=${id }" class="delete">Deletea>
<input type="hidden" value="${name }">
td>
<td><a href="emp-input?id=${id }">Edita>td>
tr>
s:iterator>
tbody>
table>
s:else>
body>
html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
head>
<script type="text/javascript" src="scripts/jquery-1.7.2.js">script>
<script type="text/javascript">
$(function() {
$(":input[name=name]").change(function() {
var nameval = $(this).val();
nameval = $.trim(nameval);
$this = $(this);
if(nameval != "") {
$this.nextAll("font").remove();
var url = "emp-validateName";
var args = {"name":nameval, "time":new Date()};
$.post(url, args, function(data) {
if(data == "1") {
$this.after("恭喜您,员工名可用!");
} else if (data == "0") {
$this.after("对不起,员工名不可用!");
} else {
alert("服务器异常,请重试!");
}
});
} else {
alert("对不起,员工姓名不能为空!");
$(this).val("");
}
});
});
script>
<body>
<h4>Add New Employee:h4>
<s:form action="emp-save" method="post">
<s:if test="id != null">
<s:textfield label="Name" name="name" disabled="true">s:textfield>
<s:hidden name="id">s:hidden>
s:if>
<s:else>
<s:textfield label="Name" name="name">s:textfield>
s:else>
<s:textfield label="Email" name="email">s:textfield>
<s:textfield label="Birth" name="birth">s:textfield>
<s:select list="#request.DEPARTMENTS"
listKey="id" listValue="name"
label="Department" name="dept.id">s:select>
<s:submit>s:submit>
s:form>
body>
html>