员工绩效管理系统(超级超级详细 ---未完待更...)


一.分级建立项目包     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"%> 注册页面 <%@ include file="/web/header.jsp" %>
     
       注册        
         
           
                                        
                                                 placeholder="请输入账号"  autocomplete="off" class="layui-input">                       
                
                
                                        
                                                 placeholder="请输入密码"  autocomplete="off" class="layui-input">                       
                
                
                                        
                                                 placeholder="请输入姓名"  autocomplete="off" class="layui-input">                       
                
                
                 
                     lay-submit lay-filter="reg" >                                                 
                                       
                                               
       
     
     
<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>               (1)   输入框不能为空 触发回调方法(测试段) 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 (将引用路径进行封装) <% String app=request.getContextPath(); %> <script type="text/javascript" src="<%=app  %>/web/base/layui/layui.js" ></script> <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 反射       * @param req       * @param clazz       * @return       */      public static T parseModel(HttpServletRequest  req,Class clazz) {            T obj = null;            try {                 obj = clazz.newInstance();            } catch (InstantiationException |  IllegalAccessException e) {                 e.printStackTrace();                 return null;            }            Map map = req.getParameterMap(); //  传过来的所有参数            for (Entry 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       * @param req       * @param clazz       * @param fields key=属性名   value=参数名       */      private static T parseModel(HttpServletRequest  req,Class clazz,Map fields) {            T obj = null;            try {                 obj = clazz.newInstance();            } catch (InstantiationException |  IllegalAccessException e) {                 e.printStackTrace();                 return null;            }            for (Entry 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) 实现员工登录功能(主要完善业务逻辑) login" > 这里的login 决定了对应的js代码怎么实现   login" > 这里的login 决定了servlet文件中的分支怎么实现             1. 创建登录界面 <%@ page language="java" contentType="text/html; charset=UTF-8"     pageEncoding="UTF-8"%> 登录页面 <%@ include file="/web/header.jsp" %>
     
       注册        
         
           
                                        
                                            
                
                
                                        
                                            
                
                
                 
                                                                      
                                       
                          
       
     
     
<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>           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:   javascript function toHref(){      location.href = base.app + "/web/login.jsp"; }   登录界面跳转注册界面 html:     javascript function toHref(){      location.href = base.app + "/web/reg.jsp"; }   简化代码 在base.js 文件中添加 function toHref(url){      location.href = base.app + url; } 修改注册界面代码 修改登录界面代码 (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"%> <%@ include file="/web/header.jsp" %> 主界面
  
                      
     
    
                  
  
     
            
     
<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> 4.主界面退出操作 (layui)     (1).mian.jsp html
  •            退出
  •   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
  •         请求处理                     
  •   js function openRight(){      layer.open({            type:1            ,content:'
    处理右侧面板的操作
    '            ,area:['260px','100%']            ,offset:'rt'//右上角            ,anim:5            ,shadeClose:true      }); } 7.主界面主体查询操作部分(layui 面板)         (1)html 操作代码 面板上半部分 html:
      
        

    部门信息--查询条件

        
                      
                 部门信息--查询条件              
                   
                     
                                                        
                                                            
                                                        
                                                            
                                                                                                                                                                                                                            
                   
                 
               
        
      
      面板下半部分 HTML:                                                                                                    
    序号编号名称电话操作
    <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 文件  取出 查询行中( )的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文件            这样就可以实现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 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 selectList(DepartmentModel  model) {            return dao2.selectList(model);      }      @Override      public DepartmentModel selectModel(DepartmentModel model)  {            return dao2.selectModel(model);      }            简单实现查询方法     @Override      public List 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 selectList(DepartmentModel model);   5返回结果     private String list(HttpServletRequest req) {         // 将所有请求的参数映射到实体类中         DepartmentModel model =FmtRequest.parseModel(req,  DepartmentModel.class);             // service.selectList(model)  返回的是集合         List list =  service.selectList(model);         return null;      }     简化后:     private List 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">      {{d.id}}{{d.code}}{{d.name}}{{d.tel}}                  删除            修改       </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添加跳转后的页面            添加   (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文件中添加关闭的静态事件绑定 onclick="layerClose()" >          实现数据添加操作    (1)html文件 的操作 首先完善 add.jsp 页面的html代码 <%@ page language="java" contentType="text/html; charset=UTF-8"     pageEncoding="UTF-8"%> <%@ include file="/web/header.jsp" %> 部门添加界面
           部门添加界面        
             
               
                                            
                                                
                    
                    
                                            
                                                
                    
                    
                                            
                                                
                    
                    
                     
                            // 添加动态事件绑定   1                                                                                                 
                    
                                               
           
         
                <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>                实现数据添加操作    (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">      {{d.id}}{{d.code}}{{d.name}}{{d.tel}}                                                           修改       </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 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 values = appendWhere(sql,model); // 这里调用了appendWhere去判断是否对应            return JDBCUtil1.update(sql.toString(), values);      } 实现数据删除操作  (7)在IDepartment2DaoImpl中调用了appendWhere去判断是否对应 private List appendWhere(StringBuffer sql,  DepartmentModel model) {            sql.append("where 1=1");            List 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">      {{d.id}}{{d.code}}{{d.name}}{{d.tel}}                                                          修改       </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"%> <%@ include file="/web/header.jsp" %> 修改页面
           部门修改界面        
             
               
                                            
                                                
                    
                    
                                            
                                                                         
                    
                    
                                            
                                                
                    
                    
                     
                         get" >                                                                           
                    
                                     get" >          
           
         
    <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> 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 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 values = appendSet(sql, model); // 这里又调用了appendSet方法执行后返回            return JDBCUtil1.update(sql.toString(), values);      }       private List appendSet(StringBuffer sql, DepartmentModel  model) { // 定义字符串拼接方法            List values = new ArrayList();            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

    相关