智销系统项目day3 - CRUD功能

1. 准备按钮

1.1 employee.jsp

<div id="tb" style="padding:5px;height:auto">
    <!-- 这部分是加上增删改的按键:现在没有功能,我们先不管它 -->
    <div style="margin-bottom:5px">
        <a href="#"  data-method="add" class="easyui-linkbutton" iconCls="icon-add" plain="true">添加</a>
        <a href="#"  data-method="edit" class="easyui-linkbutton" iconCls="icon-edit" plain="true">修改</a>
        <a href="#"  data-method="del" class="easyui-linkbutton" iconCls="icon-remove" plain="true">删除</a>
    </div>
    <!-- 这部门是查询的功能 -->
    <div>
        <form id="searchForm" action="/employee/download" method="post">
            用户名: <input name="username" class="easyui-textbox" style="width:80px;height:32px">
            邮件: <input name="email" class="easyui-textbox" style="width:80px;height:32px">
            部门 :
            <input  class="easyui-combobox" name="departmentId"
                    data-options="valueField:'id',textField:'name',panelHeight:'auto',url:'/util/departmentList'">
            <a href="#" data-method="search"  class="easyui-linkbutton" iconCls="icon-search">查找</a>
        </form>
    </div>
</div>

1.1 employee.js

//es6语法
itsource={
    //查询数据
    search () {
        //需要先引入 jquery.serializejson.js 才可以使用这个方法
        var params = searchForm.serializeJSON();
        employeeGrid.datagrid('load',params);
    },
    add () {
      //添加数据(弹出添加的模态框)
    },
    edit () {
       //修改数据(弹出修改的模态框)
    },
    del () {
       //删除数据
    }, 
    save () {
       //保存数据
    }
}

2. 删除功能

2.1 employee.js

itsource={
    //查询数据
    search () {
        //需要先引入 jquery.serializejson.js 才可以使用这个方法
        var params = searchForm.serializeJSON();
        employeeGrid.datagrid('load',params);
    },
    add () {
      //添加数据(弹出添加的模态框)
    },
    edit () {
       //修改数据(弹出修改的模态框)
    },
    //删除数据
    del () {
        //拿到选中的这条数据
        var row = employeeGrid.datagrid("getSelected");
        if(row){
            $.messager.confirm('确认框', '确定要狠心删除我么?', function(r){
                if (r){
                    //进行删除
                    $.get("/employee/delete",{id:row.id},function (result) {
                        if(result.success){
                            $('#employeeGrid').datagrid('reload');
                        }else{
                            //alert("删除失败");
                            $.messager.alert('提示信息','删除失败!,原因:'+result.msg,"error");
                        }
                    })
                }
            });
        }else{
            $.messager.alert('提示信息','请选择一行再进行删除!','info');
        }
    },
    save () {
       //保存数据
    }
}

2.2 JsonResult.java

package com.zpx.common;

public class JsonResult {
    private boolean success = true;
    private String msg;

