继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

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

程序员大阳
关注TA
已关注
手记 357
粉丝 1.5万
获赞 1523

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

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

a,登录成功后
图片描述
b,点击人员管理后
图片描述
c,点击人员编码7右边对应的删除后
图片描述
d,点击人员编码2右边对应的编辑后
图片描述
e,点击保存后
图片描述

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" %><!-- 使用c:标签需要添加本行代码 -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>   
    <title>index.jsp</title>
    <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><!-- top部分是标题栏 -->
        <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><!-- left部分是菜单栏 -->
        <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><!-- right部分是具体内容显示区 -->
    </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后端设计合理吗,能实现所有功能吗,易拓展吗?这个问题留待下篇分解。

打开App,阅读手记
4人推荐
发表评论
随时随地看视频慕课网APP