OA项目实战学习(4)——代码优化

Service层+Dao层——>Service层

前面实现了岗位管理与部门管理的功能,它们的功能大体相同,都实现了增删改查。大致都是通过了JSP页面——>访问action文件——>业务方法——>数据访问层方法——>操作数据库。

但是,通过观察业务层与数据访问层代码非常相似,因此可以将这两层抽取为一层。Service层+Dao层——>Service层。

以前的层之间类的继承与实现关系:


我们希望将Service层+Dao层——>Service层之后,代码更加少,做更多的事。


代码实现:

BaseDao.java

package cn.xbmu.oa.base;

import java.util.List;

public interface BaseDao<T> {
	/**
	 * 保存实体
	 * @param entity
	 */
	void save(T entity);
	/**
	 * 删除实体
	 * @param id
	 */
	void delete(Long id);
	/**
	 * 更新实体
	 * @param entity
	 */
	void update(T entity);
	/**
	 * 查询实体
	 * @param id
	 * @return
	 */
	T getById(Long id);
	/**
	 * 查询实体
	 * @param ids
	 * @return
	 */
	List<T> getByIds(Long[] ids);
	/**
	 * 查询所有
	 * @return
	 */
	List<T> findAll();
}
BaseDaoImpl.java
package cn.xbmu.oa.base;

import java.lang.reflect.ParameterizedType;
import java.util.Collections;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.transaction.annotation.Transactional;
//	@Transactional注解可以被继承,即对子类也有效
@Transactional
public class BaseDaoImpl<T> implements BaseDao<T> {
	@Resource
	private SessionFactory sessionFactory;
	protected Class<T> clazz;
	public BaseDaoImpl(){
		//通过反射得到T的真是类型
		ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
		this.clazz = (Class<T>) pt.getActualTypeArguments()[0];
		System.out.println("clazz="+clazz.getName());
	}
	
	public void save(T entity) {
		getSession().save(entity);
	}

	public void update(T entity) {
		getSession().update(entity);
	}
	
	public void delete(Long id) {
		Object obj = getSession().get(clazz, id);
		getSession().delete(obj);
	}


	public T getById(Long id) {
		return (T)getSession().get(clazz, id);
	}

	public List<T> getByIds(Long[] ids) {
		if(ids == null || ids.length == 0){
			return Collections.EMPTY_LIST;//避免空指针异常			
		}
		return getSession().createQuery(//
				"FROM "+clazz.getSimpleName()+" WHERE id IN(:ids)")//
				.setParameterList("ids", ids)//
				.list();
	}

	public List<T> findAll() {
		return getSession().createQuery(//
				"FROM "+clazz.getSimpleName())//
				.list();
	}
	/**
	 * 获取当前可用的session
	 * @return
	 */
	protected Session getSession() {
		return sessionFactory.getCurrentSession();
	}

}

RoleService.java

package cn.xbmu.oa.service;

import cn.xbmu.oa.base.BaseDao;
import cn.xbmu.oa.domain.Role;

public interface RoleService extends BaseDao<Role>{

}
RoleServiceImpl.java
package cn.xbmu.oa.service.impl;

import org.springframework.stereotype.Service;

import cn.xbmu.oa.base.BaseDaoImpl;
import cn.xbmu.oa.domain.Role;
import cn.xbmu.oa.service.RoleService;
@Service
public class RoleServiceImpl extends BaseDaoImpl<Role> implements RoleService {
	

}
DepartmentService.java
package cn.xbmu.oa.service;

import cn.xbmu.oa.base.BaseDao;
import cn.xbmu.oa.domain.Department;

public interface DepartmentService extends BaseDao<Department>{


}

DepartmentServiceImpl.java

package cn.xbmu.oa.service.impl;

import org.springframework.stereotype.Service;

import cn.xbmu.oa.base.BaseDaoImpl;
import cn.xbmu.oa.domain.Department;
import cn.xbmu.oa.service.DepartmentService;

@Service
public class DepartmentServiceImpl extends BaseDaoImpl<Department> implements
		DepartmentService {

}

抽取基类BaseAction

BaseAction.java

package cn.xbmu.oa.base;

import java.lang.reflect.ParameterizedType;

import javax.annotation.Resource;

import cn.xbmu.oa.service.DepartmentService;
import cn.xbmu.oa.service.RoleService;
import cn.xbmu.oa.service.UserSerivce;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

public class BaseAction<T> extends ActionSupport implements ModelDriven<T>{
	