    public JsonResult(boolean success, String msg) {
        this.success = success;
        this.msg = msg;
    }
    public JsonResult() { }

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

2.3 EmployeeController.java

@Controller
@RequestMapping("/employee")
public class EmployeeController extends BaseController {
	@Autowired
    private IEmployeeService employeeService;
	@RequestMapping("/delete")
	@ResponseBody
	public JsonResult delete(Long id){
	    try {
	        employeeService.delete(id);
	        return new JsonResult();
	    } catch (Exception e) {
	        e.printStackTrace();
	        return new JsonResult(false,e.getMessage());
	    }
	}
	.........
}

3. 完成添加修改

3.1 准备表单

使用Easyui的dialog来完成表单弹出功能

<body><div id="employeeDialog" class="easyui-dialog" data-options="closed:true,modal:true" title="员工操作" style="width:400px">
    <div style="padding:10px 60px 20px 40px">
        <form id="employeeForm" class="easyui-form" method="post" data-options="">
            <input type="hidden" id="employeeId" name="id" >
            <table cellpadding="5">
                <tr>
                    <td>用户名:</td>
                    <td><input class="easyui-validatebox" type="text" name="username" data-options="required:true"
                        validType="checkUsername"
                    ></input></td>
                </tr>
                <tr data-save="true">
                    <td>密码:</td>
                    <td><input id="password" class="easyui-validatebox" type="password" name="password" data-options="required:true"></input></td>
                </tr>
                <tr data-save="true">
                    <td>重复密码:</td>
                    <td><input class="easyui-validatebox" type="password" name="repassword" data-options="required:true"
                                validType="equals['password',’id’]"></input></td>
                </tr>
                <tr>
                    <td>邮件:</td>
                    <td><input class="easyui-validatebox" type="text" name="email" data-options="required:true,validType:'email'"></input></td>
                </tr>
                <tr>
                    <td>年龄:</td>
                    <td><input class="easyui-validatebox" type="text" name="age" data-options="required:true"></input></td>
                </tr>
                <tr>
                    <td>部门:</td>
                    <td>
                        <input class="easyui-combobox" name="department.id"
                                data-options="valueField:'id',textField:'name',panelHeight:'auto',url:'/util/departmentList'">
                    </td>
                </tr>
            </table>
        </form>
        <div style="text-align:center;padding:5px">
            <a href="javascript:void(0)" class="easyui-linkbutton" data-method="save">提交</a>
            <a href="javascript:void(0)" class="easyui-linkbutton" onclick="$(‘employeeDialog’).dialog('close')">取消</a>
        </div>
    </div>
</div></body>

3.2 修改加上弹出功能

employee.js代码

//验证扩展:两次数据是否一致
$.extend($.fn.validatebox.defaults.rules, {
    equals: {
        validator: function(value,param){
            return value == $(param[0]).val();
        },
        message: '两次密码匹配.'
    }
});
//验证扩展:用户名是否可以重复使用
$.extend($.fn.validatebox.defaults.rules, {
    checkUsername: {
        validator: function(value,param){
            var employeeId = $("#employeeId").val();
            var result = $.ajax({
                type: "GET",
                url: "/employee/checkUsername",
                data:{username:value,id:employeeId},
                async: false //同步
            }).responseText;
            return result=="true";
        },
        message: '用户名不能重复.'
    }
});
…
itsource={
    //查询数据
    search() {
        //需要先引入 jquery.serializejson.js 才可以使用这个方法
        var params = searchForm.serializeJSON();
        employeeGrid.datagrid('load',params);
    },
    //添加数据(弹出添加的模态框)
    add() {
        //如果有data-save属性,我们把它展示出来
        $("*[data-save]").show();
        //启动有data-save属性的input元素的验证功能
        $("*[data-save] input").validatebox("enable"); 
       employeeForm.form("clear");//清除数据
        //弹出表单窗口
        employeeDialog.dialog("center").dialog('open');
    },
    //修改数据(弹出修改的模态框)
    edit() {
        //选中了某一条数据才删除
        var row = employeeGrid.datagrid("getSelected");
        if(row){
            //隐藏有data-save属性的元素
            $("*[data-save]").hide();
            //禁用有data-save属性的input元素的验证功能
            $("*[data-save] input").validatebox("disable");

            employeeForm.form("clear");//清除数据
            employeeDialog.dialog("center").dialog('open');
            //单独解决部门的回显问题
            if(row.department){
                row["department.id"] = row.department.id;
            }
            //为form加载数据
            $("#employeeForm").form("load",row);
        }else{
            $.messager.alert('提示信息','请选择一行再进行修改!','info');
        }
    },
	save() {
	    var url  = "/employee/save";
	    var id = $("#employeeId").val();
	    if(id){
	        url = "/employee/update?cmd=update";
	    }
	    employeeForm.form('submit', {
	        url:url,
	        onSubmit: function(){
	            //做验证
	            return $("#employeeForm").form("validate");
	        },
	        success:function(data){
	            var result = JSON.parse(data);//转成相应的json数据
	            if(result.success) {
	                $('#employeeGrid').datagrid('reload');
	            }else{
	                $.messager.alert('提示信息','操作失败!,原因:'+result.msg,"error");
	            }
	            employeeDialog.dialog('close');
	        }
	    })
	}}

同步Ajax请求我们也可以用新的方案:

var isSuccess = $.util.requestAjaxBoolean('/employee/checkUsername',{username:value});

3.3 后台的功能支持

4.3.1 用户是否重复验证

EmployeeRepository

public interface EmployeeRepository extends BaseRepository<Employee,Long> {

