JSP+Servlet培训班作业管理系统[11] -通用CRUD后端的实现(以人员管理为例)

兄弟们,今日头条搜索三线城市程序员老陈关注我,我将持续不断推出视频教程。

根据上一篇的设计,猫哥想实现的是对于类似的某种实体概念(比如人员)的增删改查操作,将相似的逻辑封装一下,不用每次都写重复的部分。扯得远了点,直接看具体如何实现的:

在具体实现之前,先展示下效果,需要注意,猫哥将表格美工,内容部分美工,整个后台页面美工的css文件都单独抽取出来了,因为css不是本系列的重点且此前已经详细讲过了,此处不再贴代码。

a,登录成功后
JSP+Servlet培训班作业管理系统[11] -通用CRUD后端的实现(以人员管理为例)_第1张图片
b,点击人员管理后
JSP+Servlet培训班作业管理系统[11] -通用CRUD后端的实现(以人员管理为例)_第2张图片
c,点击人员编码7右边对应的删除后
JSP+Servlet培训班作业管理系统[11] -通用CRUD后端的实现(以人员管理为例)_第3张图片
d,点击人员编码2右边对应的编辑后
JSP+Servlet培训班作业管理系统[11] -通用CRUD后端的实现(以人员管理为例)_第4张图片
e,点击保存后
JSP+Servlet培训班作业管理系统[11] -通用CRUD后端的实现(以人员管理为例)_第5张图片

1,首先就是菜单信息的参数化,因为增、删、改、查等功能都是规定好的以/HomeworkSystem/AcitonServlet?method=XXX&entity=YYY&id=ZZZ中的参数为区分,所以将Constant类修改为:

package util;
import java.util.HashMap;
public class Constant {//保存常量信息
	//roleMenu用于保存角色及对应的菜单信息
	public static HashMap<String,String[][]> roleMenu=new HashMap<String,String[][]>();
	//使用static代码块对roleMenu进行初始化
	static{
		//注意,二位数组中的每一组表示一个菜单的信息,又通过map建立了角色名和菜单直接的对应关系
		roleMenu.put("校长", new String[][]{
				{"人员管理","view","User"},//由具体的地址,变为抽象的参数
				{"课程管理","view","Course"}
		});
		roleMenu.put("教师", new String[][]{});
		roleMenu.put("学生", new String[][]{});
	}
}

2,从登录页面到LoginServlet,登录录成功后跳转index.jsp,此时index.jsp中的菜单加载部分需要修改如一下,主要有两处,一是菜单栏每一个菜单href属性指向参数化了,二是右侧内容区对应网址修改为actionUrl,猫哥感觉actionUrl更能表达此刻的心意,哈哈。

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html>
  <head>   
    <title>index.jsptitle>
    <link href="css/index.css" type="text/css" rel="stylesheet"/>
  head>
  <body>
  	<div id="main">
	  	<div id="top">
	  		<div id="top_title">
	  			猫哥培训班作业管理系统
	  		div>
	  		<div id="top_info">
	  			欢迎您,尊敬的:${loginUser.userName}
	  		div>
	  	div>
	  	<div id="left">
	  		<ul>
	  		  	<c:forEach items="${loginRoleMenu}" var="menu">
		 		<li>
		 			<a href="/HomeworkSystem/ActionServlet?method=${menu[1]}&entity=${menu[2]}">${menu[0]}a>
		 		li>
		    	c:forEach>
	  		ul>
	  	div>
	  	<div id="right">
	  		<c:if test="${empty actionUrl}">
	  			欢迎来到猫哥培训班管理系统
	  		c:if>
	  		<c:if test="${not empty actionUrl}">
	  			<jsp:include page="${actionUrl}" flush="true">jsp:include>
	  		c:if>
	  	div>
  	div>
  body>
html>

3,好的,来到CRUD操作控制的核心ActionServlet了,此时都是使用if判断的,针对不同的网页请求,采用不同的处理操作:

package servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import command.ActionCommand;
import entity.*;
import java.util.List;
public class ActionServlet extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doPost(request, response);//doGet与doPost一样处理
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//输入输出设置
		response.setContentType("text/html");
		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		//获取标准Action动作的三个参数
		String method=request.getParameter("method");
		String entityType=request.getParameter("entity");
		String id=request.getParameter("id");
		//处理                                                                                                                 
		String actionUrl=doAction(request,method,entityType,id);
		request.setAttribute("actionUrl",actionUrl);
		//跳转
		request.getRequestDispatcher("/index.jsp").forward(request,response);
	}
	//具体细分的控制处理,返回内容区域应该显示的网页地址
	private String doAction(HttpServletRequest request,String method,String entityType,String entityId){
		String url="";//初始化返回值
		ActionCommand actionCommand=new ActionCommand(entityType);//处理数据库逻辑
		if(method.equals("view")){//查看
			List entityList=actionCommand.selectAll();
			request.setAttribute("entityList",entityList);
			url=entityType.toLowerCase()+"Manage.jsp";
		}else if(method.equals("delete")){//删除
			actionCommand.deleteById(entityId);
			List entityList=actionCommand.selectAll();
			request.setAttribute("entityList",entityList);//更新名单
			url=entityType.toLowerCase()+"Manage.jsp";
		}else if(method.equals("edit")){//修改
			Object entity=actionCommand.selectById(entityId);
			request.setAttribute("editEntity", entity);
			url=entityType.toLowerCase()+"Update.jsp";
		}else if(method.equals("add")){//新增
			url=entityType.toLowerCase()+"Update.jsp";
		}else if(method.equals("save")){//保存
			//因保存时各类实体代码各不一致,导致写在此处会很难看,所以由单独提取成一个方法
			this.doSaveAction(request,entityType,actionCommand);
			List entityList=actionCommand.selectAll();
			request.setAttribute("entityList",entityList);//更新名单
			url=entityType.toLowerCase()+"Manage.jsp";
		}
		return url;
	}
	//单独处理save,因为save方法是跟具体的实体类结构相关
	private void doSaveAction(HttpServletRequest request,String entityType,ActionCommand actionCommand){
		String id=request.getParameter("hiddenId");
		Object entity=null;
		//-------------------------------------------------------------------------------
		//此处为组装区域,根据不同页面内容是变化的,其余部分都是按一定规则固定了的
		if(entityType.equals("User")){
			User user=new User();
			if(!"".equals(id))//修改
				user.setUserId(Integer.parseInt(id));
			else//新增
				user.setUserPassword("1234");//初始化密码
			user.setUserName(request.getParameter("userName"));
			Role role=new Role();
			role.setRoleId(Integer.parseInt(request.getParameter("userRole")));
			user.setUserRole(role);
			entity=user;
		}
		//-------------------------------------------------------------------------------
		//实体修改到数据库
		if(!"".equals(id)){//修改
			actionCommand.update(entity);
		}else{//添加
			actionCommand.add(entity);
		}
	}
}

