1送水历史列表
点击“送水历史管理”,显示“送水历史”列表。送水历史列表查询工作涉及到三张表联合查询,我们使用MyBatis-plus映射文件(HistoryMapper.xml)代替MyBatis-Plus提供的内置查询方法。
sql
SELECT h.hid,w.worker_name,h.send_water_time,c.cust_name,h.send_water_count
FROM tb_history h,tb_worker w ,tb_customer c
WHERE h.worker_id = w.wid and h.cust_id = c.cid;
涉及到送水工、客户管理、以及我们的提成
1.1 编写YML文件
配置Mapper映射文件的路径和包别名 (mybatis-plus的扫包,以及扫它的mapper.xml)
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
id-type: auto
# 配置Mapper.xml文件的路径,此时所有Mapper.xml映射文件都定义在resources/mapper路径下
mapper-locations: classpath:/mapper/*Mapper.xml
# 配置指定包中(com.shouyi.entities)不包括包名的简单类名作为包括包名的别名
type-aliases-package: com.shouyi.entities
1.2 编写History实体类
package com.shouyi.entities;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* TODO 送水历史管理实体类
* @author caojie
* @version 1.0
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("tb_history")
public class History {
/**
* 送水历史ID
*/
private Integer hid;
/**
* 关联送水工
*/
private Worker worker;
/**
* 关联客户
*/
private Customer customer;
/**
* 送水时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date sendWaterTime;
/**
* 送水数量
*/
private Integer sendWaterCount;
}
1.3 编写Mapper接口
package com.shouyi.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.shouyi.entities.History;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* TODO: 送水历史相关的映射器
* @author caojie
* @version 1.0
*/
@Repository
public interface HistoryMapper extends BaseMapper<History> {
/**
* 自定义查询方法来代替MyBaits-Plus内置的查询方法,查询所有的送水历史信息。
* @return 送水历史列表
*/
List<History> listHistory();
}
1.4 编写Mapper映射文件
我们使用自定义查询方法来代替MyBaits-Plus
内置的查询方法,所以要编写HistoryMapper
接口对应的映射文件HistoryMapper.xml
。该映射文件在resources/mapper
路径下定义
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.shouyi.mapper.HistoryMapper">
<!-- 我们使用三张表进行联合查询,所以查询的送水历史列表返回一个结果集,将三张表查询的结果封装到resultMap结果集中。resultMap类似于JDBC的ResultSet对象
resultMap有两个核心属性:
1) id表示resultMap在整个配置文件中的唯一性
2) type表示返回值的全限定类名,我们在yml配置文件中配置了type-aliases-package: com.shouyi.entities。所以type属性值可以返回类型别名(省略了包名)
-->
<resultMap id="selectHistoryMap" type="History">
<id property="hid" column="hid" />
<result column="send_water_time" property="sendWaterTime" />
<result column="send_water_count" property="sendWaterCount"/>
<!-- 送水历史关联送水工-->
<association property="worker" javaType="com.lxyk.pojo.Worker">
<id column="wid" property="wid"></id>
<result column="worker_name" property="workerName"></result>
</association>
<!-- 送水历史关联客户-->
<association property="customer" javaType="com.lxyk.pojo.Customer">
<id column="cid" property="cid"></id>
<result column="cust_name" property="custName"></result>
</association>
</resultMap>
<!--
select节点表示一个查询方法
id属性必须跟HistoryMapper接口的方法名一致
-->
<select id="listHistory" resultMap="selectHistoryMap">
SELECT h.hid,w.worker_name,h.send_water_time,c.cust_name,h.send_water_count
FROM tb_history h, tb_worker w, tb_customer c
WHERE h.worker_id = w.wid and h.cust_id = c.cid
</select>
</mapper>
注意:
javaType(结果集)要加上全限定名,不然可能出现找不到实体类的问题
一定要文档注释,写sql语句时会有提示
1.5 编写Service接口
package com.shouyi.service;
import com.shouyi.entities.History;
import java.util.List;
/**
* TODO 送水历史管理业务逻辑接口
* @author caojie
* @version 1.0
*/
public interface HistoryService {
/**
查询所有送水历史信息
*/
List<History> listHistory() ;
}
1.6 编写Service接口实现类
package com.shouyi.service.impl;
import com.shouyi.entities.History;
import com.shouyi.mapper.HistoryMapper;
import com.shouyi.service.HistoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* TODO:送水历史管理接口实现类
* @author caojie
* @version 1.0
*/
@Service
public class HistoryServiceImpl implements HistoryService {
@Autowired
private HistoryMapper historyMapper;
/**
查询所有送水历史信息
*/
@Override
public List<History> listHistory() {
return historyMapper.listHistory();
}
}
1.7 编写Controller控制器
package com.shouyi.controller;
import com.shouyi.entities.History;
import com.shouyi.service.HistoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
/**
* TODO
*
* @author caojie
* @version 1.0
* @date 2021/10/25 20:20
*/
@RequestMapping("/history")
@Controller
@Slf4j
public class HistoryController {
@Autowired
private HistoryService historyService;
/**
点击“送水历史管理”,调用HistoryService对象查询所有送水历史信息,然后将信息渲染到前端。最后返回“送水历史”页面
*/
@RequestMapping("/listHis")
public String listHistory(Model model) {
List<History> hisList = historyService.listHistory();
log.info("history list size = "+hisList.size());
model.addAttribute("hisList",hisList);
return "historyList";
}
}
1.8 编写送水历史管理列表页面
在resources/water
路径下创建客户管理列表页面historyList.html
,显示送水历史信息。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title> 冯宝宝送水后台管理系统</title>
<!--Bootstrap固定框架-->
<link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.css}">
<link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap-theme.css}">
<!--图标库-->
<link rel='stylesheet' th:href='@{/css/material-design-iconic-font.min.css}'>
<!--核心样式-->
<link rel="stylesheet" th:href="@{/css/style.css}">
<script th:src="@{/webjars/jquery/3.3.1/jquery.js}"></script>
<script>
$(function() {
// 为“全选/全不选”复选框绑定单击事件,一旦触发该事件要么“全选”送水历史复选框,要么全不选
$("#selectAll").click(function() {
// 使用元素属性选择器选择所有的“送水历史复选框” prop---> property
$("input[name=chkHistory]").prop("checked",$(this).prop("checked"));
})
// 为“批量删除”按钮绑定一个“单击"事件,一旦触发将选中的所有“送水历史”复选框进行批量删除
$("#batchDelete").click(function(){
// 获取所有选中的“送水历史”复选框
let chkList = $("input[name=chkHistory]:checked");
// 条件成立:表示一个都没有选择,终止批量删除操作
if(chkList.length == 0) {
alert("请至少选择一项");
return;
}
// 存储复选框的id属性值
let ids = "";
// 获取所有选中的“送水历史”复选框id值
$(chkList).each(function(){
let id = $(this).val();
// 对选中的ID进行拼接
ids += ","+id;
})
// 使用异步ajax技术,向后端发起批量删除请求
$.ajax({
url:'/history/batchDeleteHistory',
data:{
idList:ids
},
method:'POST',
success: function(data,status) {
if (data == "OK") {
alert("批量删除成功");
window.location.href = "/history/listHis";
} else {
alert("批量删除失败");
}
}
})
})
})
</script>
</head>
<body>
<div id="viewport">
<!-- Sidebar
客户列表页面使用th:replace属性替换成主菜单的侧边栏,让代码能够复用
th:replace="waterMainMenu::sidebar"
waterMainMenu表示主菜单页面的文件名称
sidebar表示主菜单页面的片段名称
-->
<div id="sidebar" th:replace="waterMainMenu::sidebar">
</div>
<!-- Content -->
<div id="content">
<!--
th:replace="waterMainMenu::navbar"表示将nav标签里面所有的内容替换为主页面的navbar片段
-->
<nav class="navbar navbar-default" th:replace="waterMainMenu::navbar">
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<div class="col-md-4">
<!-- 点击“添加”按钮跳转到“添加送水历史”页面-->
<a class="btn btn-primary" href="/history/preSaveHis">添加</a>
<a class="btn btn-danger" href="#" id="batchDelete">批量删除</a>
</div>
</div>
<div class="col-md-12">
<table class="table table-hover table-striped">
<thead>
<tr>
<td>
<input type="checkbox" name="selectAll" id="selectAll" /> 全选/全不选
</td>
<td>送水历史编号</td>
<td>送水工名称</td>
<td>送水时间</td>
<td>客户名称</td>
<td>送水数量</td>
<td>操作</td>
</tr>
</thead>
<tbody>
<tr th:each="his : ${hisList}">
<td>
<input type="checkbox" th:value="${his.hid}" name="chkHistory"/>
</td>
<td th:text="${his.hid}"></td>
<td th:text="${his.worker.workerName}"></td>
<td th:text="${#dates.format(his.sendWaterTime,'yyyy-MM-dd')}"></td>
<td th:text="${his.customer.custName}"></td>
<td th:text="${his.sendWaterCount}"></td>
<td>
<a class="glyphicon glyphicon-edit" th:href="@{'/history/preUpdateHis/'+${his.hid}}"></a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
<td th:text="${his.worker.workerName}"></td>workerName是在worker表里的
1.9 编写主页面
修改主页面waterMainMenu.html
,在“送水历史管理”菜单里面定义超链接
<li>
<a th:href="@{/history/listHis}">
<i class="zmdi zmdi-widgets"></i> 送水历史管理
</a>
</li>
2 添加送水历史信息
添加页面选择对应的“送水工”和“客户”,输入”送水时间“和“送水数量”
2.1编写Mapper接口
由于History涉及到三张表,我们无法使用Mapper
内置的添加方法。必须在HistoryMapper
接口里面定义saveHistory
方法来添加“送水历史”信息。
/**
* 添加送水历史
* @param history 送水历史信息
* @return 受影响行数,大于0添加成功,否则添加失败
*/
int saveHistory(History history);
2.2 编写Mapper映射文件
在HistoryMapper.xml
映射文件中定义insert
节点,添加“送水历史”信息。
<insert id="saveHistory" >
insert into tb_history(worker_id,cust_id,send_water_time,send_water_count)
values(#{worker.wid},#{customer.cid},#{sendWaterTime},#{sendWaterCount})
</insert>
2.3 编写Service接口
/**
* 添加送水历史
* @param history 表单采集的送水历史信息
* @return 手影响行数,大于0添加成功,否则添加失败
*/
int saveHistory(History history);
2.4 编写接口实现类
/**
* 添加送水历史
*
* @param history 表单采集的送水历史信息
* @return 受影响行数,大于0添加成功,否则添加失败
*/
@Override
public int saveHistory(History history) {
return historyMapper.saveHistory(history);
}
2.5 编写Controller
/**
送水历史需要用到客户信息,自动装配CustomerService对象
*/
@Autowired
private CustomerService customerService;
/**
送水历史需要用到送水工信息,自动装配WorkerService对象
*/
@Autowired
private WorkerService workerService;
/**
点击“添加”按钮执行预修改操作
步骤:
1 查询客户列表和送水工列表
2 将客户列表和送水工列表渲染到前端页面
3 返回送水历史页面
*/
@RequestMapping("/preSaveHis")
public String preSaveHistory(Model model) {
// 查询客户列表和送水工列表,渲染到前端
List<Customer> custList = customerService.listCustomer();
List<Worker> workerList = workerService.listWorker();
model.addAttribute("custList",custList);
model.addAttribute("workerList",workerList);
return "historySave";
}
/**
* 在“添加送水历史页面”点击“提交”按钮,将送水历史信息持久化(insert插入)到数据库中,然后返回“送水历史列表”,重新
* 查询送水历史列表显示新添加的数据
* 步骤:
* 1 将客户ID和送水工ID注入到History对象
* 2 调用HistoryService对象的saveHistory方法将表单采集的数据持久化到数据库
* 3 重新“查询送水历史信息”,显示新添加的数据
* @param workerId 表单采集的送水工编号
* @param custId 表单采集的客户编号
* @param history 表单采集的送水历史信息
* @return 重定向到送水历史列表路径
*/
@RequestMapping(value="/saveHis",method = RequestMethod.POST)
public String saveHistory(Integer workerId,Integer custId,History history) {
log.info("save History workerId = "+workerId);
log.info("save History customerId = "+custId);
log.info("History history = "+history);
// 将送水工编号和客户编号注入到History对象
Worker worker = new Worker();
worker.setWid(workerId);
Customer customer = new Customer();
customer.setCid(custId);
history.setCustomer(customer);
history.setWorker(worker);
// 将History对象持久化到数据库
int rows =historyService.saveHistory(history);
log.info("save History rows = "+rows);
return "redirect:/history/listHis";
}
2.6 编写送水历史列表页面
在送水历史列表页面新增加一个“添加”按钮,单击“添加”按钮跳转到“添加送水历史”页面
<div class="col-md-12">
<div class="col-md-4">
<a class="btn btn-primary"
th:href="@{/history/preSaveHis}">添加</a>
</div>
</div>
2.7 编写添加送水历史页面
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title> 冯宝宝送水后台管理系统</title>
<!--Bootstrap固定框架-->
<link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.css}">
<link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap-theme.css}">
<!--图标库-->
<link rel='stylesheet' th:href='@{/css/material-design-iconic-font.min.css}'>
<!--核心样式-->
<link rel="stylesheet" th:href="@{/css/style.css}">
</head>
<body>
<div id="viewport">
<!-- Sidebar -->
<div id="sidebar" th:replace="waterMainMenu::sidebar">
</div>
<!-- Content -->
<div id="content">
<nav class="navbar navbar-default" th:replace="waterMainMenu::navbar">
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<form class="form-horizontal" method="post" th:action="@{/history/saveHis}" >
<div class="form-group">
<label class="col-sm-2 control-label">送水工名称</label>
<div class="col-sm-5">
<select name="workerId" class="form-control">
<!-- 遍历每一个送水工选择-->
<option th:each="worker : ${workerList}"
th:value="${worker.wid}"
th:text="${worker.workerName}"/>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">送水时间</label>
<div class="col-sm-5">
<input type="date" class="form-control"
name="sendWaterTime" placeholder="送水时间">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">客户名称</label>
<div class="col-sm-5">
<!-- 以下拉列表框的形式展示所有的客户信息,实际的值是客户ID,显示的文本是客户名称-->
<select name="custId" class="form-control">
<!-- 遍历客户信息-->
<option th:each="cust : ${custList}"
th:value="${cust.cid}" th:text="${cust.custName}"/>
</select>
</div>
</div>
<div class="form-group" >
<label class="col-sm-2 control-label">送水数量</label>
<div class="col-sm-5">
<input type="text" class="form-control"
name="sendWaterCount" placeholder="送水数量"/>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-5">
<input type="submit" class="btn btn-primary" name="submit" value="提交">
<input type="reset" class="btn btn-warning" name="reset" value="取消">
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
3 修改送水历史信息
修改"送水历史"流程如下:
3.1 编写Mapper接口
/**
* 根据送水历史ID查询对应的送水历史
* 用途:修改之前的数据回显
* @param hid 送水历史ID
* @return 送水历史信息
*/
History getHistoryById(Integer hid);
/**
* 修改送水历史
* @param history 表单采集的的送水历史信息
* @return update语句受影响行数,大于0修改成功,否则修改失败
*/
int updateHistory(History history);
3.2 编写Mppaer映射文件
<!--
根据id查询对应的送水历史信息
id="getHistoryById" 对应HistoryMapper接口的getHistoryById方法
resultMap="selectHistoryMap"表示select查询语句返回的结果集是selectHistoryMap
parameterType="int" 表示getHistoryById方法的参数类型是Integer类型
-->
<sql id="selectHistory" >
SELECT h.hid, w.worker_name, h.send_water_time, c.cust_name, h.send_water_count
FROM tb_history h,tb_worker w, tb_customer c
</sql>
<select id="getHistoryById" resultMap="selectHistoryMap" parameterType="int" >
<include refid="selectHistory"></include>
WHERE h.worker_id = w.wid and h.cust_id = c.cid and hid = #{hid}
</select>
<!-- 修改“送水历史信息"
id="updateHistory"对应HistoryMapper接口的updateHistory方法
parameterType="History"表示HistoryMapper接口的updateHistory方法参数类型为History
-->
<update id="updateHistory" parameterType="History">
update tb_history
set worker_id = #{worker.wid}, cust_id = #{customer.cid},
send_water_time = #{sendWaterTime}, send_water_count = #{sendWaterCount}
where hid = #{hid}
</update>
3.3 编写Service接口
/**
* 根据送水历史ID查询对应的送水历史
* 用途:修改之前的数据回显
* @param hid 送水历史ID
* @return 送水历史信息
*/
History getHistoryById(Integer hid);
/**
* 修改送水历史
* @param history 表单采集的的送水历史信息
* @return update语句受影响行数,大于0修改成功,否则修改失败
*/
int updateHistory(History history);
3.4 编写Service接口实现类
/**
* 根据送水历史ID查询对应的送水历史
* 用途:修改之前的数据回显
*
* @param hid 送水历史ID
* @return 送水历史信息
*/
@Override
public History getHistoryById(Integer hid) {
return historyMapper.getHistoryById(hid);
}
/**
* 修改送水历史
*
* @param history 表单采集的的送水历史信息
* @return update语句受影响行数,大于0修改成功,否则修改失败
*/
@Override
public int updateHistory(History history) {
return historyMapper.updateHistory(history);
}
3.5 编写Controller控制器
/**
* 在“送水历史列表”页面,点击“修改”按钮,根据ID查询对应的“送水历史”信息,然后将信息渲染到前端页面
* 步骤:
* 1 查询所有客户信息
* 2 查询所有送水工信息
* 3 根据ID查询对应的送水历史信息
* 4 将以上信息渲染到前端页面上
* 5 跳转到“修改送水历史”页面
* @param hid 送水历史ID
* @param model
* @return “修改送水历史”页面
*/
@RequestMapping("/preUpdateHis/{hid}")
public String preUpdateHistory(@PathVariable("hid") Integer hid, Model model) {
List<Customer> custList = customerService.listCustomer();
List<Worker> workerList = workerService.listWorker();
History history = historyService.getHistoryById(hid);
// 将查询的数据渲染到前端页面,完成数据的回显
model.addAttribute("custList",custList);
model.addAttribute("workerList",workerList);
model.addAttribute("history",history);
// 跳转到“修改送水历史”页面
return "historyUpdate";
}
/**
* 点击“提交”按钮修改送水历史信息,修改完毕重定向执行“送水历史列表”,显示已修改的“送水历史信息”
* 步骤:
* 1 将送水工ID和客户ID注入到History对象
* 2 调用HistoryService对象的updateHistory方法完成修改
* 3 修改完毕重定向执行“送水历史列表”
* @param workerId 送水历史对应的送水工ID
* @param custId 送水历史对应的客户ID
* @param history 送水历史信息
* @return 重定向执行“送水历史列表”
*/
@RequestMapping(value="/updateHis",method=RequestMethod.POST)
public String updateHistory(Integer workerId,Integer custId,History history) {
log.info(" update custId id = "+custId);
log.info(" update worker id = "+workerId);
log.info(" update History = "+history);
Worker worker = new Worker();
worker.setWid(workerId);
Customer customer = new Customer();
customer.setCid(custId);
history.setCustomer(customer);
history.setWorker(worker);
// 修改送水历史,返回受影响行数
int rows = historyService.updateHistory(history);
log.info("update history rows = "+rows);
return "redirect:/history/listHis";
}
3.6 编写送水历史列表页面 historyUpdate.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title> 冯宝宝送水后台管理系统</title>
<!--Bootstrap固定框架-->
<link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap.css}">
<link rel='stylesheet' th:href="@{/webjars/bootstrap/3.3.7/css/bootstrap-theme.css}">
<!--图标库-->
<link rel='stylesheet' th:href='@{/css/material-design-iconic-font.min.css}'>
<!--核心样式-->
<link rel="stylesheet" th:href="@{/css/style.css}">
</head>
<body>
<div id="viewport">
<!-- Sidebar -->
<div id="sidebar" th:replace="waterMainMenu::sidebar">
</div>
<!-- Content -->
<div id="content">
<nav class="navbar navbar-default" th:replace="waterMainMenu::navbar">
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<form class="form-horizontal" method="post" th:action="@{/history/updateHis}" >
<!-- type="hidden"表示提交表单将送水历史的hid作为隐藏域传入到后端的Controller
type="hidden" 特征:隐藏在表单内部,浏览器看不见hid
-->
<input type="hidden" th:value="${history.hid}" name="hid" />
<div class="form-group">
<div class="col-sm-2">送水工名称</div>
<div class="col-sm-5">
<select name="workerId" class="form-control">
<!-- 遍历每一个送水工选择
th:selected="${history.worker.wid eq worker.wid}"
条件成立:就将worker对象设置为选中状态
-->
<option th:each="worker : ${workerList}"
th:selected="${history.worker.workerName eq worker.workerName}"
th:value="${worker.wid}"
th:text="${worker.workerName}"/>
</select>
</div>
</div>
<div class="form-group">
<div class="col-sm-2">送水时间</div>
<div class="col-sm-5">
<input type="date" class="form-control"
th:value="${#dates.format(history.sendWaterTime,'yyyy-MM-dd')}"
name="sendWaterTime" placeholder="送水时间">
</div>
</div>
<div class="form-group">
<div class="col-sm-2">客户名称</div>
<div class="col-sm-5">
<!-- 以下拉列表框的形式展示所有的客户信息,实际的值是客户ID,显示的文本是客户名称-->
<select name="custId" class="form-control">
<!-- 遍历客户信息-->
<option th:each="cust : ${custList}"
th:selected="${cust.custName eq history.customer.custName}"
th:value="${cust.cid}" th:text="${cust.custName}"/>
</select>
</div>
</div>
<div class="form-group" >
<div class="col-sm-2">送水数量</div>
<div class="col-sm-5">
<input type="text" class="form-control"
th:value="${history.sendWaterCount}"
name="sendWaterCount" placeholder="送水数量"/>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-5">
<input type="submit" class="btn btn-primary" name="submit" value="提交">
<input type="reset" class="btn btn-warning" name="reset" value="取消">
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
4 批量删除
4.1 编写Mapper接口
int batchDeleteHistory(@Param("ids") List<Integer> ids);
4.2 编写Mppaer映射文件
<delete id="batchDeleteHistory" parameterType="list">
delete from tb_history
where hid in
<foreach collection="ids" item="hid" open="(" close=")" separator=",">
#{hid}
</foreach>
</delete>
批量删除就是in(sql语句: delete from tb_history where hid in (1,2,3))
<foreach>标签:该标签的作用是遍历集合类型的条件
item表示集合中每一个元素进行迭代时的别名.
index指 定一个名字,用于表示在迭代过程中,每次迭代到的位置.
open表示该语句以什么开始,separator表示在每次进行迭代之间以什么符号作为分隔 符.
close表示以什么结束
用来循环 collection(集合的父类) : 用来指定循环的数据的类型 可以填的值有:array,list,map item
4.3 编写Service接口
/**
* 批量删除
* @param idList 需要批量删除的送水历史id列表
* @return 受影响行数,大于0批量删除成功,否批量删除失败
*/
int batchDeleteHistory(String idList);
4.4 编写Service接口实现类
/**
* 批量删除
*
* @param idList 需要批量删除的送水历史id列表
* @return 受影响行数,大于0批量删除成功,否批量删除失败
*/
@Override
public int batchDeleteHistory(String idList) {
// 字符串转换为List集合
String[] split = StrUtil.split(idList, ",");
List<Integer> ids = new ArrayList<>();
for (String id : split) {
if (StrUtil.isNotEmpty(id)) {
ids.add(Integer.parseInt(id));
}
}
return historyMapper.batchDeleteHistory(id);
}
4.5 编写Controller控制器
/**
* 处理批量删除请求
* @param idList 前端传入的要删除的送水历史id列表
* @return OK 批量删除成功,Fail表示批量删除失败
*/
@RequestMapping(value="/batchDeleteHistory",method = RequestMethod.POST)
@ResponseBody
public String batchDeleteHistory(String idList) {
// 调用业务逻辑层方法进行批量删除
int rows = historyService.batchDeleteHistory(idList);
if (rows > 0) {
return "OK";
} else {
return "Fail";
}
}
historyList.html页面添加删除js
注意:怎么实现批量删除?首先要思考选中全选后,所有的数据都要被选中
1.要有一个主函数
2.全选和全不选的单击事件
3.找到批量删除的按钮和全选/全不选的按钮
<a class="btn btn-danger" href="#" id="batchDelete">批量删除</a>
再找到
<div class="col-md-12">
<table class="table table-hover table-striped">
<thead>
<tr>
<td>
<input type="checkbox" name="selectAll" id="selectAll" /> 全选/全不选
</td>
<td>送水历史编号</td>
<td>送水工名称</td>
<td>送水时间</td>
<td>客户名称</td>
<td>送水数量</td>
<td>操作</td>
</tr>
</thead>
<tbody>
<tr th:each="his : ${hisList}">
<td>
<input type="checkbox" th:value="${his.hid}" name="chkHistory"/>
</td>
<td th:text="${his.hid}"></td>
<td th:text="${his.worker.workerName}"></td>
<td th:text="${#dates.format(his.sendWaterTime,'yyyy-MM-dd')}"></td>
<td th:text="${his.customer.custName}"></td>
<td th:text="${his.sendWaterCount}"></td>
<td>
<a class="glyphicon glyphicon-remove" th:href="@{'/history/delHis/'+${his.hid}}"></a>
<a class="glyphicon glyphicon-edit" th:href="@{'/history/preUpdateHis/'+${his.hid}}"></a>
</td>
</tr>
</tbody>
</table>
</div>
4.获取两个按钮的id,怎么获取呢?用#{ }
5.然后再入口函数中写js代码()
<script>
$(function () {
//全不选或全选的单击事件
$("#selectAll").click(function () {
})
})
</script>
6.在id选择器中用元素选择器去全选
<script>
$(function () {
//全不选或全选的单击事件
$("#selectAll").click(function () {
// 使用元素属性选择器选择所有的“送水历史复选框” prop---> property
$("input[name=chkHistory]").prop("checked",$(this).prop("checked"));
})
})
</script>
prop是自身的方法 ,checked:选中
7.点击批量删除按钮触发事件
<script>
$(function() {
// 为“批量删除”按钮绑定一个“单击"事件,一旦触发将选中的所有“送水历史”复选框进行批量删除
$("#batchDelete").click(function(){
// 获取所有选中的“送水历史”复选框
let chkList = $("input[name=chkHistory]:checked");
// 条件成立:表示一个都没有选择,终止批量删除操作
if(chkList.length == 0) {
alert("请至少选择一项");
return;
}
// 存储复选框的id属性值
let ids = "";
// 获取所有选中的“送水历史”复选框id值
$(chkList).each(function(){ //循环遍历复选框id值
let id = $(this).val(); //获取到所有的
// 对选中的ID进行拼接
ids += ","+id; //回想一下sql删除语句 :delete from tb_history where hid in (1,2,3)
})
// 使用异步ajax技术,向后端发起批量删除请求 (拿到id之后,就是删除)
$.ajax({
url:'/history/batchDeleteHistory', //向后台发送的删除请求接口
data:{ //参数
idList:ids //后端方法需要传的参数
},
method:'POST', //请求方式
success: function(data,status) { //success:成功 data:数据(需要删除的)status:状态(删除后返回的状态)
if (data == "OK") {
alert("批量删除成功");
window.location.href = "/history/listHis";
} else {
alert("批量删除失败");
}
}
})
})
})
</script>
// 获取所有选中的“送水历史”复选框 let chkList = $("input[name=chkHistory]:checked");input: 标签
[name=chkHistory]:标签名称
checked:方法(自带)
8.拿到id之后就是删除了(需要我们使用的Ajax)
<script>
$(function() {
// 为“全选/全不选”复选框绑定单击事件,一旦触发该事件要么“全选”送水历史复选框,要么全不选
$("#selectAll").click(function() {
// 使用元素属性选择器选择所有的“送水历史复选框” prop---> property
$("input[name=chkHistory]").prop("checked",$(this).prop("checked"));
})
// 为“批量删除”按钮绑定一个“单击"事件,一旦触发将选中的所有“送水历史”复选框进行批量删除
$("#batchDelete").click(function(){
// 获取所有选中的“送水历史”复选框
let chkList = $("input[name=chkHistory]:checked");
// 条件成立:表示一个都没有选择,终止批量删除操作
if(chkList.length == 0) {
alert("请至少选择一项");
return;
}
// 存储复选框的id属性值
let ids = "";
// 获取所有选中的“送水历史”复选框id值
$(chkList).each(function(){
let id = $(this).val();
// 对选中的ID进行拼接
ids += ","+id;
})
// 使用异步ajax技术,向后端发起批量删除请求
$.ajax({
url:'/history/batchDeleteHistory',
data:{
idList:ids
},
method:'POST',
success: function(data,status) {
if (data == "OK") {
alert("批量删除成功");
window.location.href = "/history/listHis";
} else {
alert("批量删除失败");
}
}
})
})
})
</script>