    @Query("select count(o) from Employee o where o.username=?1")
    Long getCountByUsername(String username);
}

IEmployeeService

public interface IEmployeeService extends IBaseService<Employee,Long> {
    /**
     * 如果根据用户名查询到了员工 -> 返回false(代表这个用户已经存在)
     * @param username
     * @return
     */
    boolean checkUsername(String username);
}

EmployeeServiceImpl

@Service
public class EmployeeServiceImpl extends BaseServiceImpl<Employee,Long> implements IEmployeeService {
    @Autowired
    private EmployeeRepository employeeRepository;
    //如果得到的结果大于0,返回false,代表用户名已被占用
    @Override
    public Boolean checkUsername(String username) {
        return !(employeeRepository.getCountByUsername(username)>0);
    }
}

EmployeeController

@RequestMapping("/checkUsername")
@ResponseBody
 public Boolean redelete(Long id,String username){
     //1.判断id是否存在
     if(id!=null){
         //2.根据id查询对象
         Employee dbEmp = employeeService.findOne(id);
         //3.判断名称是否相等
         //4.如果相等,直接返回true
         return(username.equals(dbEmp.getUsername()));
     }
     return employeeService.checkUsername(username);
 }

3.3.2 完成基本的添加与修改

//删除功能
@RequestMapping("/save")
@ResponseBody
public JsonResult save(Employee employee){
    try {
        employeeService.save(employee);
        return new JsonResult();
    } catch (Exception e) {
        e.printStackTrace();
        return new JsonResult(false,e.getMessage());
    }
}
//添加功能
@RequestMapping("/update")
@ResponseBody
public JsonResult update(@ModelAttribute("editEmployee")Employee employee){
    try {
        employeeService.save(employee);
        return new JsonResult();
    } catch (Exception e) {
        e.printStackTrace();
        return new JsonResult(false,e.getMessage());
    }
}

4. 数据丢失问题

这里我们出现一个新的问题,当我们完成修改之后,咱们的密码就消失不见了,这里咱们有三个解决方案
在这里插入图片描述

4.1 三种解决方案

在这里,咱们有三个解决方案:

  • 方案一:隐藏要传递的值(只隐藏,但是数据还是需要传递,这和第一个项目是同相同的方案)
    这个方案的优点是简单易理解,缺点是如果字段过多,代码量会比较大,另外这种方案的安全性确实是有一些低!
  • 方案二:在JPA的相应字段上加标签:
@Column(updatable = false)
private String password;

这个方案也比较简单,但是如果你需要修改这个字段的时候就比较麻烦!