	/**以下变量声明为protected,是为了子类方便访问*/
	protected T model;
	@Resource
	protected UserSerivce userSerivce;
	@Resource
	protected RoleService roleService;
	@Resource
	protected DepartmentService departmentService;
	public BaseAction(){
		try {
			// 得到model的类型信息
			ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
			Class clazz = (Class) pt.getActualTypeArguments()[0];
			// 通过反射生成model的实例
			model = (T) clazz.newInstance();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	public T getModel() {
		return model;
	}

}

其他的Action继承BaseAction即可。

现在目录结构为:

                       

我们发现添加与修改的页面基本一样。因此可以将修改和添加页面合并为一起。

editUI.jsp+addUI.jsp——>saveUI.jsp

主要修改<s:form action="..."></s:form>提交信息,struts.xml配置信息,action文件信息:




UserAction.java

package cn.xbmu.oa.view.action;

import java.util.HashSet;
import java.util.List;

import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.opensymphony.xwork2.ActionContext;

import cn.xbmu.oa.base.BaseAction;
import cn.xbmu.oa.domain.Department;
import cn.xbmu.oa.domain.Role;
import cn.xbmu.oa.domain.User;

@Controller
@Scope("prototype")
public class UserAction extends BaseAction<User> {
	private Long departmentId;
	private Long[] roleIds;

	public String list() throws Exception {
		List<User> userList = userSerivce.findAll();
		ActionContext.getContext().put("userList", userList);
		return "list";
	}

	public String delete() throws Exception {
		userSerivce.delete(model.getId());
		return "toList";
	}

	public String addUI() throws Exception {
		// 准备数据,departmentList
		// TODO:应是显示树状结构,先使用所有的部门列表代替
		List<Department> departmentList = departmentService.findAll();
		ActionContext.getContext().put("departmentList", departmentList);
		// 准备数据,roleList
		List<Role> roleList = roleService.findAll();
		ActionContext.getContext().put("roleList", roleList);
		return "saveUI";
	}

	public String add() throws Exception {
		// 1.新建对象并设属性(也可以使用model)
		Department department = departmentService.getById(departmentId);
		model.setDepartment(department);

		List<Role> roleList = roleService.getByIds(roleIds);
		model.setRoles(new HashSet<Role>(roleList));

		String passwdMD5 = DigestUtils.md5Hex("1234");
		model.setPassword(passwdMD5);// 默认密码为1234,应使用MD5加密

		// 2.保存到数据库
		userSerivce.save(model);
		return "toList";
	}

	public String editUI() throws Exception {
		// 准备数据,departmentList
		// TODO:应是显示树状结构,先使用所有的部门列表代替
		List<Department> departmentList = departmentService.findAll();
		ActionContext.getContext().put("departmentList", departmentList);
		// 准备数据,roleList
		List<Role> roleList = roleService.findAll();
		ActionContext.getContext().put("roleList", roleList);
		// 准备回显的数据
		User user = userSerivce.getById(model.getId());
		ActionContext.getContext().getValueStack().push(user);
		if (user.getDepartment() != null) {
			departmentId = user.getDepartment().getId();
		}
		if (user.getRoles().size() > 0) {
			roleIds = new Long[user.getRoles().size()];
			int index = 0;
			for (Role role : user.getRoles()) {
				roleIds[index++] = role.getId();
			}
		}
		return "saveUI";
	}

	public String edit() throws Exception {
		// 1,从数据库中取出原对象
		User user = userSerivce.getById(model.getId());

		// 2,设置要修改的属性
		// >> 普通属性
		user.setLoginName(model.getLoginName());
		user.setName(model.getName());
		user.setGender(model.getGender());
		user.setPhoneNumber(model.getPhoneNumber());
		user.setEmail(model.getEmail());
		user.setDescription(model.getDescription());
		// >> 所属部门
		Department department = departmentService.getById(departmentId);
		user.setDepartment(department);
		// >> 关联的岗位
		List<Role> roleList = roleService.getByIds(roleIds);
		user.setRoles(new HashSet<Role>(roleList));

		// 3,更新到数据库
		userSerivce.update(user);
		return "toList";
	}

	/** 初始化密码 */
	public String initPassword() throws Exception {
		//1.从数据库中取出原对象
		User user = userSerivce.getById(model.getId());
		//2.设置要修改的属性(要使用MD5摘要)
		String passwdMD5 = DigestUtils.md5Hex("1234");
		user.setPassword(passwdMD5);
		//3.更新到数据库
		userSerivce.update(user);
		return "toList";
	}

	// --------------------------------------
	public Long getDepartmentId() {
		return departmentId;
	}

	public void setDepartmentId(Long departmentId) {
		this.departmentId = departmentId;
	}

	public Long[] getRoleIds() {
		return roleIds;
	}

	public void setRoleIds(Long[] roleIds) {
		this.roleIds = roleIds;
	}

}

其中密码使用了摘要MD5加密,我们使用了Apache旗下的一个jar包


saveUI.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
	<title>用户信息</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script language="javascript" src="${pageContext.request.contextPath}/script/jquery.js"></script>
    <script language="javascript" src="${pageContext.request.contextPath}/script/pageCommon.js" charset="utf-8"></script>
    <script language="javascript" src="${pageContext.request.contextPath}/script/PageUtils.js" charset="utf-8"></script>
    <link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath}/style/blue/pageCommon.css" />
    <script type="text/javascript">
    </script>
</head>
<body>

<!-- 标题显示 -->
<div id="Title_bar">
    <div id="Title_bar_Head">
        <div id="Title_Head"></div>
        <div id="Title"><!--页面标题-->
            <img border="0" width="13" height="13" src="${pageContext.request.contextPath}/style/images/title_arrow.gif"/> 用户信息
        </div>
        <div id="Title_End"></div>
    </div>
</div>

<!--显示表单内容-->
<div id=MainArea>
    <s:form action="userAction_%{id==null ? 'add':'edit'}">
    	<s:hidden name="id"/>
        <div class="ItemBlock_Title1"><!-- 信息说明 --><div class="ItemBlock_Title1">
        	<img border="0" width="4" height="7" src="${pageContext.request.contextPath}/style/blue/images/item_point.gif" /> 用户信息 </div> 
        </div>
        
