记录一下普通表格批量删除的写法.
批量删除本质上都有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那列也单独作为了一列来筛选。而列筛选功能里会支持多选功能。