Java EE入门(十五)——Servlet&JSP案例(用户信息系统)
Java EE入门(十五)——Servlet&JSP案例(用户信息系统)
iwehdio的博客园:https://www.cnblogs.com/iwehdio/
一、资源跳转
-
使用绝对路径,先要判断所定义的路径是给谁用。
- 如果要给客户端浏览器用,就要在其前面加虚拟路径,如浏览器访问、重定向。
- 如果要给服务器用,则直接写定义的资源路径,如转发。
-
request 是浏览器给服务器的请求,是服务器接收并处理的信息,不需要加虚拟路径。
- 转发:
request.getRequestDispatcher(资源路径).forward(request, response)
。 - 转发是在服务器端进行的跳转,可以共享 request 域中的数据。
- 转发:
-
response 是服务器给浏览器的响应,需要浏览器再访问其他资源,因此需要加虚拟路径。。
- 重定向:
response.sendRedirect(虚拟目录 + 资源路径)
。 - request 获取虚拟目录:
request.getContextPath()
。 - 则动态获取虚拟目录:
response.sendRedirect(request.getContextPath() + 资源路径)
。 - 重定向是在浏览器端进行的跳转,不能共享 request 域中的数据。
- 重定向:
-
jsp 页面最后要由浏览器解析,因此需要加虚拟路径。
- jsp 动态获取虚拟目录:
${pageContext.request.contextPath}
。
- jsp 动态获取虚拟目录:
-
转发和重定向的区别:
- 实际发⽣位置(端)不同,地址栏变换不同。
- 资源地址用法不同。给服务器⽤的直接从资源名开始写,给浏览器⽤的
要把应⽤名写上, - 能够去往的URL的范围不⼀样。
- 传递数据的类型不同。转发的request对象可以传递各种类型的数据,包括对象,重定向只能传递字符串。
- 跳转的时间不同。转发时,执⾏到跳转语句时就会⽴刻跳转。重定向,整个⻚⾯执⾏完之后才执⾏跳转。
-
什么时候使用转发,什么时候使用重定向?
- 需要 request 域中数据的时候,必须用请求转发。
- 需要访问站外资源的时候用重定向。
- 典型的应⽤场景:
- 转发: 访问 Servlet 处理业务逻辑,然后转发到 jsp 显示处理结果,浏览器地址栏不变。
- 重定向: 提交表单,处理成功后重定向到另⼀个 jsp,防⽌表单重复提交,浏览器地址栏变了。
-
案例中转发与重定向的选择:
- UserListServlet:查询完所有用户后,需要到 list.jsp 显示查询结果,使用转发。
- LoginServlet:登录。
- 验证码错误或密码错误,需要携带错误信息,到 login.jsp 显示处理结果,使用转发。
- 全部正确登录成功,登录业务处理成功,使用重定向。而且需要把用户信息存入 session 。
- AddListServlet / DelUserServlet:添加 / 删除用户信息成功后,需要显示更新后用户列表,重定向到 UserListServlet 再转发到 list.jsp 显示查询结果。
- FindServlet:按 id 查询用户后,需要携带数据到 update.jsp 重显,使用转发。而且作为修改功能的一部分,此次请求还没有被完成,使用转发。
- UpdateUserServlet:修改用户信息成功后,需要显示更新后用户列表,重定向到 UserListServlet 再转发到 list.jsp 显示查询结果。作为修改功能的一部分,此次请求已经被完成,使用重定向。
二、标准类封装
-
BeanUtils 工具类:一般用于封装从 request 域中获取的 Map 集合。
-
使用 Map 集合获取的一般是以 post 方式提交的 form 表单数据。
-
调用
populate(Object obj, Map map)
方法,将Map集合中的键值对封装为 JavaBean 中的属性和属性值。 -
实现:
//获取request域中的参数,返回Map集合 Map<String, String[]> map = request.getParameterMap(); //创建一个空的对象接收 User loginuser = new User(); try { //按键值对封装 BeanUtils.populate(loginuser, map); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); }
-
-
Spring JDBC 下的 JavaBean 对象的封装实现类 RowMapper。
-
可以使用匿名类自定义,一般使用
BeanPropertyPowMapper
实现类自动封装。 -
一般用于接收 JdbcTemplate.query 方法 / JdbcTemplate.queryForObject 方法返回的结果,将其封装为相应的 JavaBean 对象的数组 / JavaBean 对象,需要传入泛型和字节码对象。
-
格式为
new BeanPropertyRowMapper<类型>(类型.class)
。 -
实现:
//查询id对应的信息 String sql = "select * from JSP where id = ?"; return template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), id);
-
三、用户信息系统案例分析
-
需求分析:
- 基础功能:
- 列表显示。
- 用户登录。
- 添加用户信息。
- 删除单个用户。
- 修改用户信息。
- 综合功能:
- 批量删除选中用户。
- 分页列表显示。
- 条件查询。
- 基础功能:
-
Java 后端项目结构:
-
三层架构:
- 表示层:web 包下的 Servlet ,接收前端请求,封装后调用业务逻辑层。完成后转发到 jsp 页面显示。
- 业务逻辑层:
- UserService 接口:定义业务逻辑层的功能与传入传出参数类型。
- UserServiceImpl 实现类:组合数据访问层中的底层数据操作方法,完成表示层要求的复杂功能。
- 数据访问层:
- UserDao 接口:定义数据访问层的功能与传入传出参数类型。
- UserDaoImpl 实现类:定义了对数据库最基础的增删改查操作。
-
项目总体结构:
- Java 后端项目结构:
- src / cn.iwehdio 。
- druid.properties 配置文件。
- Web 前端项目结构:
- css / js / fonts:BootStrap、JQuery 相关依赖。
- WEB-INF / lib:数据库、Servlet 相关依赖 jar 包。
- index.jsp:项目初始页面。
- list.jsp:列表显示页面。
- login.jsp:登录页面。
- add.jsp:添加用户信息页面。
- update.jsp:修改用户信息页面。
- Java 后端项目结构:
-
表示层 Servlet 编写流程:
- 如果是 post 请求方式,设置编码字符集。
- 使用 request 下的
.getParameter
方法获取单个参数,使用.getParameterMap
方法按键值对 (form表单中的 name : value 对) 获取多个参数。 - 判断输入参数的合法性,处理空指针异常。
- 如果获取到参数为已有的对象,可以用
BeanUtils.populate(类, map)
封装为对象。 - 创建业务逻辑层接口引用下的实现类对象:
UserService service = new UserServiceImpl()
。 - 对获取的参数进行处理,并调用 service 下的方法实现业务逻辑。
- 如果有需要存储的返回的数据,根据其性质存储到 request 域
request.setAttribute()
,或 session 域session.setAttribute()
。 - 根据需求,转发或重定向到 jsp 页面或其他 Servlet 。
-
业务逻辑层 service 编写流程:
- 创建成员变量,数据操作层对象:
private UserDao dao = new UserDaoImpl()
。 - 重写接口中定义的方法。
- 处理参数的异常或空指针情况。
- 对表示层 Servlet 的输入进行处理,使其符合数据操作层的底层接口定义。
- 如果需要输出,对数据操作层 Dao 的输出进行处理,使其符合表示层 Servlet 的接收形式。
- 创建成员变量,数据操作层对象:
-
数据操作层 dao 编写流程:
- 创建成员变量,Jdbc 工具类对象:
private JdbcTemplate template = new JdbcTemplate((JDBCUtils.getDataSource()))
。 - 重写接口中定义的方法。
- 定义初始 SQL 语句。
- 根据输入,对 SQL 语句进行拼接和赋值。
- 使用 Jdbc 工具类下的方法进行查询。
- 创建成员变量,Jdbc 工具类对象:
-
创建数据库:
USE db1; CREATE TABLE jsp( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(20) NOT NULL, gender VARCHAR(5), age INT, qq VARCHAR(20), email VARCHAR(50) );
四、基础功能实现
-
列表显示:
-
创建 User 对象:
public class User { private int id; private String name; private String gender; private int age; private String qq; private String email; private String username; private String password; /* set / get / toString 方法 */ }
-
UserListServlet:
- 没有传入的参数。
- 使用
service.findAll()
方法获取数据库中的所有用户,并将结果存入 request。 - 转发到 list.jsp 。
@WebServlet("/userListServlet") public class UserListServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { UserService service = new UserServiceImpl(); List<User> users = service.findAll(); request.setAttribute("users", users); request.getRequestDispatcher("/list.jsp").forward(request,response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
-
UserServiceImpl:
@Override public List<User> findAll() { return dao.findAll(); }
-
UserDaoImpl:
@Override public List<User> findAll() { String sql = "select * from jsp"; List<User> users = template.query(sql, new BeanPropertyRowMapper<User>(User.class)); return users; }
-
index.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"/> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <meta name="viewport" content="width=device-width, initial-scale=1"/> <title>首页</title> <link href="css/bootstrap.min.css" rel="stylesheet"> <script src="js/jquery-2.1.0.min.js"></script> <script src="js/bootstrap.min.js"></script> <script type="text/javascript"> </script> </head> <body> <div> <h2 style="margin-left: 50px">${sessionScope.user.username}</h2> </div> <div align="center"> <a href="${pageContext.request.contextPath}/pageListServlet" style="text-decoration:none;font-size:33px">查询所有用户信息 </a> </div> </body> </html>
-
-
用户登录:
-
LoginServlet:
- 获取填写到文本框中的验证码。
- 从 session 中获取 CheckCodeServlet 生成的验证码并进行比对。
- 验证码比对失败则直接存入错误信息并转发到登录页面。
- 验证码比对成功则获取账号密码参数。
- 使用
service.login()
方法获取账号密码匹配的用户信息。 - 如果匹配得到,则重定向到初始页面 index.jsp 。
- 如果匹配不到,则存入错误信息并转发到登录页面。
@WebServlet("/loginServlet") public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); String verifycode = request.getParameter("verifycode"); HttpSession session = request.getSession(); String server_checkcode = (String)session.getAttribute("CHECKCODE_SERVER"); session.removeAttribute("CHECKCODE_SERVER"); if(!server_checkcode.equalsIgnoreCase(verifycode)){ request.setAttribute("login_msg", "验证码错误"); request.getRequestDispatcher("/login.jsp").forward(request, response); return; } Map<String, String[]> map = request.getParameterMap(); User user = new User(); try { BeanUtils.populate(user, map); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } UserService service = new UserServiceImpl(); User loginUser = service.login(user); if(loginUser != null){ session.setAttribute("user", loginUser); response.sendRedirect(request.getContextPath() + "/index.jsp"); } else { request.setAttribute("login_msg", "用户名密码错误"); request.getRequestDispatcher("/login.jsp").forward(request, response); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
-
UserServiceImpl:
@Override public User login(User user) { return dao.checkNameAndPassword(user.getUsername(), user.getPassword()); }
-
UserDaoImpl:
@Override public User checkNameAndPassword(String username, String password) { try { String sql = "select * from JSP where username = ? and password = ?"; User user = template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), username, password); return user; } catch (Exception e){ e.printStackTrace(); return null; } }
-
-
添加用户信息:
-
AddListServlet:
- list.jsp 页面下点击添加,进入 add.jsp ,在此页面下再点击提交,调用 addListServlet 。
- 使用 map 集合获取填写的用户信息并封装为 JavaBean 。
- 调用
service.addUser()
方法添加用户信息。 - 重定向到 UserListServlet 显示添加结果。
@WebServlet("/addListServlet") public class AddListServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); Map<String, String[]> map = request.getParameterMap(); User user = new User(); try { BeanUtils.populate(user, map); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } UserService service = new UserServiceImpl(); service.addUser(user); response.sendRedirect(request.getContextPath() + "/pageListServlet"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
-
UserServiceImpl:
@Override public void addUser(User user) { dao.add(user); }
-
UserDaoImpl:
@Override public void add(User user) { String sql = "insert into JSP values(null, ?, ?, ?, ?, ?, null, null)"; template.update(sql, user.getName(), user.getGender(), user.getAge(), user.getQq(), user.getEmail()); }
-
add.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <!-- HTML5文档--> <!DOCTYPE html> <!-- 网页使用的语言 --> <html lang="zh-CN"> <head> <!-- 指定字符集 --> <meta charset="utf-8"> <!-- 使用Edge最新的浏览器的渲染方式 --> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- viewport视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。 width: 默认宽度与设备的宽度相同 initial-scale: 初始的缩放比,为1:1 --> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --> <title>添加用户</title> <!-- 1. 导入CSS的全局样式 --> <link href="css/bootstrap.min.css" rel="stylesheet"> <!-- 2. jQuery导入,建议使用1.9以上的版本 --> <script src="js/jquery-2.1.0.min.js"></script> <!-- 3. 导入bootstrap的js文件 --> <script src="js/bootstrap.min.js"></script> </head> <body> <div class="container"> <center><h3>添加联系人页面</h3></center> <form action="${pageContext.request.contextPath}/addListServlet" method="post"> <div class="form-group"> <label for="name">姓名:</label> <input type="text" class="form-control" id="name" name="name" placeholder="请输入姓名"> </div> <div class="form-group"> <label>性别:</label> <input type="radio" name="gender" value="男" checked="checked"/>男 <input type="radio" name="gender" value="女"/>女 </div> <div class="form-group"> <label for="age">年龄:</label> <input type="text" class="form-control" id="age" name="age" placeholder="请输入年龄"> </div> <div class="form-group"> <label for="qqnumber">QQ:</label> <input type="text" class="form-control" name="qq" id="qqnumber" placeholder="请输入QQ号码"/> </div> <div class="form-group"> <label for="email">Email:</label> <input type="text" class="form-control" name="email" id="email" placeholder="请输入邮箱地址"/> </div> <div class="form-group" style="text-align: center"> <input class="btn btn-primary" type="submit" value="提交" /> <input class="btn btn-default" type="reset" value="重置" /> <input class="btn btn-default" type="button" value="返回" /> </div> </form> </div> </body> </html>
-
-
删除单个用户:
-
DelUserServlet:
- 获取所要删除的用户的 id。
- 使用
service.delUserById()
方法删除用户信息。 - 重定向到 UserListServlet 显示删除结果。
@WebServlet("/delUserServlet") public class DelUserServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id = request.getParameter("id"); UserService service = new UserServiceImpl(); service.delUserById(id); response.sendRedirect(request.getContextPath() + "/pageListServlet"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
-
UserServiceImpl:
- 注意将传入的 String 类型参数转换为 int 类型。
@Override public void delUserById(String id) { dao.delete(Integer.parseInt(id)); }
-
UserDaoImpl:
@Override public void delete(int id) { String sql = "delete from JSP where id = ?"; template.update(sql, id); }
-
删除按钮操作:
<!-- HTML中的删除按钮 --> <a class="btn btn-default btn-sm" href="javascript:deleteUser(${i.id})">删除</a> <!-- JS中绑定按钮并提示 --> <script> function deleteUser(id) { if(confirm("确认删除?")){ location.href = "${pageContext.request.contextPath}/delUserServlet?id=" + id; } } </script>
-
-
修改用户信息:
-
FindServlet / UpdateServlet:
- list.jsp 页面下点击修改,调用 FindServlet 。找到对于用户信息后,转发 update.jsp ,在此页面下再点击提交,调用 UpdateServlet 。
- FindServlet ,调用
service.findUserById()
方法寻找用户信息,转发到 update.jsp。 - 将用户信息重显,按下提交到 UpdateServlet。
- UpdateServlet ,使用 map 集合获取填写的用户信息并封装为 JavaBean 。
- 调用
service.update()
方法添加用户信息。 - 重定向到 UserListServlet 显示添加结果。
@WebServlet("/findServlet") public class FindServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id = request.getParameter("id"); UserService service = new UserServiceImpl(); User user = service.findUserById(id); request.setAttribute("user", user); request.getRequestDispatcher("/update.jsp").forward(request, response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } } @WebServlet("/updateServlet") public class UpdateServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); Map<String, String[]> map = request.getParameterMap(); User user = new User(); try { BeanUtils.populate(user, map); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } UserService service = new UserServiceImpl(); service.update(user); response.sendRedirect(request.getContextPath() + "/pageListServlet"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
-
UserServiceImpl:
@Override public User findUserById(String id) { return dao.findById(Integer.parseInt(id)); } @Override public void update(User user) { dao.update(user); }
-
UserDaoImpl:
@Override public User findById(int id) { String sql = "select * from JSP where id = ?"; return template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), id); } @Override public void update(User user) { String sql = "update JSP set name = ?, gender = ?, age = ?, qq = ?, email = ? where id = ?"; template.update(sql, user.getName(), user.getGender(), user.getAge(), user.getQq(), user.getEmail(), user.getId()); }
-
update.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>修改用户</title> <link href="css/bootstrap.min.css" rel="stylesheet"> <script src="js/jquery-2.1.0.min.js"></script> <script src="js/bootstrap.min.js"></script> </head> <body> <div class="container" style="width: 400px;"> <h3 style="text-align: center;">修改联系人</h3> <form action="${pageContext.request.contextPath}/updateServlet" method="post"> <input type="hidden" name="id" value="${user.id}"> <div class="form-group"> <label for="name">姓名:</label> <input type="text" class="form-control" id="name" name="name" value="${user.name}" readonly="readonly" placeholder="请输入姓名" /> </div> <div class="form-group"> <label>性别:</label> <c:if test="${user.gender=='男'}"> <input type="radio" name="gender" value="男" checked/>男 <input type="radio" name="gender" value="女" />女 </c:if> <c:if test="${user.gender=='女'}"> <input type="radio" name="gender" value="男" />男 <input type="radio" name="gender" value="女" checked/>女 </c:if> </div> <div class="form-group"> <label for="age">年龄:</label> <input type="text" class="form-control" id="age" name="age" value="${user.age}" placeholder="请输入年龄" /> </div> <div class="form-group"> <label for="qq">QQ:</label> <input type="text" class="form-control" name="qq" id="qq" value="${user.qq}" placeholder="请输入QQ号码"/> </div> <div class="form-group"> <label for="email">Email:</label> <input type="text" class="form-control" name="email" id="email" value="${user.email}" placeholder="请输入邮箱地址"/> </div> <div class="form-group" style="text-align: center"> <input class="btn btn-primary" type="submit" value="提交" /> <input class="btn btn-default" type="reset" value="重置" /> <input class="btn btn-default" type="button" value="返回"/> </div> </form> </div> </body> </html>
-
五、综合功能实现
-
批量删除选中用户:
-
DelSelectServlet:
- list.jsp 中删除选中按钮提交。
- 使用
.getParameterValues()
方法获取所有被选中的用户。 - 使用
service.delSelect()
方法删除选中的用户。 - 重定向到 UserListServlet 显示删除后的结果。
@WebServlet("/delSelectServlet") public class DelSelectServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); String[] ids = request.getParameterValues("uid"); UserService service = new UserServiceImpl(); service.delSelect(ids); response.sendRedirect(request.getContextPath() + "/pageListServlet"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
-
UserServiceImpl:
@Override public void delSelect(String[] ids) { for (String id: ids) { dao.delete(Integer.parseInt(id)); } }
-
list.jsp 中的全选和提示:
<!-- 删除选中按钮 --> <a class="btn btn-primary" href="javascript:void(0)" id="delSelect">删除选中</a> <!-- 全选和提示 --> <script> window.onload = function () { document.getElementById("delSelect").onclick = function () { if(confirm("确认删除选中?")) document.getElementById("tableForm").submit(); } document.getElementById("AllCb").onclick = function () { var Cbs = document.getElementsByName("uid"); for(var i=0; i<Cbs.length; i++){ Cbs[i].checked = this.checked; } } } </script>
-
更进一步,如何实现在分页后实现跨页的选中删除?
-
-
分页列表显示:
-
前端:分页条的样式,选中和禁用。
-
封装 Page 对象:
- 包括当前页码、每页显示条目数、总页码、总条目数和当前页面所要显示的用户信息列表。
public class Page<T> { private int currentPage; private int rows; private int totalPage; private int totalCount; private List<T> list; /* set / get / toString 方法 */ }
-
PageListServlet:
- 获取当前页码和每页条目数。
- 处理传入的页码不合法和每页条目数缺省的情况。
- 使用
service.listByPage()
方法,按当前页码和每页条目数获取 Page 对象。 - 将 Page 对象存入 request 域中,转发到 list.jsp。
@WebServlet("/pageListServlet") public class PageListServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); String currentPage = request.getParameter("currentPage"); String rows = request.getParameter("rows"); Map<String ,String[]> condition = request.getParameterMap(); if(currentPage == null || "".equals(currentPage)){ currentPage = "1"; } if(rows == null || "".equals(rows)){ rows = "5"; } UserService service = new UserServiceImpl(); Page<User> page = service.listByPage(currentPage, rows, condition); request.setAttribute("page", page); request.setAttribute("condition", condition); request.getRequestDispatcher("/list.jsp").forward(request, response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
-
UserServiceImpl:
- 使用
.getCount()
方法获取总条目数。 - 使用
.findByPage()
方法获取当前页的用户信息。
@Override public Page<User> listByPage(String _currentPage, String _rows, Map<String, String[]> condition) { Page<User> page = new Page<User>(); int currentPage = Integer.parseInt(_currentPage); int rows = Integer.parseInt(_rows); int totalCount = dao.getCount(condition); int totalPage = (totalCount % rows) == 0 ? totalCount / rows : totalCount / rows + 1; if(currentPage < 1 ){ currentPage = 1; } else if(currentPage > totalPage){ currentPage = totalPage; } List<User> list = dao.findByPage((currentPage-1)*rows, rows, condition); page.setCurrentPage(currentPage); page.setRows(rows); page.setTotalCount(totalCount); page.setList(list); page.setTotalPage(totalPage); return page; }
- 使用
-
UserDaoImpl:
- 聚合函数和分页查询。
@Override public int getCount(Map<String, String[]> condition) { String sql = "select count(*) from JSP where 1=1 "; StringBuilder sb = new StringBuilder(sql); Set<String> keys = condition.keySet(); List<Object> param = new ArrayList<Object>(); for (String key : keys) { if ("currentPage".equals(key) || "rows".equals(key)){ continue; } String value = condition.get(key)[0]; if(value != null && !"".equals(value)) { sb.append(" and " + key + " like ?"); param.add("%" + value + "%"); } } sql = sb.toString(); return template.queryForObject(sql, Integer.class, param.toArray()); } @Override public List<User> findByPage(int i, int rows, Map<String, String[]> condition) { String sql = "select * from JSP where 1=1 "; StringBuilder sb = new StringBuilder(sql); Set<String> keys = condition.keySet(); List<Object> param = new ArrayList<Object>(); for (String key : keys) { if ("currentPage".equals(key) || "rows".equals(key)){ continue; } String value = condition.get(key)[0]; if(value != null && !"".equals(value)) { sb.append(" and " + key + " like ?"); param.add("%" + value + "%"); } } sb.append(" limit ?, ?"); param.add(i); param.add(rows); sql = sb.toString(); return template.query(sql, new BeanPropertyRowMapper<User>(User.class), param.toArray()); }
-
list.jsp 中的分页条:
<div> <nav aria-label="Page navigation"> <ul class="pagination"> <c:if test="${requestScope.page.currentPage==1}"> <li class="disabled"> </c:if> <c:if test="${requestScope.page.currentPage!=1}"> <li> </c:if> <a href="${pageContext.request.contextPath}/pageListServlet?currentPage=${requestScope.page.currentPage-1}&rows=5" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> <c:forEach begin="1" end="${requestScope.page.totalPage}" var="i"> <c:if test="${requestScope.page.currentPage==i}"> <li class="active"><a href="${pageContext.request.contextPath}/pageListServlet?currentPage=${i}&rows=5">${i}</a></li> </c:if> <c:if test="${requestScope.page.currentPage!=i}"> <li><a href="${pageContext.request.contextPath}/pageListServlet?currentPage=${i}&rows=5">${i}</a></li> </c:if> </c:forEach> <c:if test="${requestScope.page.currentPage==requestScope.page.totalPage}"> <li class="disabled"> </c:if> <c:if test="${requestScope.page.currentPage!=requestScope.page.totalPage}"> <li> </c:if> <a href="${pageContext.request.contextPath}/pageListServlet?currentPage=${requestScope.page.currentPage+1}&rows=5" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> <span style="font-size:25px;margin: 15px"> 共${requestScope.page.totalCount}项,第${requestScope.page.currentPage}页 </span> </ul> </nav> </div>
-
-
条件查询:
-
PageListServlet 改造:
- list.jsp 中搜索按钮提交表单。
- 获取提交的参数 map 为 condition。
- 改造
service.listByPage()
方法,增加 condition 为参数。
-
UserServiceImpl:
- 改造
.getCount()
方法和.findByPage()
方法,增加 condition 为参数。
- 改造
-
UserDaoImpl:
- 对传入的 condition 进行条件模糊查询。
-
list.jsp 完整:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>用户信息管理系统</title> <link href="css/bootstrap.min.css" rel="stylesheet"> <script src="js/jquery-2.1.0.min.js"></script> <script src="js/bootstrap.min.js"></script> <style type="text/css"> td, th { text-align: center; } </style> <script> function deleteUser(id) { if(confirm("确认删除?")){ location.href = "${pageContext.request.contextPath}/delUserServlet?id=" + id; } } window.onload = function () { document.getElementById("delSelect").onclick = function () { if(confirm("确认删除选中?")) document.getElementById("tableForm").submit(); } document.getElementById("AllCb").onclick = function () { var Cbs = document.getElementsByName("uid"); for(var i=0; i<Cbs.length; i++){ Cbs[i].checked = this.checked; } } } </script> </head> <body> <div class="container"> <h3 style="text-align: center">用户信息列表</h3> <div style="float: left"> <form action="${pageContext.request.contextPath}/pageListServlet" class="form-inline" method="post"> <div class="form-group"> <label for="InputName">姓名</label> <input type="text" class="form-control" value="${requestScope.condition.name[0]}" name="name" id="InputName" > </div> <div class="form-group"> <label for="InputGender">性别</label> <input type="text" class="form-control" value="${requestScope.condition.gender[0]}" name="gender" id="InputGender"> </div> <div class="form-group"> <label for="InputAge">年龄</label> <input type="text" class="form-control" value="${requestScope.condition.age[0]}" name="age" id="InputAge"> </div> <button type="submit" class="btn btn-default">搜索</button> </form> </div> <div style="float: right;margin: 5px"> <a class="btn btn-primary" href="${pageContext.request.contextPath}/add.jsp">添加联系人</a> <a class="btn btn-primary" href="javascript:void(0)" id="delSelect">删除选中</a> </div> <form action="${pageContext.request.contextPath}/delSelectServlet" id="tableForm"> <table border="1" class="table table-bordered table-hover"> <tr class="success"> <th><input type="checkbox" id="AllCb"></th> <th>编号</th> <th>姓名</th> <th>性别</th> <th>年龄</th> <th>QQ</th> <th>邮箱</th> <th>操作</th> </tr> <c:forEach items="${requestScope.page.list}" var="i" varStatus="s"> <tr> <th><input type="checkbox" name="uid" value="${i.id}"></th> <td>${s.count}</td> <td>${i.name}</td> <td>${i.gender}</td> <td>${i.age}</td> <td>${i.qq}</td> <td>${i.email}</td> <td> <a class="btn btn-default btn-sm" href="${pageContext.request.contextPath}/findServlet?id=${i.id}">修改</a> <a class="btn btn-default btn-sm" href="javascript:deleteUser(${i.id})">删除</a> </td> </tr> </c:forEach> </table> </form> <div> <nav aria-label="Page navigation"> <ul class="pagination"> <c:if test="${requestScope.page.currentPage==1}"> <li class="disabled"> </c:if> <c:if test="${requestScope.page.currentPage!=1}"> <li> </c:if> <a href="${pageContext.request.contextPath}/pageListServlet?currentPage=${requestScope.page.currentPage-1}&rows=5&name=${requestScope. condition.name[0]}&age=${requestScope.condition.age[0]}&gender=${requestScope.condition.gender[0]}" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> <c:forEach begin="1" end="${requestScope.page.totalPage}" var="i"> <c:if test="${requestScope.page.currentPage==i}"> <li class="active"><a href="${pageContext.request.contextPath}/pageListServlet?currentPage=${i}&rows=5&name=${requestScope. condition.name[0]}&age=${requestScope.condition.age[0]}&gender=${requestScope.condition.gender[0]}">${i}</a></li> </c:if> <c:if test="${requestScope.page.currentPage!=i}"> <li><a href="${pageContext.request.contextPath}/pageListServlet?currentPage=${i}&rows=5&name=${requestScope. condition.name[0]}&age=${requestScope.condition.age[0]}&gender=${requestScope.condition.gender[0]}">${i}</a></li> </c:if> </c:forEach> <c:if test="${requestScope.page.currentPage==requestScope.page.totalPage}"> <li class="disabled"> </c:if> <c:if test="${requestScope.page.currentPage!=requestScope.page.totalPage}"> <li> </c:if> <a href="${pageContext.request.contextPath}/pageListServlet?currentPage=${requestScope.page.currentPage+1}&rows=5&name=${requestScope. condition.name[0]}&age=${requestScope.conditon.age[0]}&gender=${requestScope.condition.gender[0]}" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> <span style="font-size:25px;margin: 15px"> 共${requestScope.page.totalCount}项,第${requestScope.page.currentPage}页 </span> </ul> </nav> </div> </div> </body> </html>
-
iwehdio的博客园:[https://www.cnblogs.com/iwehdio/](https://www.cnblogs.com/iwehdio/)