        <!-- 表单内容显示 -->
        <div class="ItemBlockBorder">
            <div class="ItemBlock">
                <table cellpadding="0" cellspacing="0" class="mainForm">
                    <tr><td width="100">所属部门</td>
                        <td>
                            <s:select name="departmentId" list="#departmentList" 
                            	listKey="id" listValue="name" cssClass="SelectStyle"
                            	headerKey="" headerValue="请选择部门"
                            />
                            
                        </td>
                    </tr>
                    <tr><td>登录名</td>
                        <td><s:textfield name="loginName" cssClass="InputStyle"/> *
							(登录名要唯一)
						</td>
                    </tr>
                    <tr><td>姓名</td>
                        <td><s:textfield name="name" cssClass="InputStyle"/> *</td>
                    </tr>
					<tr><td>性别</td>
                        <td>
                        	<%--
                        		<s:radio name="gender" list="#{'男':'男','女':'女'}"></s:radio>
                        	--%>
							<s:radio name="gender" list="%{{'男','女' }}"/>
						</td>
                    </tr>
					<tr><td>联系电话</td>
                        <td><s:textfield name="phoneNumber" cssClass="InputStyle"/></td>
                    </tr>
                    <tr><td>E-mail</td>
                        <td><s:textfield name="email" cssClass="InputStyle"/></td>
                    </tr>
                    <tr><td>备注</td>
                        <td><s:textarea name="description" cssClass="TextareaStyle"/></td>
                    </tr>
                </table>
            </div>
        </div>
        
		<div class="ItemBlock_Title1"><!-- 信息说明 --><div class="ItemBlock_Title1">
        	<img border="0" width="4" height="7" src="${pageContext.request.contextPath}/style/blue/images/item_point.gif" /> 岗位设置 </div> 
        </div>
        
        <!-- 表单内容显示 -->
        <div class="ItemBlockBorder">
            <div class="ItemBlock">
                <table cellpadding="0" cellspacing="0" class="mainForm">
                    <tr>
						<td width="100">岗位</td>
                        <td>
                        	<s:select name="roleIds" list="#roleList" cssClass="SelectStyle"
                        		multiple="true" size="10" listKey="id" listValue="name">
                        	</s:select>
                                                       按住Ctrl键可以多选或取消选择
                        </td>
                    </tr>
                </table>
            </div>
        </div>		
		
        <!-- 表单操作 -->
        <div id="InputDetailBar">
            <input type="image" src="${pageContext.request.contextPath}/style/images/save.png"/>
            <s:a action="javascript:history.go(-1);"><img src="${pageContext.request.contextPath}/style/images/goBack.png"/></s:a>
        </div>
    </s:form>
</div>

<div class="Description">
	说明:<br />
	1,用户的登录名要唯一,在填写时要同时检测是否可用。<br />
	2,新建用户后,密码被初始化为"1234"。<br />
	3,密码在数据库中存储的是MD5摘要(不是存储明文密码)。<br />
	4,用户登录系统后可以使用“个人设置→修改密码”功能修改密码。<br />
	5,新建用户后,会自动指定默认的头像。用户可以使用“个人设置→个人信息”功能修改自已的头像<br />
	6,修改用户信息时,登录名不可修改。
</div>

</body>
</html>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

上善若水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值