员工绩效管理系统(超级超级详细 -

员工绩效管理系统(超级超级详细  -

一.分级建立项目包
    1.建立department包(实现有关department表的操作)
          ① 建立dao包(实现数据库中department的增删改查操作  建立java和数据库直接的联系)
                (1)添加记录
          (2)根据主键删除
          (3)根据查询条件删除
          (4)根据主键修改其它全部字段
          (5)根据主键修改部分其他字段
          (6)根据多条件模糊查询记录
          (7)根据主键查询一条记录
 
          ② 建立model包(创建有关department实体类)
          ③ 建立service包
          ④ 建立servlet包
  2.建立employee包(实现有关employee表的操作)
          ① 建立dao包(实现数据库中employee的增删改查操作  建立java和数据库直接的联系)
                (1)添加记录
          (2)根据主键删除
          (3)根据查询条件删除
          (4)根据主键修改其它全部字段
          (5)根据主键修改部分其他字段
          (6)根据多条件模糊查询记录
          (7)根据主键查询一条记录
          ② 建立model包(创建有关employee实体类)
          ③ 建立service包
          ④ 建立servlet包
  3.建立project包(实现有关project表的操作)
          ① 建立dao包(实现数据库中project的增删改查操作  建立java和数据库直接的联系)
                 (1)添加记录
          (2)根据主键删除
          (3)根据查询条件删除
          (4)根据主键修改其它全部字段
          (5)根据主键修改部分其他字段
          (6)根据多条件模糊查询记录
          (7)根据主键查询一条记录
          ② 建立model包(创建有关project实体类)
          ③ 建立service包
          ④ 建立servlet包
  4.建立score包(实现有关score表的操作)
          ① 建立dao包(实现数据库中score的增删改查操作  建立java和数据库直接的联系)
                 (1)添加记录
          (2)根据主键删除
          (3)根据查询条件删除
          (4)根据主键修改其它全部字段
          (5)根据主键修改部分其他字段
          (6)根据多条件模糊查询记录
          (7)根据主键查询一条记录
          ② 建立model包(创建有关score实体类)
          ③ 建立service包
          ④ 建立servlet包
 5.建立until 工具包(封装工具类简化代码)
          ① 建立JDBCUtil工具类(数据库加载、数据库连接、数据库操作、数据库关闭、)
          ② 建立FmtEmpty(判空)
          ③ 建立jdbc 配置文件
 6.建立init 工具包(封装工具类简化代码)
          ① 建立CharFilter工具类(解决数据库中文乱码的问题)
二、 整个系统的交互过程(开发流程)
    ①建立工具类
        (1)hedaer  封装路径(java代码获取、EL表达式获取)
    ②创建注册界面(reg.jsp)  css(base.css -- window样式)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<!-- <meta charset="UTF-8"> -->
<title>注册页面</title>
<!-- <link rel="stylesheet"  href="/demo220111/web/base/layui/css/layui.css" > -->
<!-- <script type="text/javascript"  src="/demo220111/web/base/layui/layui.js" ></script> -->
<!-- 利用包含来简化代码(工具类) -->
<%@ include file="/web/header.jsp" %>
</head>
<body >
<div class="window">
     <fieldset class="layui-elem-field" >
       <legend>注册</legend>
       <div class="layui-field-box">
         <form class="layui-form layui-form-pane" >
           <div class="layui-form-item">
                      <label class="layui-form-label">账号</label>
                 <div class="layui-input-inline">
                     <input type="text" name="code" required   lay-verify="required"
                           placeholder="请输入账号"  autocomplete="off" class="layui-input">
                      </div>
                </div>
                <div class="layui-form-item">
                      <label class="layui-form-label">密码</label>
                 <div class="layui-input-inline">
                     <input type="password" name="pass"  required  lay-verify="required"
                           placeholder="请输入密码"  autocomplete="off" class="layui-input">
                      </div>
                </div>
                <div class="layui-form-item">
                      <label class="layui-form-label">姓名</label>
                 <div class="layui-input-inline">
                     <input type="text" name="name" required   lay-verify="required"
                           placeholder="请输入姓名"  autocomplete="off" class="layui-input">
                      </div>
                </div>
                <div class="layui-form-item">
                 <div class="layui-input-inline">
                     <input type="button" value="注册"  class="layui-btn" lay-submit lay-filter="reg" >
                         <input type="reset" value="重置"  class="layui-btn layui-btn-primary">
                      </div>
                      <input type="button" value="返回登录"  class="layui-btn" onclick="">
                </div>
                    <!-- reg是传递给EmployeeServlet 参数 -->
                <input type="hidden" name="action" value="reg" >
         </form>
       </div>
     </fieldset>
     
</div>
<script type="text/javascript">
var form = layui.form;
var $ = layui.jquery;
var layer = layui.layer;
form.on("submit(reg)",function(data){
     //layer.msg("1111");
     console.log(data.field)
     $.ajax({//四个属性一个方法
           url : base.app +"/EmployeeServlet",
           type : "post",
           data : data.field, //a=b&c=d /{a:b,c:d}
           dataType : "text",//text / json
           success : function(data){
                console.log(data)
                // todo
           }
     });
});
</script>
     
</body>
</html>
        (1) <input type="button" value="注册" class="layui-btn" lay-submit lay-filter="reg" >  输入框不能为空
触发回调方法(测试段)
var form = layui.form;
var layer = layui.layer;
form.on("submit(reg)",function(data){
     layer.msg("1111");
});
 
    (2)注册页面请求,是请求到employee表中,注册员工信息
触发回调方法(应用段)
<script type="text/javascript">
var form = layui.form;
var $ = layui.jquery;
var layer = layui.layer;
form.on("submit(reg)",function(data){
     //layer.msg("1111");
     console.log(data.field)
     $.ajax({//四个属性一个方法
           url:"",
           data:"",
           type:"",
           dataType:"",
           success:function(data){
                
           }
     });
});
</script>
 
    (3)编写EmployeeServlet类中的方法 (接受请求、获取数据、封装对象、调用方法、返回结果)
        注解@WebServlet("/EmployeeServlet")
       
实现ajax请求交互
private static final long serialVersionUID =1L;
     
     @Override
     protected void doGet(HttpServletRequest req,  HttpServletResponse resp) throws ServletException, IOException {
           doPost(req, resp);
     }
     
        @Override
     protected void doPost(HttpServletRequest req,  HttpServletResponse resp) throws ServletException, IOException {
           String res = null;
           switch (req.getParameter("action")) {
                case "reg":
                     res = reg(req);
                     break;
           }
           // ajax 请求接收
           PrintWriter writer = resp.getWriter();
           writer.write(res);
           writer.flush();
           writer.close();
           writer = null ;
     }
     private String reg(HttpServletRequest req) {
           String code = req.getParameter("code");
           String pass = req.getParameter("pass");
           String name = req.getParameter("name");
           
           EmployeeModel model = new  EmployeeModel(code,name,pass);
           return service.insert(model);
     }
 
(4) 实现员工注册功能(主要测试能否交互)
 
(5) 完善员工注册功能(主要完善业务逻辑)
PS:
     private static String table = "employee";
     private static String cols =  "code,name,pass,code_dept,image";
     // 此处的数据库表字段 在方法中可以不使用某一个,但是不能在方法中使用没有的表字段
    1.reg.jsp 文件
form.on("submit(reg)",function(data){
     //layer.msg("1111");
     //console.log(data.field)
     $.ajax({//四个属性一个方法
           url : base.app +"/EmployeeServlet",
           type : "post",
           data : data.field, //a=b&c=d /{a:b,c:d}
           dataType : "text",//text / json
           success : function(data){
                // console.log(data)  测试ajax请求是否可用
                // todo
                if(data==1){
                     layer.msg("注册成功")
                }else if(data == "repeat"){
                     layer.msg("注册失败,账号重复")
                }else{
                     layer.msg("注册失败")
                }
           }
     });
});
    2.EmployeeServiceImpl 文件
public String insert(EmployeeModel model) {
           // return dao.insert(model) + "";  测试能否实现交互
           
           // 完善业务逻辑
           // 在EmployeeModel 创建code构造方法
           EmployeeModel m1 = new  EmployeeModel(model.getCode());
           EmployeeModel mdb = dao.selectModel(m1);
           if (mdb != null)
                return "repeat";
           return dao.insert(model) + "";
           }
    3.EmployeeModel  创建code 构造方法
public EmployeeModel(String code) {
           super();
           this.code = code;
     }
      4.给reg.jsp 页面添加交互操作(判断注册是否成功)
var form = layui.form;
var $ = layui.jquery;
var layer = layui.layer;
form.on("submit(reg)",function(data){
     //layer.msg("1111");
     //console.log(data.field)
     $.ajax({//四个属性一个方法
           url : base.app +"/EmployeeServlet",
           type : "post",
           data : data.field, //a=b&c=d /{a:b,c:d}
           dataType:"text",//text / json
           success : function(data){
                //console.log(data)  //测试ajax请求是否可用
                // todo
                if(data==1){
                     layer.msg("注册成功")
                }else if(data=="repeat"){
                     layer.msg("注册失败,账号重复")
                }else{
                     layer.msg("注册失败")
                }
           }
           error:function(){// 异常处理
                alert("注册失败,账号重复");
           }
     });
});
5.使用工具类来简化reg.jsp 页面添加操作的代码
header.jsp (将引用路径进行封装)
<!-- java代码 获取工程名 -->
<% String app=request.getContextPath(); %>
<meta charset="UTF-8">
<link rel="stylesheet" href="<%=app %>/web/base/css/base.css" >
<link rel="stylesheet" href="<%=app  %>/web/base/layui/css/layui.css" >
<script type="text/javascript" src="<%=app  %>/web/base/layui/layui.js" ></script>
<!-- EL表达式 获取工程名 -->
<script>
var base={
           app:"${pageContext.request.contextPath}"
           
}
</script>
<script type="text/javascript" src="<%=app  %>/web/base/js/base.js"></script>
 
 
base.js 工具类(将操作方法进行封装)
var form = layui.form;
var $ = layui.jquery;
var layer = layui.layer;
// 添加监听
function formSubmit(event,url,dataType,func){
     //console.log(event) 调试
     form.on("submit(" +event+")",function(data){
     //   console.log(data.field)调试
           ajax(url,data.field,dataType,func)
     })
}
function ajax(url,field,dataType,func){
     //console.log(field)
     $.ajax({//四个属性一个方法
           url : base.app + url,
           type : "post",
           data : field,
           dataType : dataType, //后采用
           //dataType : "text",//text / json
           success : func
//         error:function(){// 异常处理
//              alert("注册失败,账号重复");
//         }
           
     });
}
  1. 封装 关于请求的  FmtRequest 类
    
public class FmtRequest {
     
     
     /**
      * 根据传过来的所有参数得到实体类的对象
      * 根据请求的参数情况反射实体类的对象   (请求的参数名与实体类的属性名一致 ,并且一个参数名对应一个参数值 )
      *
      * @param <T> 反射
      * @param req
      * @param clazz
      * @return
      */
     public static <T> T parseModel(HttpServletRequest  req,Class<T> clazz) {
           T obj = null;
           try {
                obj = clazz.newInstance();
           } catch (InstantiationException |  IllegalAccessException e) {
                e.printStackTrace();
                return null;
           }
           Map<String, String[]> map = req.getParameterMap(); //  传过来的所有参数
           for (Entry<String, String[]> entry : map.entrySet())  {
                String name = entry.getKey();
                if("action".equals(name))
                     continue;
                try {
                     Field field =  clazz.getDeclaredField(name);
                     field.setAccessible(true);
                     field.set(obj,entry.getValue()[0]);
                } catch (NoSuchFieldError | SecurityException |  NoSuchFieldException | IllegalArgumentException |  IllegalAccessException e) {
                     e.printStackTrace();
                }
           }
           
           return obj;
     }
     
     
     /**
      * 根据所传过来的映射关系得到实体类对象
      * 根据映射关系反射得到实体类的对象
      *
      * @param <T>
      * @param req
      * @param clazz
      * @param fields key=属性名   value=参数名
      */
     private static <T> T parseModel(HttpServletRequest  req,Class<T> clazz,Map<String,String> fields) {
           T obj = null;
           try {
                obj = clazz.newInstance();
           } catch (InstantiationException |  IllegalAccessException e) {
                e.printStackTrace();
                return null;
           }
           for (Entry<String, String> entry : fields.entrySet())  { // 根据所传过来的映射关系
                String name = entry.getKey();  // 得到实体类的属性名
                String val =req.getParameter(entry.getValue());   // 得到实体类的参数名
                try {
                     Field field =  clazz.getDeclaredField(name);
                     field.setAccessible(true);
                     field.set(obj,val);
                } catch (NoSuchFieldError | SecurityException |  NoSuchFieldException | IllegalArgumentException |  IllegalAccessException e) {
                     e.printStackTrace();
                }
           }
           
           return obj;
     }
     
     
     
     /**
      * 将 ajax 请求进行封装
      * @param wr
      * @param val
      */
     public static void write(Writer wr,String val) {
           try {
                wr.write(val);
                wr.close();
                wr.flush();
           } catch (IOException e) {
                e.printStackTrace();
           }
           wr = null;
           
     }
}
            7.通过应用FmtRequest 类 简化EmployeeServlet中的代码
简化EmployeeServlet中的代码
private String reg(HttpServletRequest req) {
           //String code = req.getParameter("code");
           //String pass = req.getParameter("pass");
           //String name = req.getParameter("name");
           //EmployeeModel model = new  EmployeeModel(code,name,pass);
           //return service.insert(model);
           
           // 利用FmtRequest类中 parseModel方法进行简化
           // 将请求当中的参数得到,映射到对应的实体类中。
           EmployeeModel model =  FmtRequest.parseModel(req,EmployeeModel.class);
           return service.insert(model);
     
(6) 实现员工登录功能(主要完善业务逻辑)
<input type="button" value="登录" class="layui-btn" lay-submit  lay-filter="login" > 这里的login 决定了对应的js代码怎么实现
 
<input type="hidden" name="action" value="login" > 这里的login 决定了servlet文件中的分支怎么实现
            1. 创建登录界面
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<!-- <meta charset="UTF-8"> -->
<title>登录页面</title>
<!-- <link rel="stylesheet"  href="/demo220111/web/base/layui/css/layui.css" > -->
<!-- <script type="text/javascript"  src="/demo220111/web/base/layui/layui.js" ></script> -->
<!-- 利用包含来简化代码(工具类) -->
<%@ include file="/web/header.jsp" %>
</head>
<body >
<div class="window" >
     <fieldset class="layui-elem-field" >
       <legend>注册</legend>
       <div class="layui-field-box">
         <form class="layui-form layui-form-pane" >
           <div class="layui-form-item">
                      <label class="layui-form-label">账号</label>
                 <div class="layui-input-inline">
                     <input type="text" name="code" required   lay-verify="required"
                           placeholder="请输入账号"  autocomplete="off" class="layui-input">
                      </div>
                </div>
                <div class="layui-form-item">
                      <label class="layui-form-label">密码</label>
                 <div class="layui-input-inline">
                     <input type="password" name="pass"  required  lay-verify="required"
                           placeholder="请输入密码"  autocomplete="off" class="layui-input">
                      </div>
                </div>
                <div class="layui-form-item">
                 <div class="layui-input-inline">
                     <input type="button" value="登录"  class="layui-btn" lay-submit lay-filter="login" >
                         <input type="reset" value="重置"  class="layui-btn layui-btn-primary">
                      </div>
                      <input type="button" value="返回注册"  class="layui-btn" onclick="">
                </div>
<!--                 reg是传递给EmployeeServlet 参数 -->
                <input type="hidden" name="action" value="login"  >
         </form>
       </div>
     </fieldset>
     
</div>
<script type="text/javascript">
调用servlet中的分支 
formSubmit("login","/EmployeeServlet","text",function(data){//console.log(data)
     if(data==1){
           layer.msg("登录成功")
     }else if(data=="repeat"){
           layer.msg("登录失败,账号重复")
     }else{
           layer.msg("登录失败")
     }
})
</script>
</body>
</html>
          2. 在servlet中 建立分支  
一、 创建login分支 (1)
 @Override
     protected void doPost(HttpServletRequest req,  HttpServletResponse resp) throws ServletException, IOException {
           String res = null;
           switch (req.getParameter("action")) {
                case "reg":
                     res = reg(req);
                     break;
                case "login":
                     res = login(req);
                     break;
           }
           // ajax 请求接收
           // 利用FmtRequest 工具类中write方法进行简化
           FmtRequest.write(resp.getWriter(), res);
           
     }
 
二、生成对应的 login 方法(2)
     private String login(HttpServletRequest req) {
           EmployeeModel model =  FmtRequest.parseModel(req,EmployeeModel.class);
           String res = service.login(model);
           return null;
     }
 
实现后(7)
     private String login(HttpServletRequest req) {
           EmployeeModel model = FmtRequest.parseModel(req,  EmployeeModel.class);
           String res = service.login(model); // res 就是EmployeeServiceImpl中 login方法中的 0、1、2
           if ("1".equals(res)) {
                req.getSession().setAttribute("user",  service.selectModel(model));
           }
           return res;
     }
                3.先在IEmployeeService接口中创建用于登录的方法
参考文章地址:https://blog.csdn.net/lemo_ice/article/details/100690860?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_title~default-0.pc_relevant_paycolumn_v2&spm=1001.2101.3001.4242.1&utm_relevant_index=3
用到了抽象类的注入 --暂不确定 自己理解的
小明有添加的功能 可以通过接口实现小明拥有按人名添加的功能
小红有添加的功能 可以通过接口实现小明拥有按id添加的功能
 
IEmployeeService类(3)
 
String login(EmployeeModel model);
 
实现后(6)
/**
      * 登录功能
      *
      * @param model
      * @return String 0=账号不存在   1=登录成功   2=密码错误
      */
     String login(EmployeeModel model);
            4.IEmployeeService接口新加了login方法它的实现类(EmployeeServiceImp)也需要对添加方法进行实现(重写)
EmployeeServiceImpl类 (4)
@Override
     public String login(EmployeeModel model) {
           // TODO Auto-generated method stub
           return null;
     }
 
实现后:(5)
@Override
     public String login(EmployeeModel model) {
           EmployeeModel mdb = selectModel(model);
           if (mdb == null)
                return "0";
           String pass = MD5.encode(model.getPass());
           return mdb.getPass().equals(pass) ? "1" : "2";
     }
            5. 将密码MD5加密(此处在service中加密MD5)
将注册后加密结果和登录时加密结果进行比较判断是否正确
注册加码
@Override
     public String insert(EmployeeModel model) {
           // return dao.insert(model) + "";  测试能否实现交互
     
           // 完善业务逻辑
           // 在EmployeeModel 创建code构造方法
           EmployeeModel m1 = new  EmployeeModel(model.getCode());
           EmployeeModel mdb = dao.selectModel(m1);
           if (mdb != null)
                return "repeat";
           model.setPass(MD5.encode(model.getPass()));
           return dao.insert(model) + "";  
     }
登录加密
@Override
     public String login(EmployeeModel model) {
           EmployeeModel mdb = selectModel(model);
           if (mdb == null)
                return "0";
           String pass = MD5.encode(model.getPass());
           return mdb.getPass().equals(pass) ? "1" : "2";
     }
    6.在登录界面添加跳转注册界面,在注册界面添加跳转登录界面
注册界面跳转登录界面    
html:
<input type="button" value="返回登录" class="layui-btn"  onclick="toHref()">
 
javascript
function toHref(){
     location.href = base.app + "/web/login.jsp";
}
 
登录界面跳转注册界面
html:
<input type="button" value="返回注册" class="layui-btn"  onclick="toHref()">
 
 
javascript
function toHref(){
     location.href = base.app + "/web/reg.jsp";
}
 
简化代码
在base.js 文件中添加
function toHref(url){
     location.href = base.app + url;
}
修改注册界面代码
<input type="button" value="返回注册" class="layui-btn"  onclick="toHref("/web/reg.jsp")">
修改登录界面代码
<input type="button" value="返回登录" class="layui-btn"  onclick="toHref("/web/login.jsp")">
(7) 实现主界面功能
    1.创建page文件夹(登录之后的操作 --- 防盗链)      2.从登录界面跳转 (layui 弹出层)
formSubmit("login","/EmployeeServlet","text",function(data){//console.log(data)
     if(data == 1){
           layer.msg("登录成功哦!!!",{time:1000},function(){
                toHref("/web/page/main.jsp")
           })
     }else if(data == 2){
           layer.msg("登录失败,密码错误!!!")
     }else if(data == 0){
           layer.msg("登录失败,账号不存在!!!")
     }
})
            3.创建主界面(layui)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<%@ include file="/web/header.jsp" %>
<meta charset="UTF-8">
<title>主界面</title>
</head>
<body>
<body>
<div class="layui-layout layui-layout-admin">
  <div class="layui-header">
    <div class="layui-logo layui-hide-xs layui-bg-black">员工绩效管理系统</div>
    <!-- 头部区域(可配合layui 已有的水平导航) -->
    <ul class="layui-nav layui-layout-left">
      <!-- 移动端显示 -->
      <li class="layui-nav-item layui-show-xs-inline-block  layui-hide-sm" lay-header-event="menuLeft">
        <i class="layui-icon layui-icon-spread-left"></i>
      </li>
      
      <li class="layui-nav-item layui-hide-xs"><a href="">部门信息</a></li>
      <li class="layui-nav-item layui-hide-xs"><a href="">员工信息</a></li>
      <li class="layui-nav-item layui-hide-xs"><a href="">项目信息</a></li>
      <li class="layui-nav-item">
        <a href="javascript:;">绩效信息</a>
        <dl class="layui-nav-child">
          <dd><a href="">menu 11</a></dd>
          <dd><a href="">menu 22</a></dd>
          <dd><a href="">menu 33</a></dd>
        </dl>
      </li>
    </ul>
    <ul class="layui-nav layui-layout-right">
      <li class="layui-nav-item layui-hide  layui-show-md-inline-block">
        <a href="javascript:;">
          <img src="<%=app %>/web/base/img/1.jpeg"  class="layui-nav-img">
            用户&nbsp[&nbsp&nbsp&nbsp${user.name}&nbsp&nbsp&nbsp]
        </a>
        <dl class="layui-nav-child">
          <dd><a href="">修改个人资料</a></dd>
          <dd><a href="">修改个人密码</a></dd>
          <dd><a href="">修改个人博客</a></dd>
        </dl>
      </li>
      <li class="layui-nav-item" lay-header-event="menuRight"  lay-unselect>
        <a href="javascript:;">
          <i class="layui-icon layui-icon-more-vertical"></i>
        </a>
      </li>
    </ul>
  </div>
  
  <div class="layui-side layui-bg-black">
    <div class="layui-side-scroll">
      <!-- 左侧导航区域(可配合layui已有的垂直导航) -->
      <ul class="layui-nav layui-nav-tree" lay-filter="test">
        <li class="layui-nav-item layui-nav-itemed">
          <a class="" href="javascript:;">信息维护</a>
          <dl class="layui-nav-child">
            <dd><a href="javascript:;"  data-url="/web/page/department/list.jsp"  class="site-demo-active">部门信息维护</a></dd>
            <dd><a href="javascript:;"  data-url="/web/page/employee/list.jsp"  class="site-demo-active">员工信息维护</a></dd>
            <dd><a href="javascript:;"  data-url="/web/page/employee/list.jsp"  class="site-demo-active">项目信息维护</a></dd>
            <dd><a href="javascript:;"  data-url="/web/page/department/list.jsp">绩效信息维护</a></dd>
          </dl>
        </li>
        <li class="layui-nav-item">
          <a href="javascript:;">menu group 2</a>
          <dl class="layui-nav-child">
<!--             实现打开网页显示主体网页 -->
            <dd><a  href="javascript:openurl("/web/page/department/list.jsp");">list  1</a></dd>
            <dd><a href="javascript:;">list 2</a></dd>
            <dd><a href="">超链接</a></dd>
          </dl>
        </li>
      </ul>
    </div>
  </div>
  
  <div class="layui-body">
    <!-- 内容主体区域 -->
    <iframe name="framA" width="99%" height="97%"></iframe>
  </div>
  
  <div class="layui-footer">
    <!-- 底部固定区域 -->
      有问题请联系我们!0000-0000000
  </div>
</div>
<script type="text/javascript">
//JS
// 使用 H5(jQuery) 提供的 data-url实现打开后显示主体网页     data-url="/web/page/department/list.jsp"
$(".site-demo-active").click(function(){
     window.open(base.app + $(this).data("url"),"framA")
})
$(".site-demo-active").click() // 默认打开第一个
// <!--               实现打开网页显示主体网页 -->
function openurl(url){
     window.open(base.app + url,"framA")
}
</script>
</body>
</body>
</html>
4.主界面退出操作 (layui)
    (1).mian.jsp
html
<li class="layui-nav-item">
           <a href="javascript:toLogout()">退出</a>
</li>
 
js
function toLogout(){
     layerConfirm(function(){
           toHref("/EmployeeServlet?action=logout")
     },"您确定要离开了吗?")
}
 
base.js
function layerConfirm(func,title){
     layer.confirm(title ? title : "确定要进行该操作?",{
           icon:3,
           title:"提示"
     },func)
}
        (2). EmployeeServlet 实现分支
     case "logout":
                req.getSession().removeAttribute("user");
                resp.sendRedirect(req.getContextPath()+"/web/login.jsp");
                break;
 
5.防盗链的功能 (UserFilter类来实现,用户退出后或未登录情况下,无法访问page文件下的界面)
@WebFilter(urlPatterns =  {"/web/page/*","/EmployeeServlet","/DepartmentServlet","/ProjectServlet","/ScoreServlet"})
public class UserFilter implements Filter { // 防盗链  确认当前地址栏用户是否登录
     @Override
     public void doFilter(ServletRequest request,  ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
           HttpServletRequest req = (HttpServletRequest)  request;
           String action = req.getParameter("action");
           if("reg".equals(action)||"login".equals(action)) { //  将 注册请求和登录请求单独放行
                chain.doFilter(request, response);
                return;
           }
            Object user = req.getSession().getAttribute("user");
            if (user == null) {
                req.getRequestDispatcher("/web/login.jsp").forward(request,  response);// 进行页面跳转(请求转发)
           } else
                chain.doFilter(request, response);
     }
     
}
  6.  右侧边栏 操作展示功能
html
<li class="layui-nav-item" lay-header-event="menuRight"  lay-unselect>
        <a href="javascript:openRight();">请求处理
          <i class="layui-icon layui-icon-more-vertical"></i>
        </a> 
</li>
 
js
function openRight(){
     layer.open({
           type:1
           ,content:"<div >处理右侧面板的操作</div>"
           ,area:["260px","100%"]
           ,offset:"rt"//右上角
           ,anim:5
           ,shadeClose:true
     });
}
7.主界面主体查询操作部分(layui 面板)
        (1)html 操作代码
面板上半部分 html:
<div class="layui-collapse">
  <div class="layui-colla-item">
    <h2 class="layui-colla-title" >部门信息--查询条件</h2>
    <div class="layui-colla-content layui-show">
        
         <fieldset class="layui-elem-field layui-field-title"  >
             <legend>部门信息--查询条件</legend>
             <div class="layui-field-box">
               <form class="layui-form" >
                 <div class="layui-form-item">
                            <label class="layui-form-label">编号</label>
                       <div class="layui-input-inline">
                           <input type="text" name="code" placeholder="请输入编号"  autocomplete="off" class="layui-input ">
                            </div>
                            <label class="layui-form-label">名称</label>
                       <div class="layui-input-inline">
                           <input type="text" name="name"  placeholder="请输入名称" autocomplete="off" class="layui-input ">
                            </div>
                             &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                            <span>
                                <input type="button" value="查询" class="layui-btn layui-btn-sm" lay-submit lay-filter="search"  >
                               <input type="reset" value="重置"  class="layui-btn layui-btn-sm layui-btn-primary">
                                <input type="button" value="添加" class="layui-btn layui-btn-sm" lay-submit lay-filter="search"  >
                            </span>
                      </div>
<!--                 reg是传递给EmployeeServlet 参数 -->
<!--                  <input type="hidden" name="action"  value="login" > -->
               </form>
             </div>
           </fieldset>
    </div>
  </div>
</div>
 
面板下半部分 HTML:
<!-- 面板下半部分 -->
<table class="layui-table">
<!-- colgroup限制宽度 -->
     <colgroup>
           <col width="10&" ><col width="15%" ><col width="15%"  ><col width="20%" ><col width="40%" >
     </colgroup>
     <thead>
           <tr>
           <th>序号</th><th>编号</th><th>名称</th><th>电话</th><th>操作</th>
           </tr>
     </thead>
     <tbody>
           
     </tbody>
     
</table>
<script type="text/javascript">
// base文件要先在base.js文件中定义出来
// var element =layui.element;
// 折叠面板不好用 记得用渲染
// element.render();
</script>
            (2)JavaScript操作代码
script 实现 部分代码
解释:
//function formSubmit(event,url,dataType,func){
//   //console.log(event) 调试
//   form.on("submit(" +event+")",function(data){
//   //   console.log(data.field)调试
//         ajax(url,data.field,dataType,func)
//   })
//}
// 调用了base.js 文件  取出 查询行中( <input type="button"  value="查询" class="layui-btn layui-btn-sm" lay-submit  lay-filter="search" >)的search
 
//  此处 search是网页查询行的方法   
//  EmployeeServlet是实现业务逻辑的类
//  json  是请求传递的参数类型 以json形式传递
 
formSubmit("search","/EmployeeServlet","json",function(data){})
     formSubmit 类比base.js 文件
        (3)EmployeeServlet中操作代码
one:先继承HttpServlet
public class EmployeeServlet extends HttpServlet {}
 
two:定义程序 序列化ID
public class EmployeeServlet extends HttpServlet {
     private static final long serialVersionUID = 1L;
}
 
three: 创建表单提交数据到服务器的方式
public class EmployeeServlet extends HttpServlet {
     private static final long serialVersionUID = 1L;
        (4) EmployeeServlet中建立业务逻辑分支
@Override
     protected void doPost(HttpServletRequest req,  HttpServletResponse resp) throws ServletException, IOException {
           String res = null;
           switch (req.getParameter("action")) {
           case "list":
                res = list(req);
                break;
           default:
                break;
           }
     }
            list 通过隐藏域(hidden) 来传递到EmployeeServlet中  通过EmployeeServlet 中 "list" 分支来实现表格中数据的加载
lsit.jsp文件
<input type="hidden" name="action" value="list">
           这样就可以实现list分支的方法了
常用套路:
1接受请求、
2获取数据、
3封装对象、
4调用方法、
5返回结果
 
1接受请求、
 String conextPath = req.getContextPath();
 String path1 = "/web/success.jsp";
2获取数据、
DepartmentModel model2 = new DepartmentModel();
     req.getParameter("code");
     req.getParameter("name");
    可以利用工具类简化
  // 将所有请求的参数映射到实体类中
     DepartmentModel model =FmtRequest.parseModel(req,  DepartmentModel.class);    
          return null;
 
1和2 利用工具类简化后:
     private String list(HttpServletRequest req) {
       // 将所有请求的参数映射到实体类中
       DepartmentModel model =FmtRequest.parseModel(req,  DepartmentModel.class);    
         return null;
     }
 
3封装对象(1)、
    在接口(IDepartmentService)中定义方法(至少有这五个)
 public interface IDepartmentService {
     String insert(DepartmentModel model);
     String delete(DepartmentModel model);
     String update(DepartmentModel model);
     List<DepartmentModel> selectList(DepartmentModel model);
     DepartmentModel selectModel(DepartmentModel model);
}
3封装对象(2)、
    在实现类中(EmployeeServiceImpl)重写方法 ,根据对应的方法去数据库里查找
        初始版本
public class DepartmentServiceImpl  implements  IDepartmentService{
     private IDepartmentDao dao2  = new Department2DaoImpl();
     
     
     @Override
     public String insert(DepartmentModel model) {
           return dao2.Insert(model)+"";
     }
     @Override
     public String delete(DepartmentModel model) {
           return dao2.delete(model)+"";
     }
     @Override
     public String update(DepartmentModel model) {
           return dao2.updateActive(model)+"";
     }
     @Override
     public List<DepartmentModel> selectList(DepartmentModel  model) {
           return dao2.selectList(model);
     }
     @Override
     public DepartmentModel selectModel(DepartmentModel model)  {
           return dao2.selectModel(model);
     }
     
     简单实现查询方法
    @Override
     public List<DepartmentModel> selectList(DepartmentModel  model) {
           String code = model.getCode();
           model.setCode(code == null ? "%" : "%" + code + "%");
           String name = model.getName();
           model.setName(name == null ? "%" : "%" + name + "%");
           return dao2.selectList(model);
     }
    
4调用方法(通过调用IDepartmentService接口来调用实现方法)
    List<DepartmentModel> selectList(DepartmentModel model);
 
5返回结果
    private String list(HttpServletRequest req) {
        // 将所有请求的参数映射到实体类中
        DepartmentModel model =FmtRequest.parseModel(req,  DepartmentModel.class);    
        // service.selectList(model)  返回的是集合
        List<DepartmentModel> list =  service.selectList(model);
        return null;
     }
    简化后:
    private List<DepartmentModel> list(HttpServletRequest req) {
      // 将所有请求的参数映射到实体类中
         DepartmentModel model =FmtRequest.parseModel(req,  DepartmentModel.class);    
         // service.selectList(model)  返回的是集合
         return service.selectList(model);
     }
    
    这里由于返回的是集合 就不能用字符串接收了 就需要 将doPost中的String类型的res 修改为Object型来接收(DepartmentServlet文件下
       @Override
     protected void doPost(HttpServletRequest req,  HttpServletResponse resp) throws ServletException, IOException {
           Object res = null;
           switch (req.getParameter("action")) {
           case "list":
                res = list(req);
                break;
           default:
                break;
           }
            FmtRequest.write(resp.getWriter(), res); 
            // 难点:这里重写了FmtRequest工具类中的write方法
     }
 
至此完成一个 从 网页到 java 再从java到数据库  再数据库返回到java 最后从Java(传递)展示在网页上
FmtRequest工具类中的write方法重写代码为:
public static void write(Writer wr,Object val) {
           if (val instanceof Collection<?>) { // 判断对象是否为线性集合
                write(wr, new  JSONArray((Collection<?>)val).toString());
                //传进去的线性集合,在传过来的时候进行向下转型(var 是Object类型 最大了),
                //转型完之后传递到JSONArray当中在调用toString方法得到json格式的字符串,
                //将json格式的字符串再传递给write方法,再写回给网页。
           } else if(val instanceof String){ // 判断对象是否为字符串
                write(wr, val.toString());
           }else if (val instanceof Map<?, ?>) { // 判断对象是否为map集合
                write(wr, new  JSONObject((Map<?,?>)val).toString());
           }else {// 判断是否为(其它对象)实体类
                write(wr, new JSONObject(val).toString());
           }
           
     }
            (5) 完善javascript 功能
1 .
base.js 文件添加
var laytpl = layui.laytpl;
 
list.js文件
element.render();
formSubmit("search","/DepartmentServlet","json",function(data){
//    console.log(data)
      var html = "";
      var tpl = $("#tradd").html();
        $.方法  别忘了加 $.
      $.each(data , function(i,dom){
            var d =  {id:i,code:dom.code,name:dom.name,tel:dom.tel}
            html += laytpl(tpl).render(d);
      })
      $("tbody").html(html);
})
 
2.(只包含紫色部分)
//  实现一开的主体界面 不用点查询 就可以显示数据,为后续的添加操作和 删除操作奠基(相当于刷新吧)
function refresh(){
     $("input[value="重置" ]").click();
     $("input[value="查询" ]").click();
}refresh();
 
</script>
<!-- 定义模板引擎 -->
<script type="text/html" id="tradd">
<tr>
     <td>{{d.id}}</td><td>{{d.code}}</td><td>{{d.name}}</td><td>{{d.tel}}</td>
     <td>
           <a href="javascript:" class="layui-btn layui-btn-sm" >删除</a>
           <a href="javascript:" class="layui-btn layui-btn-sm" >修改</a>
     </td>
</tr>
</script>
8.主界面主体添加操作部分(弹出层)
        添加(1)在base.js 定义弹出层 方法(主要测试能否弹出 ,一步一步,慢慢来)
// layui 弹出层
function layerOpen(url , end){
     layer.open({
           type : 2,                                  // 弹出窗口的形式
           content : base.app + url,                  // 弹出窗口的内容(路径,将路径上的网页展示在弹出窗口中)
           area : ["650px","450px"],                  // 弹出窗口的大小尺寸
           fixed : false,                             // 弹出窗口的 固定(不可拖动)
           maxmin : true,                             // 弹出窗口的最大化
           shade : 0.3,                               // 弹出窗口的阴影
           closeBtn : 1,                              // 弹出窗口的关闭按钮
           shadeClose : false,                        // 点击遮罩是否关闭
           success : function(layero,index){          //  成功打开后要调用的方法
                
           },
           end : end                                  // 关闭后要调用的方法
                
           
     })
}
       添加   (2)在list.jsp 文件中 添加 静态事件绑定(html中),并且创建add.jap添加跳转后的页面
    <input type="button" value="添加" class="layui-btn layui-btn-sm"  onclick="openAdd()" >
      添加   (3)在list.jsp 文件中 给添加按钮创建跳转方法 
// 实现 一开的主体界面 不用点查询 就可以显示数据   为后续的添加操作和  删除操作奠基(相当于刷新吧)
function refresh(){
     $("input[value="重置" ]").click();
     $("input[value="查询" ]").click();
}refresh();
 
// 定义添加方法
function openAdd(){
     // 测试添加按钮能否弹出
     // layer.msg(123)
     // 调用layerOpen方法
     layerOpen("/web/page/department/add.jsp" , refresh);
}
       关闭 (1) 在base.js文件中 定义关闭方法
// 弹出层关闭
function layerClose(){                                    // 当你在iframe页面关闭自身时
     var index = parent.layer.getFrameIndex(window.name); // 先得到当前iframe层的索引
     parent.layer.close(index);                           // 再执行关闭
}    
        关闭  (2) 在add.js文件中添加关闭的静态事件绑定
<input type="button" value="关闭" class="layui-btn"  onclick="layerClose()" >
         实现数据添加操作    (1)html文件 的操作
首先完善 add.jsp 页面的html代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<%@ include file="/web/header.jsp" %>
<meta charset="UTF-8">
<title>部门添加界面</title>
</head>
<body>
<fieldset class="layui-elem-field" >
       <legend>部门添加界面</legend>
       <div class="layui-field-box">
         <form class="layui-form layui-form-pane" >
           <div class="layui-form-item">
                      <label class="layui-form-label">编号</label>
                 <div class="layui-input-inline">
                     <input type="text" name="code" required   lay-verify="required"
                           placeholder="请输入编号"  autocomplete="off" class="layui-input">
                      </div>
                </div>
                <div class="layui-form-item">
                      <label class="layui-form-label">名称</label>
                 <div class="layui-input-inline">
                     <input type="text" name="name" required   lay-verify="required"
                           placeholder="请输入名称"  autocomplete="off" class="layui-input">
                      </div>
                </div>
                <div class="layui-form-item">
                      <label class="layui-form-label">电话</label>
                 <div class="layui-input-inline">
                     <input type="text" name="tel" required   lay-verify="required"
                           placeholder="请输入联系方式"  autocomplete="off" class="layui-input">
                      </div>
                </div>
                <div class="layui-form-item">
                 <div class="layui-input-black">
                        // 添加动态事件绑定   1
                     <input type="button" value="确定"  class="layui-btn" lay-submit lay-filter="add" >
                         <input type="reset" value="重置"  class="layui-btn layui-btn-primary">
                         <input type="button" value="关闭"  class="layui-btn" onclick="layerClose()" >
                      </div>
                </div>
                <!-- reg是传递给EmployeeServlet 参数 -->
                <input type="hidden" name="action" value="reg" >
         </form>
       </div>
     </fieldset>
     
     
<script type="text/javascript">
// 2 实现添加操作的JavaScript代码
formSubmit("add","/DepartmentServlet","text",function(data){console.log(data)
     if(data==1){
           layer.msg("添加成功",layerClose)
     }else if(data=="repeat"){
           layer.msg("添加失败,编号重复")
     }else{
           layer.msg("添加失败")
     }
})
</script>  
</body>
</html>
 
 
         实现数据添加操作    (2) 在DepartmentServlet类中 定义add 分支和 创建add方法
  1. 定义 add 分支 
  @Override
     protected void doPost(HttpServletRequest req,  HttpServletResponse resp) throws ServletException, IOException {
           Object res = null;
           switch (req.getParameter("action")) {
           case "list":
                res = list(req);
                break;
           case "add":
                res = add(req);
                break;
                
           default:
                break;
           }
           FmtRequest.write(resp.getWriter(), res);
     }
 
2. 创建 add 方法
      /**
      * 定义上述分支中的 add方法
      * @param req
      * @return
      */
     private String add(HttpServletRequest req) {
           DepartmentModel model =FmtRequest.parseModel(req,  DepartmentModel.class);    
           return service.insert(model);
     }
 实现数据添加操作    (3) 去IDepartmentService接口中 定义insert方法
      String insert(DepartmentModel model);
 实现数据添加操作    (4)在DepartmentServiceImpl中  通过接口(IDepartmentService) 重写添加的业务逻辑
DepartmentServiceImpl类中
 
1. 重写insert 业务逻辑
@Override
     public String insert(DepartmentModel model) {
            // 2 和 3 只是为了在这里查询判断时更严谨
           if (selectModel(model) == null) {
                Integer res = dao2.Insert(model);
                return res == null ? null : res.toString();
           }
           return "repeat";
     }
 
2.为了更严谨一点 先在 DepartmentModel  添加code 无参构造方法和有参构造方法
public DepartmentModel() {// 无参构造方法   
     }
     public DepartmentModel(String code) { // 有参构造方法
           this.code = code;
     }
3. 在调用selectModel 方法查询判断 code字段
@Override
     public DepartmentModel selectModel(DepartmentModel model)  {
           return dao2.selectModel(new  DepartmentModel(model.getCode()));
     }
 
实现数据删除操作   (1)在 list.jsp中 实现删除的html代码
<script type="text/html" id="tradd">
<tr>
     <td>{{d.id}}</td><td>{{d.code}}</td><td>{{d.name}}</td><td>{{d.tel}}</td>
     <td>
           <a href="javascript:del("{{d.code}}")"  class="layui-btn layui-btn-sm layui-btn-danger " >
                <i class="layui-icon layui-icon-delete"></i>
           </a>
           <a href="javascript:" class="layui-btn layui-btn-sm"  >修改</a>
     </td>
</tr>
</script>
实现数据删除操作     (2)在 list.jsp中 实现删除的javascrip代码
 
// 定义删除方法
function del(code){
     // 测试方法是否可用  1
     //layer.msg(code)
     layerConfirm(function(index){
           // 测试layerConfirm提示是否可用  2
           // layer.msg(code);
           // 通过调用 base.js 文件的ajax请求 实现删除   注意: code是字段  del 是DepartmentServlet的 del 分支
           ajax("/DepartmentServlet",{code:code,action:"del"})
     })
}
 
// 完善删除方法
function del(code){
     // 测试方法是否可用
     //layer.msg(code)
     layerConfirm(function(index){
           // 测试layerConfirm提示是否可用
           // layer.msg(code);
           ajax("/DepartmentServlet",{code:code,action:"del"},"text",function(data){
                // 测试ajax 调用是否可行
                // console.log(data)
                if(data == 1){
                     layer.msg("删除成功",refresh)
                }else{
                     layer.msg("删除失败")
                }    
           })
     })
}
实现数据删除操作  (3)在DepartmentServlet中创建del 分支 并创建对应的del方法
DepartmentServlet 类中
1. 创建del 分支
     @Override
     protected void doPost(HttpServletRequest req,  HttpServletResponse resp) throws ServletException, IOException {
           Object res = null;
           switch (req.getParameter("action")) {
           case "list":
                res = list(req);
                break;
           case "add":
                res = add(req);
                break;
           case "del":
                res = del(req);
                break;
           default:
                break;
           }
           FmtRequest.write(resp.getWriter(), res);
     }
2. 创建del 方法
private Object del(HttpServletRequest req) {
           return service.delete(FmtRequest.parseModel(req,  DepartmentModel.class));
     }
实现数据删除操作     (4)在IDepartmentService接口中创建del方法
public interface IDepartmentService {
     String insert(DepartmentModel model);
     String delete(DepartmentModel model);
     String update(DepartmentModel model);
     List<DepartmentModel> selectList(DepartmentModel model);
     DepartmentModel selectModel(DepartmentModel model);
}
实现数据删除操作  (5)在IDepartmentServiceImpl中重写del方法
@Override
     public String delete(DepartmentModel model) {
           Integer res = dao2.delete(model);
           return res == null ? null : res.toString();
     }
实现数据删除操作  (6)在IDepartment2DaoImpl中重写del方法
     @Override
     public Integer delete(DepartmentModel model) {
           StringBuffer sql = new StringBuffer(" delete from  department ");
           // 通过使用工具类JDBCUtil 简化 根据查询条件的删除操作代码
           List<Object> values = appendWhere(sql,model); // 这里调用了appendWhere去判断是否对应
           return JDBCUtil1.update(sql.toString(), values);
     }
实现数据删除操作  (7)在IDepartment2DaoImpl中调用了appendWhere去判断是否对应
private List<Object> appendWhere(StringBuffer sql,  DepartmentModel model) {
           sql.append("where 1=1");
           List<Object> values = new ArrayList<>();
           try {
                String code = model.getCode();
                if (!FmtEmpty.isEmpty(code)) {
                     sql.append(" and code like ? ");
                     values.add(code);
                }
                String name = model.getName();
                if (!FmtEmpty.isEmpty(name)) {
                     sql.append(" and name like ? ");
                     values.add(name);
                }
                String tel = model.getTel();
                if (!FmtEmpty.isEmpty(tel)) {
                     sql.append(" and tel like ? ");
                     values.add(tel);
                }
           } catch (Exception e) {
                e.printStackTrace();
           }
           return values;
     }
实现数据删除操作  (8)将结果返回到DepartmentServlet中 的del 方法中去 在回到 分支里面去判断
private Object del(HttpServletRequest req) {
           return service.delete(FmtRequest.parseModel(req,  DepartmentModel.class));
     }
实现数据删除操作  (9)如果 res = del(req)  则在数据库中删除成功 
@Override
     protected void doPost(HttpServletRequest req,  HttpServletResponse resp) throws ServletException, IOException {
           Object res = null;
           switch (req.getParameter("action")) {
           case "list":
                res = list(req);
                break;
           case "add":
                res = add(req);
                break;
           case "del":
                res = del(req);
                break;
           default:
                break;
           }
           FmtRequest.write(resp.getWriter(), res);
     }
实现数据删除操作  (10)返回到 list.jsp文件中 执行if判断做出相应的提示
// 定义删除方法
function del(code){
     // 测试方法是否可用
     //layer.msg(code)
     layerConfirm(function(index){
           // 测试layerConfirm提示是否可用
           // layer.msg(code);
           ajax("/DepartmentServlet",{code:code,action:"del"},"text",function(data){
                console.log(data)
                if(data == 1){
                     layer.msg("删除成功",refresh)
                }else{
                     layer.msg("删除失败")
                }    
           })
     })
}
ajax请求实现数据修改操作(前半部分 回显)  (1) 在list.jsp 创建修改页面的跳转 方法
1.创建修改按钮
<script type="text/html" id="tradd">
<tr>
     <td>{{d.id}}</td><td>{{d.code}}</td><td>{{d.name}}</td><td>{{d.tel}}</td>
     <td>
           <a href="javascript:del("{{d.code}}")"  class="layui-btn layui-btn-sm layui-btn-danger " >
                <i class="layui-icon layui-icon-delete"></i>
           </a>
          <a href="javascript:openUpd("{{d.code}}")" class="layui-btn  layui-btn-sm" >修改</a>
     </td>
</tr>
</script>
 
2.
// 定义修改方法
function openUpd(code){
     // 通过修改页面的路径 传参数
     layerOpen("/web/page/department/upd.jsp?code="+code ,  refresh);
}
ajax请求实现数据修改操作(前半部分 回显)   (2)  创建修改页面 upd.jsp  获取参数
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<%@ include file="/web/header.jsp" %>
<meta charset="UTF-8">
<title>修改页面</title>
</head>
<body>
<fieldset class="layui-elem-field" >
       <legend>部门修改界面</legend>
       <div class="layui-field-box">
         <form class="layui-form layui-form-pane" >
           <div class="layui-form-item">
                      <label class="layui-form-label">编号</label>
                 <div class="layui-input-inline">
                     <input type="text" name="code" required   lay-verify="required"
                           placeholder="请输入编号"  autocomplete="off" class="layui-input">
                      </div>
                </div>
                <div class="layui-form-item">
                      <label class="layui-form-label">名称</label>
                 <div class="layui-input-inline">
                        <!-- readonly  不可修改 -->
                     <input type="text" name="code" required   lay-verify="required" readonly
                           placeholder="请输入编号"  autocomplete="off" class="layui-input">
                      </div>
                </div>
                <div class="layui-form-item">
                      <label class="layui-form-label">电话</label>
                 <div class="layui-input-inline">
                     <input type="text" name="tel" required   lay-verify="required"
                           placeholder="请输入联系方式"  autocomplete="off" class="layui-input">
                      </div>
                </div>
                <div class="layui-form-item">
                 <div class="layui-input-black">
                     <input type="button" value="确定"  class="layui-btn" lay-submit lay-filter="get" >
                         <input type="reset" value="重置"  class="layui-btn layui-btn-primary">
                         <input type="button" value="关闭"  class="layui-btn" onclick="layerClose()" >
                      </div>
                </div>
                <!-- reg是传递给EmployeeServlet 参数 -->
                <input type="hidden" name="action" value="get" >
         </form>
       </div>
     </fieldset>
<script type="text/javascript">
// 得到传入的参数 code
var code = "<%=request.getParameter("code")%>";
// layer.msg(code)
function init(){
     ajax("/DepartmentServlet",{code:code,action:"get"},"json",function(data){
           console.data(data)
           
     })
}
</script>
</body>
</html>
ajax请求实现数据修改操作(前半部分 回显)   (3)  创建DepartmentServlet 类中的 get 分支 和 get方法
1. 创建get 分支
@Override
     protected void doPost(HttpServletRequest req,  HttpServletResponse resp) throws ServletException, IOException {
           Object res = null;
           switch (req.getParameter("action")) {
           case "list":
                res = list(req);
                break;
           case "add":
                res = add(req);
                break;
           case "del":
                res = del(req);
                break;
           case "get":
                res = get(req);
                break;
           default:
                break;
           }
           FmtRequest.write(resp.getWriter(), res);
     }
2.创建get 方法
     /**
      * 定义上述分支中的 get方法
      * @param req
      * @return
      */
     private DepartmentModel get(HttpServletRequest req) {
           return service.selectModel(FmtRequest.parseModel(req,  DepartmentModel.class));
           
     }
 ajax请求实现数据修改操作(前半部分 回显)   (3)  通过IDepartmentService接口调用DepartmentServiceImpl实现的方法
IDepartmentService接口
     DepartmentModel selectModel(DepartmentModel model);
 
DepartmentServiceImpl实现类
    @Override
         public DepartmentModel selectModel(DepartmentModel model)  {
               return dao2.selectModel(new  DepartmentModel(model.getCode()));
         }
再次通过dao2在调用Department2DaoImpl中的selectModel重写方法
          @Override
     public DepartmentModel selectModel(DepartmentModel model)  {
           StringBuffer sql = new StringBuffer("select  id,code,name,tel from ");
           sql.append(table).append(" where code =? ");
           // 通过使用工具类JDBCUtil 简化根据主键查询一条记录的代码
           List<Object> values = Arrays.asList(model.getCode());
           return JDBCUtil1.queryModel(sql.toString(), values,  DepartmentModel.class);
     }
 ajax请求实现数据修改操作(前半部分 回显)   (4) 将结果返回到 DepartmentServlet中
先返回给  get 方法
 
再返回给 get分支判断 是否 相等  如果相等 将数据以json的形式传回到upd.jsp网页中 执行回显方法
 
ajax请求 实现数据修改操作(前半部分 回显)   (5) 如果分支判断相等 ,就将数据以json的形式传回网页 执行回显方法  完成操作
// 得到传入的参数 code
var code = "<%=request.getParameter("code")%>";
// 测试点击修改是否能得到相应的code
// layer.msg(code)
function init(){
     ajax("/DepartmentServlet",{code:code,action:"get"},"json",function(data){
           console.log(data)
           $("input[name="code"]").val(data.code)
           $("input[name="name"]").val(data.name)
           $("input[name="tel"]").val(data.tel)
           form.val("formA",{code:data.code,name:data.name,tel:data.tel});
     //   form.val("formA",data);
     })
}
// 不调用 init方法 它怎么执行!!!
init();
ajax请求实现数据修改操作(后半部分 更新)       (6) upd.jsp 页面创新 upd 方法
formSubmit("upd","/DepartmentServlet","text",function(data){//console.log(data)
     if(data==1){
           layer.msg("修改成功",layerClose)
     }else{
           layer.msg("修改失败")
     }
})
ajax请求实现数据修改操作(后半部分 更新)       (7) 去DepartmentServlet 文件创建upd 分支 和 upd 执行方法
1. upd 分支  
       case "upd":
            res = upd(req);
            break;     
2. upd 方法
     /**
      * 定义上述分支中的 upd方法  修改的前半部分   更新
      * @param req
      * @return
      */
     private Object upd(HttpServletRequest req) {
           return service.update(FmtRequest.parseModel(req,  DepartmentModel.class));
     }
ajax请求实现数据修改操作(后半部分 更新)       (8) 通过 接口 和实现类 执行 update 方法
1. 先调用IDepartmentService接口
public interface IDepartmentService {
     String update(DepartmentModel model);
}
 
2. 在调用DepartmentServiceImpl实现类重写方法
     @Override
     public String update(DepartmentModel model) {
           return dao2.updateActive(model)+"";
     }
 
3. 调用DepartmentServiceImpl  中的updateActive方法(先调用IDepartmentDao接口)
public interface IDepartmentDao {
    Integer updateActive(DepartmentModel model);
}
 
4. 调用DepartmentServiceImpl  中的updateActive方法(再调用Department2DaoImpl实现类中的updateActive 方法)
public class Department2DaoImpl implements IDepartmentDao {
     @Override
     public Integer updateActive(DepartmentModel model) {
           StringBuffer sql = new StringBuffer("update "); // 字符串的拼接一定要会
           sql.append(table).append(" set id = id ");
           // 通过使用工具类JDBCUtil 简化根据主键修改部分其他字段操作的代码
           List<Object> values = appendSet(sql, model); // 这里又调用了appendSet方法执行后返回
           return JDBCUtil1.update(sql.toString(), values);
     }
 
    private List<Object> appendSet(StringBuffer sql, DepartmentModel  model) { // 定义字符串拼接方法
           List<Object> values = new ArrayList<Object>();
           String name = model.getName();
           if (FmtEmpty.isEmpty(name)) { // 判断有没有对象以及是否为空 str == null || str.trim().isEmpty()
                sql.append(",name=? ");// 字符串的拼接一定要会
                values.add(name);
           }
           String tel = model.getTel();
           if (tel != null) {
                sql.append(" ,tel=? ");// 字符串的拼接一定要会
                values.add(tel);
           }
           sql.append("where code = ? ");
           values.add(model.getCode());
           return values;
     }
}
ajax请求实现数据修改操作(后半部分 更新)       (8) 将 结果再依次返回  并将参数传回到 upd.jsp 文件中 继续执行if 判断 显示相应提示 完成 更新操作。
// 修改的后半部分 更新数据
formSubmit("upd","/DepartmentServlet","text",function(data){//console.log(data)
     if(data==1){
           layer.msg("修改成功",layerClose)
     }else{
           layer.msg("修改失败")
     }
})
分页的实现  
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
为了减少时间 暂时去掉了防盗链功能UserFilter类上面的注解 注释了 最后记得取消掉啊!!!!!!!!!
三、交互过程 
 接受请求:   web-->servlet-->service-->dao-->sql
 回应请求: table-->model-->dao( *jdbc - 数据库和Java*)-->web-->servlet(*网页和Java*)-->service
 
servlet (每个分支的过程(1接受请求、2获取数据、3封装对象、4调用方法、5返回结果))
 
四、未实现错误点
 
  1. dataType : "text",//text / json  可以
    dataType : "json",    不可以--- 原因是EmployeeServlet 中返回类型不对应,不是json类型,暂时采用 异常抛出的方式
dataType:"text" 只能是文本
dataType:"json" 可以是文本也可以是json
    网上寻找的方法:通过建立异常抛出将错误信息展示出来(只能是凑合,不严谨 -- 属于只能是勉强看上去是正确的!)
function ajax(url,field,func){
     //console.log(field)
     $.ajax({//四个属性一个方法
           url : base.app + url,
           type : "post",
           data : field,
           //dataType : "json",//text / json
           success : func,
         error:function(){// 异常处理
              alert("注册失败,账号重复");
         }
           
     });
}
 
    后来采用:
function formSubmit(event,url,dataType,func){
     //console.log(event) 调试
     form.on("submit(" +event+")",function(data){
     //   console.log(data.field)调试
           ajax(url,data.field,dataType,func)
     })
}
function ajax(url,field,dataType,func){
     //console.log(field)
     $.ajax({//四个属性一个方法
           url : base.app + url,
           type : "post",
           data : field,
           dataType : dataType, //后采用
           //dataType : "text",//text / json
           success : func
     });
}
 
2.使用请求转发的方式实现 回显(get2)方法   未实现 报方法不可用
 
 
五、已解决错误点
 
判断注册输入账号是否存在  老师用的是 反射 
EmployeeDaoImpl类中 
//   private static String cols = "code,name,pass";
     private static String cols =  "code,name,pass,code_dept,image";
     // 此处的数据库表字段 在方法中可以不使用某一个,但是不能在方法中使用没有的表字段
 
控制台报 SQL语句错误   code=‘网页你输入的数’
 
关于字符串拼接(没搞明白)===》 (苦思冥想 终于解决,但是原因居然是因为空格  ,append的空格没对起来    还要记得里面有符号时要加 转义字符        重要!!!!! 重要!!!!  重要!!!!)
StringBuffer sql = new StringBuffer("select id,code,name,tel  from ").append(table); 不可以 (没看出为什么来)
StringBuffer sql = new StringBuffer("select id,code,name,tel  from ").append(table).append(" ") 改成这样就可以了 
 
  append 拼接时一定不要忘了 语句间的 空格(切记!!!)   不要忘了空格(重要重要!!!)   不要忘了空格!!!   不要忘了空格!!!不要忘了空格!!!不要忘了空格!!!
           
 
StringBuffer sql = new StringBuffer("select  id,code,name,tel from department ");  可以
append  未解之谜(不是未解了 ,搞定了!!!)
为什么 StringBuffer sql = new StringBuffer("select id,code,name,tel  from ").append(table); 取到的值为空  但是StringBuffer sql = new StringBuffer("select  id,code,name,tel from department "); 就能取到  初步怀疑 是因为 JDBCUtil工具类中的selectList遍历有问题
 
五、NullPointerException 有可能是缓存的问题
1.
 
2.
六、解决报错 问题的步骤
  1.网页 控制台报 500 就是java端代码报错了 
  2.回到java控制台
    3.先去 FmtRequest方法中 用控制台输出可能产生为空的变量的值 如果没有输出
    4. 去DepartmentServlet 中 输出add分支中 可能为空的变量(req) 如果 还没输出就是 分支根本没有执行 是jsp文件中的错误
    5.隐藏域中的方法和 java中 不对应导致的
  6.修改后又包sql语句错误 然后去Department2DaoImpl 找insert 语句 发放插入sql语句错误 字段对应不起来 修改后 成功添加
拼接容易出错就用完整的sql语句 一点一点来实现
 
七、使用debug 方式来调试  
 
F5:跳入方法
F6:向下逐行调试
F7:跳出方法
F8:直接跳转到下一个断点
debug 详解  https://blog.csdn.net/chao430/article/details/65443449