  • 方案三:先查询数据库,获取持久状态的对象,然后把页面的数据set到对象里面
    (这种方案也是用得比较多的一种方案)
Employee tempEmployee = employeeService.get(employee.getId());
//需要修改的值就从页面里面的employee放入tempEmployee
tempEmployee.setUsername(employee.getUsername());
employeeService.save(tempEmployee);

在这里插入图片描述

4.2 SpringMVC之@ModelAttribute

咱们如果自己要完成所有数据查询,再进行相应的字段拷备覆盖,还是比较麻烦的。大家如果反射与JavaBean部分学得比较透彻的话可以去进行相应的尝试(主要就是完成一个属性拷备功能)。
而在SpringMVC中,有一个ModelAttribute标签,可以助我们完成这个功能!
接下来,我们就来学习一下这个标签的作用!!!

4.2.1 ModelAttribute的作用

运用在方法上,会在每一个@RequestMapping标注的方法前执行,如果有返回值,则自动将该返回值加入到ModelMap中;
运用在参数上,会将客户端传递过来的参数按名称注入到指定对象中,并且会将这个对象自动加入ModelMap中,便于View层使用;

咱们先不管返回值,我们在EmployeeController类中加一个相应的方法,看是否要执行所有代码之前都会先执行这个方法!!!

@ModelAttribute
public void beforeEdit(){
    System.out.println("执行就执行,我不怕的!!!");
}

4.2.2 传参与解决方案

这时候,我们可以看到这个类所有的方法(通过路@RequestMapping)访问之前都会先访问这个方法。接下来,我们可以看一下这个是怎么传值的。
在下面的传值代码中我们也解决了数据丢失的问题。

//这里准备一个方法,所有方法执行前都会执行它
@ModelAttribute("editEmployee")
public Employee beforeEdit(Long id,String cmd){
     if (id!=null && "_update".equals(cmd)){
         //修改才走这个代码
         Employee dbEmployee = employeeService.findOne(id);
         //解决n-to-n的问题,把关联对象设置为空
         dbEmployee.setDepartment(null);
         return dbEmployee;
     }
     return null;
 }
//保存功能
@RequestMapping("/save")
@ResponseBody
public JsonResult save(Employee employee){
    try {
        employeeService.save(employee);
        return new JsonResult();
    } catch (Exception e) {
        e.printStackTrace();
        return new JsonResult(false,e.getMessage());
    }
}
//修改功能
@RequestMapping("/update")
@ResponseBody
public JsonResult update(@ModelAttribute("editEmployee")Employee employee){
    try {
        employeeService.save(employee);
        return new JsonResult();
    } catch (Exception e) {
        e.printStackTrace();
        return new JsonResult(false,e.getMessage());
    }
}

4.2.3 只让修改功能去查询

大家思考一下,咱们的现在所有方法都会进入到beforeEdit中,那么只要传过来id,就会执行这个方法,这个对效率是会有影响的。所以我们可以对代码进行修改,让只有修改功能才去执行这个查询代码!!
employee.js -> 修改时传一个cmd=update

itsource={//保存数据
    save:function () {
        var url  = "/employee/save";
        var id = $("#employeeId").val();
        if(id){
            url = "/employee/update?cmd=update";
        }
        employeeForm.form('submit', {
            url:url,
            onSubmit: function(){
                //做验证
                return $("#employeeForm").form("validate");
            },
            success:function(data){
                $('#employeeGrid').datagrid('reload');
                employeeDialog.dialog('close');
            }
        })
    }
}

EmployeeController进行判断

/**
*ModelAttribute:路径访问Controller的每个方法,都会先执行它里面的代码
*/
@ModelAttribute("editEmployee")
public Employee beforeEdit(Long id,String cmd){
   if (id!=null && "_update".equals(cmd)){
       //修改才走这个代码
       Employee dbEmployee = employeeService.findOne(id);
       return dbEmployee;
   }
   return null;
}

4.2.4 部门修改的n-to-n

这时候大家继续开发会发现一个问题,在修改部门的时候,会出现n-to-n错误,就是咱们修改的时候也在相应的修改它的部门(这时候部门是一个持久化对象,它的id是不允许进行修改的。)
报错如下:
在这里插入图片描述
解决方案(在获到员工的时候把部门设置为空):

/**
 *ModelAttribute:路径访问Controller的每个方法,都会先执行它里面的代码
 */
@ModelAttribute("editEmployee")
public Employee beforeEdit(Long id,String cmd){
    if (id!=null && "_update".equals(cmd)){
        //修改才走这个代码
        Employee dbEmployee = employeeService.findOne(id);
        //解决n-to-n的问题,把关联对象设置为空
        dbEmployee.setDepartment(null);
        return dbEmployee;
    }
    return null;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值