表单中用多选框实现批量删除

93 阅读2分钟

记录一下普通表格批量删除的写法.


批量删除本质上都有n次删除动作,但是可以有不同的写法。

  • 第一种策略

    选中n条数据后往后台发送n次删除请求,每个请求中只包含一条数据的 id 。这样做的好处主要是可以和单条删除共用一个controller层的函数。

  • 第二种策略

    选中n条数据后往后,将他们组成一个list传给后端controller,list中包含的是要删除的数据的 id 。这样做的好处就是大大减少请求次数(只有一次请求),而缺点就是要在controller里多写一个函数,但不会很复杂。


综合来看,还是第二种策略更好,因为连接的建立还是挺珍贵的。两者的前端html代码都是一样的,区别在前端js代码和controller的java方法。



一、前端html代码

<button type="button" onclick="allDelete()">批量删除


<table>
    <thead>
    <tr>
        <th><input type="checkbox" id="allChecks" onclick="ckAll()"/> 全选/全不选</th>
        <th>客户姓名</th>
        <th>客户邮箱</th>
        <th>客户电话</th>
        <th>客户地址</th>
        <th>创建时间</th>
    </tr>
    </thead>
    
    <tbody>
    <c:forEach items="${pageInfo.list}" var="order">
        <tr>
            <td><input type="checkbox" name="check" value=${order.id}></td>
            <td>${order.name}</td>
            <td>${order.email}</td>
            <td>${order.phone}</td>
            <td>${order.address}</td>
            <td>${order.create_time}</td>
        </tr>
    </c:forEach>
    </tbody>
</table>


二、前端js代码

第一种策略(n次请求)

// 批量删除
function allDelete() {
    // 不能用$("input[type='checkbox']:checked"),因为全选的那个按钮,type也是checkbox,全选时,数组中下标会多出来一个
    var checkIds = $("input[name='check']:checked") 
    if (checkIds.length < 1) {
        alert("没有要删除的数据")
        return
    }
    var isDelete = confirm("你确定删除这" + checkIds.length + "条记录吗?");

    if (isDelete === true) {
        var deleteRes;
        $(checkIds).each(function (index) {    
            $.ajax({							// n次请求
                url: "/order/delete",
                type: "post",
                data: {
                    id: checkIds[index].value
                },
                success: function (msg) {
                    deleteRes = !!(msg.ans === '成功');
                }
            });
        });
        if (deleteRes) {
            alert("删除成功!");
            window.location.reload();
        } else {
            alert("删除失败!");
        }
    }
}

// 控制全选与全不选的效果
function ckAll() {
    var flag = document.getElementById("allChecks").checked;
    var cks = document.getElementsByName("check");
    for (var i = 0; i < cks.length; i++) {
        cks[i].checked = flag;
    }
}

第二种策略(1次请求)

function allDelete() {
    var checkIds = $("input[name='check']:checked")    
    if (checkIds.length < 1) {
        alert("没有要删除的数据")
        return
    }
    var isDelete = confirm("你确定删除这" + checkIds.length + "条记录吗?");

    if (isDelete === true) {
        let ids=[];
        $(checkIds).each(function (index) {   // 把n个id装到list中
            ids.push(checkIds[index].value)
        });

        $.ajax({							// 1次请求
            url: "/order/deleteMulti",
            type: "post",
            data: {
                // ajax无法直接传递list给后端,需要将list转化成json字符串
                ids:  JSON.stringify(ids)    
            },
            success: function (msg) {
                console.log(msg)
                if (msg.ans === "成功") {
                    alert(checkIds.length + "条记录删除成功!");
                    window.location.reload();
                } else {
                    alert(msg.ans);
                }
            },
            error: function (data) {
                alert("返回到ajax的error函数中");
            }

        });

    }
}


三、后端controller层java代码

第一种策略(n次请求)

@RequestMapping(value = "/delete", method = RequestMethod.POST)
@ResponseBody
public HashMap<String ,String > deleteById(@RequestParam("id") String id) {

    int count =  orderService.deleteById(id);

    if (count > 0) {
        msg.put("ans", ResultEnum.SUCCESS.getMessage());
    }
    else {
        msg.put("ans", ResultEnum.FAIL.getMessage());
    }
    return msg;
}

第二种策略(1次请求)

@RequestMapping(value = "/deleteMulti", method = RequestMethod.POST)
@ResponseBody
public HashMap<String ,String > deleteByIds(@RequestParam("ids") String tmp) {   //传来的类型是json字符串,需要用String接收,用List或JsonElement都是错的

    // 使用gson工具,将前端发来的json字符串转换为list
    Gson gson = new Gson();
    ArrayList<String>  ids=new ArrayList<>();
    ids=gson.fromJson(tmp, ids.getClass()); // 两个参数:json字符串的名字、目标类型
    
    for(Object id:ids){
        int count =orderService.deleteById((String) id);
        if (count <1){   // 删除任何一个失败,都要报告,配合事务回滚,结束整个批量删除动作
            msg.put("ans","在删除id为"+id+"的数据时发生错误,事务已回滚");
            return msg;
        }
    }
    msg.put("ans", "成功");
    return msg;
}


四、后端serviceImp层java代码

@Override
@Transactional    // 事务,遇到异常时回滚
public Order queryById(String id) {
    return orderDao.queryById(id);
}


注意:

如果用到了bootstrap-table插件,其中的列筛选功能会和上面的代码冲突,导致 全选/全不选 按钮失效,因为checkbox那列也单独作为了一列来筛选。而列筛选功能里会支持多选功能。