4,其中数据库操作部分是调用ActionCommand实现的,ActionCommand具体如下:

package command;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import entity.*;
import operation.*;
public class ActionCommand{
	private String entityType;
	public ActionCommand(String type){
		entityType=type;
	}
	public List selectAll(){
		ObjectOperation oper=OperationFactory.createOperation(entityType);
		return oper.selectAll();
	}
	public int deleteById(String id){
		ObjectOperation oper=OperationFactory.createOperation(entityType);
		return oper.deleteById(id);
	}
	public Object selectById(String id){
		ObjectOperation oper=OperationFactory.createOperation(entityType);
		return oper.selectById(id);
	}
	public int add(Object entity){
		ObjectOperation oper=OperationFactory.createOperation(entityType);
		return oper.add(entity);
	}
	public int update(Object entity){
		ObjectOperation oper=OperationFactory.createOperation(entityType);
		return oper.update(entity);
	}
}

发现ActionCommand的代码倒是非常精简啊,因为本来就是要增删改查嘛。好的,至于数据库操作层的代码,此处就不细讲了,需要的可自行翻看以前的章节。

5,下面先来实现人员管理的列表页面userManage.jsp如下:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><!-- 使用c:标签需要添加本行代码 -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>  
    <title>userManage.jsp</title>
    <link href="css/content.css" type="text/css" rel="stylesheet"/>
    <link href="css/table.css" type="text/css" rel="stylesheet"/>
  </head>
  <body>
  	<div id="user_top">
  		人员管理
  	</div><!-- user_top end -->
  	<div id="user_mid">
  		<table class="table_theme1">
  			<thead>
  				<th>人员编码</th>
  				<th>姓名</th>
  				<th>角色</th>
  				<th>操作</th>
  				<th>操作</th>
  			</thead>
  			<c:forEach items="${entityList}" var="item">
		 		<tr>
		 			<td>${item.userId}</td>
		 			<td>${item.userName}</td>
		 			<td>${item.userRole.roleName}</td>
		 			<td><a href="/HomeworkSystem/ActionServlet?method=edit&entity=User&id=${item.userId}">编辑</a></td>
		 			<td><a href="/HomeworkSystem/ActionServlet?method=delete&entity=User&id=${item.userId}">删除</a></td>
		 		</tr>
		    </c:forEach>	
  		</table>
  	</div><!-- user_mid end -->
  	<div id="user_bottom">
  		<a href="/HomeworkSystem/ActionServlet?method=add&entity=User">新增</a>
  	</div><!-- "user_bottom" end -->
  </body>
</html>

6,最后,实现人员管理修改/新增时的页面:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><!-- 使用c:标签需要添加本行代码 -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>  
    <title>userUpdate.jsp</title>
    <link href="css/content.css" type="text/css" rel="stylesheet"/>
   	<link href="css/table.css" type="text/css" rel="stylesheet"/>
  </head>
  <body>
  	<form action="/HomeworkSystem/ActionServlet?method=save&entity=User" method="post">
	  	<div id="user_top">
	  		人员信息更新
	  	</div><!-- user_top end -->
	  	<div id="user_mid">
	  		<table class="table_theme1">
	  			<tr>
	  				<td>姓名:</td>
	  				<td>
	  					<input type="text" name="userName" value="${editEntity.userName}"/>
	  					<input type="hidden" name="hiddenId" value="${editEntity.userId}"/>
	  				</td>
	  			</tr>
	  			<tr>
	  				<td>角色:</td>
	  				<td>
		  				<select name="userRole"><!-- 编辑情况下,默认显示编辑用户的角色的功能,待后续优化项目时再讲如何实现 -->
		  					<option value="1">校长</option>
		  					<option value="2">老师</option>
		  					<option value="3">学生</option>
		  				</select>
	  				</td>
	  			</tr>
	  		</table>
	  	</div><!-- user_mid end -->
	  	<div id="user_bottom">
			<input type="submit" value="保存"></input>
	  	</div><!-- "user_bottom" end -->
	  </form>
  </body>
</html>

最后总结一下子,因为有了通用的CRUD后端,我们每次添加一个实体(比如课程、人员、角色等等)的增删改查功能时,只需要建立两个网页xxxManage.jsp和xxxUpdate.jsp,并按照规则修改里面的链接和具体信息(每种实体内容不同),然后在ActionServlet的
doSaveAction方法里添加新的if分支以保存新类型的实体就行了。

怎么感觉一下子就简单了呢,这样的一个通用CRUD后端设计合理吗,能实现所有功能吗,易拓展吗?这个问题留待下篇分解。

你可能感兴趣的:(Java----实战)