一、批量删除
需要注意的点:
如何将页面上选中的checkbox提交给servlet?
页面端: name value
<input type=”checkbox” name=”ids” value=”${cus.id}”/>
将table包裹一层form表单
<!--form表单的提交只提交input输入框内的值-->
<form id="form" action="${pageContext.request.contextPath}/batchDel" method="post">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th><input type="checkbox" id="checkAll"/></th>
<th>序号</th>
<th>客户邮箱</th>
<th>客户登记</th>
<th>过期时间</th>
<th>编辑</th>
<th>删除</th>
</tr>
</thead>
<tbody>
<c:if test="${not empty customerList}">
<c:forEach items="${customerList}" var="cus" varStatus="vvv">
<tr>
<td scope="row"><input type="checkbox" name="ids" value="${cus.id}"/></td>
<td>${vvv.count}</td>
<td>${cus.address}</td>
<td>${cus.levelName}</td>
<td>${cus.overTimeStr}</td>
<td><a href="#"> <span class="glyphicon glyphicon-edit"></span></a></td>
<td><a onclick="delConfirm(${cus.id})"> <span class="glyphicon glyphicon-trash"></span></a></td>
</tr>
</c:forEach>
</c:if>
</tbody>
</table>
</form>
点击“批量删除”按钮,通过jquery提交表单
function batchDel(){
if(choiceNum!=0){
Confirm.show('溫馨提示', '您确定要删除这'+choiceNum+'条记录吗?', {
'Delete' : {
'primary' : true,
'callback' : function() {
// 此处进行删除操作 此处只需要提交表单即可
$("#form").submit();
}
}
});
}else{
alert("请选择您要删除的数据!");
}
}
后台如何获取提交的checkbox数据呢?
String[] ids = req.getParameterValues(“ids”);
Dao层通过jdbcTemplate批量删除方法进行操作
public int batchDel(String[] ids) {
String sql ="delete from customer where id=?";
int[] ints = jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement preparedStatement, int i) throws SQLException {
preparedStatement.setInt(1, Integer.valueOf(ids[i]));
}
@Override
public int getBatchSize() {
return ids.length;
}
});
System.out.println(Arrays.toString(ints));
return ints.length;
}
二、优化新增
1、如何选择客户类型
给 a 标签加事件
第一步获取a标签的文本内容即客户类型,将文本内容替换掉按钮上的内容,给隐藏的input输入框赋值
// obj 指的就是 a标签这个对象
function selectLevel(obj){
// obj 指的是js 对象
var levelName= $(obj).text();
$("#levelBtn").html(levelName+"<span class='caret'></span>");
$("[name='levelName']").val(levelName);
}
表单提交,只提交input输入框的内容,button上的文本内容是提交不了的,输入框不管隐藏或者不隐藏,都可以提交。<br /><**input type="hidden" class="form-control" id="inputPassword3" name="levelName" placeholder="客户类型"**><br />2、验证表单的数据<br /> 在提交表单的时候,添加一个onclick事件,如果该函数返回false,可以阻止事件冒泡。<br /> 一个摁钮,先执行onclick 事件,随即还会执行commit事件,我们为了不让它执行下一个commit事件,我们需要在onclick的时候给其返回false.
三、改造当前的项目(会用就可以)
思考:每写一个功能,就要写一个Servlet,真做一个大型的应用,岂不是要写一堆的Servlet ?
http://localhost:8080/HqComming/customer/add
可以截取到方法名,通过反射调用这个类中的方法即可
public class BaseServlet extends HttpServlet {
// http://localhost:8080/HqComming/customer/add
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//将来所有的子servlet,会先执行BaseSerlvet中的service
String requestURI = req.getRequestURI();// customer/add
System.out.println(requestURI);
int loc = requestURI.lastIndexOf("/");
// 获取到要执行的方法名
String methodName = requestURI.substring(loc + 1);
Class<? extends BaseServlet> clazz =this.getClass();//获取到当前正在执行的类的class对象
try {
Method method = clazz.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
method.invoke(this,req,resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
将来所有的Servlet都继承自BaseServlet即可
package com.qfedu.servlet;
import com.qfedu.pojo.Customer;
import com.qfedu.service.CustomerService;
import com.qfedu.service.impl.CustomerServiceImpl;
import org.apache.commons.beanutils.BeanUtils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;
//http://localhost:8080/HqComming/customer/add
@WebServlet("/customer/*")
public class CustomerPlusServlet extends BaseServlet {
CustomerService customerSerivce =new CustomerServiceImpl();
public void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("新增目前走的是最新的方法....");
/**
* Servlet
* 1、获取页面数据
* 2、给页面返回数据
* 3、跳转页面
*/
req.setCharacterEncoding("utf-8");
Map<String, String[]> parameterMap = req.getParameterMap();
Customer customer = new Customer();
try {
//将map中的数据,一一赋值给customer对象
/*
1、必须有一个空参构造
2、页面上的name值必须跟实体中的属性名保持一致
*/
BeanUtils.populate(customer,parameterMap);
} catch (Exception e) {
e.printStackTrace();
}
//进行数据的保存
int result = customerSerivce.save(customer);
if(result>0){
resp.sendRedirect(req.getContextPath()+"/customer/show");
}
}
public void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String id = req.getParameter("id");
int result = customerSerivce.deleteCustomerById(id);
if(result>0){
resp.sendRedirect(req.getContextPath()+"/customer/show");
}
}
public void batchDel(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//我们需要获取到页面传递过来的所有的id
String[] ids = req.getParameterValues("ids");
int result = customerSerivce.batchDel(ids);
if (result > 0) {
resp.sendRedirect(req.getContextPath() + "/customer/show");
}
}
public void show(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
List<Customer> list = customerSerivce.showList();
req.setAttribute("customerList",list);
// 跳转页面到showCustomer.jsp中,然后展示出来
//String contextPath = req.getContextPath();//获取虚拟路径名
req.getRequestDispatcher("/showCustomer.jsp").forward(req,resp);
}
}
此时我们的uri 从之前的一层请求变为两层请求,所以对页面的css,js有影响,每个css/js 都加上虚拟路径名
防止加载失败。
<script src="${pageContext.request.contextPath}/js/jquery-3.2.1.min.js" ></script>
四、编辑
1、点击编辑按钮—>去数据库查询出来该信息—>展示在编辑页面
我们先将数据存放到req域中,然后页面通过el表达式获取req中的数据,一定要在页面上编写一个隐藏的id文本框,为后面的保存做准备。
<input type=”hidden” value=”${cus.id}” name=”id”/>
展示数据的时候,客户类型是页面一加载就会出现的,所以我们要在$(function(){}) 将数据修改一下
$(function(){
// 页面一加载 就在类型下拉框展示数据库中的会员类型
$("#levelBtn").html("${cus.levelName}<span class='caret'></span>");
});
2、在页面上修改需要改动的数据,然后点击“保存”按钮,修改数据库中的数据
通过传递过去的id,修改数据。
五、查询
准备页面端
准备一个form表单
<form class="form-inline" action="${pageContext.request.contextPath}/customer/search" method="post">
<div class="form-group">
<input type="text" name="address" class="form-control" id="exampleInputEmail3" placeholder="客户邮箱">
</div>
<!-- Single button -->
<div class="btn-group">
<button id="levelBtn" type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
--客户类型-- <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a href="#" onclick="choiceLevel(this)">试用客户</a></li>
<li><a href="#" onclick="choiceLevel(this)">月卡用户</a></li>
<li><a href="#" onclick="choiceLevel(this)">年卡用户</a></li>
</ul>
<input type="hidden" name="levelName" />
</div>
<button type="submit" class="btn btn-info">查询</button>
</form>
一定要注意,选择下拉的时候一定要有一个隐藏的文本输入框。
接着要注意SQL的拼接:因为我们的用户有可能一个条件都不输入,也有可能输入一个或多个条件,要求sql比较的灵活
String sql = "select * from customer where 1=1 ";
String email = customer.getAddress();
String levelName= customer.getLevelName();
// 用户的查询,因为我们不知道用户会选择哪些进行查询,所以sql语句不固定
if(email!=null && !email.equals("")){
sql += " and email like '%"+email+"%'";
}
if(levelName!=null && !levelName.equals("")){
sql += " and level='"+levelName+"'";
}
System.out.println(sql);
将来还有修改 的,未完待续。
六、新增和修改的过期时间问题
一个日期如何新增一周,一月,一年
// 在此处给customer一个过期时间
Calendar calendar = Calendar.getInstance();
switch(customer.getLevelName()){
case "试用客户":
// 过期时间=当前时间+一周
calendar.add(Calendar.WEEK_OF_MONTH,1);
break;
case "月卡用户":
// 过期时间=当前时间+一月
calendar.add(Calendar.MONTH,1);
break;
case "年卡用户":
// 过期时间=当前时间+一年
calendar.add(Calendar.YEAR,1);
break;
}
System.out.println(calendar.getTime());
customer.setOverTime(calendar.getTime());
return customerDao.insert(customer);
修改:
不能通过修改用户的客户类型,调整过期时间。
可以通过修改过期时间,调整用户的过期时间。
req.getParameterMap();
获取到的数据都是String类型
但是我们使用了BeanUtils.populte方法。
map中数据向customer中的数据进行设置值。
Customer中的overTime 是Date类型的,req中获取的overTime是String类型的
就会报错?
BeanUtils.populate(customer,parameterMap);
设置值得原理是:从req的map集合中,获取值,调用customer中同名的属性的set方法。
页面中:
<input type=”datetime” name=”overTimeStr” class=”form-control” id=”inputPassword3” placeholder=”过期时间” value=”${cus.overTime}”>
将来会调用customer中的overTimeStr 属性的set方法。
public void setOverTimeStr(String overTime) throws ParseException {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
this.overTime = simpleDateFormat.parse(overTime);
}