【知了堂学习笔记】分页查询—第二章

来源:互联网 发布:淘宝素材主图图片大全 编辑:程序博客网 时间:2024/05/22 02:01

上一章我们整理了无条件的分页查询,实现过程较为简单。今天带来的是条件查询之后的内容进行分页。

先上效果图:


如何实现这个效果呢?先看我的目录结构



首先说一下思路,在上一篇博客实现的内容上我们需要加一些点功能:第一、多条件查询,我们如何在多个条件选择后得到我们想要的结果。第二、多条件查询结果后

点击下一页如何带着上一次的查询条件。第三、在删除之后,如何回到之前的页面,如何在删除最后一页最后一条数据后自动跳到上一页。

第一步:JavaBean

第一个是Stu,这个用来封装学生的信息,第二个是PageBean,用来封装显示页面的属性,包括当前页码pc、总页数tp(这个不需要手动设置,直接用tr/ps 判断即可得到)、总记录数tr(满足条件的数据总记录数)、每页的记录条数ps、装多个Stu的beanList(当前页的记录 ),在上一次的基础上加了一个 url属性,主要解决的是,多条件查询得到结果后,切换页面条件得以保留,防止条件丢失。

package com.jie.bean;public class Stu {private int id;private String name;private String sex;private int age;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Stu [age=" + age + ", id=" + id + ", name=" + name + ", sex="+ sex + "]";}}

package com.jie.bean;import java.util.List;public class PageBean <T>{private int pc;//当前页码private int tp;//总页数private int tr;//总记录数private int ps;//每页记录数private List<T> beanList;//当前页的记录private String url;//url后的条件public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}public int getPc() {return pc;}public void setPc(int pc) {this.pc = pc;}public int getTp() { tp = tr/ps;return tr%ps==0?tp:tp+1;}public int getTr() {return tr;}public void setTr(int tr) {this.tr = tr;}public int getPs() {return ps;}public void setPs(int ps) {this.ps = ps;}public List<T> getBeanList() {return beanList;}public void setBeanList(List<T> beanList) {this.beanList = beanList;}}

第二步:我们先来看看dao层

多条件查询查询后,总记录数就不在是之前的了,而是我们满足条件之后的记录数。这时我们就需要考虑怎么获取现在的记录数。当页面输入的数据时在Servlet中被封

装成一个Stu对象。而当我们页面没有输入条件时,它的属性就为空或者为零,默认为全部查询。所以我们这里会做一个判断,如果满足条件我们就在whereSql语句用

StringBuilder的append()方法把条件添加进去,而后面的参数赋值我用了一个List集合,满足条件就把参数加到集合中,然后把它转化为数组。然后通过DBUtils的ScalarHandler

结果集得到总记录数(tr)。而后面pc(当前页码)进行了一个判断,当pc(当前页码)>tb(总页数),即当前页大于总页数时pb赋值给pc,这里在删除最后一页最后一条数据

后自动跳到上一页时起作用。最后通过pc(当前页码)、ps(每页记录数)得到分页条件 limit  (pc-1)*ps,ps, 然后拼凑前面的sql语句(查询条件),组成最终的sql语句,查询得到

BeanListHandler结果集,赋值给beanList(当前页的记录),设置给pb(PageBeand对象),并返回给servlet层。

package com.jie.dao;import java.sql.Connection;import java.sql.SQLException;import java.util.ArrayList;import java.util.List;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.handlers.BeanListHandler;import org.apache.commons.dbutils.handlers.ScalarHandler;import com.jie.bean.PageBean;import com.jie.bean.Stu;import com.jie.utils.JdbcUtils;public class StuDao {public PageBean<Stu> query(Stu s,int pc,int ps) throws SQLException{//创建pbPageBean<Stu> pb = new PageBean<Stu>();//设置已有条件  pspb.setPs(ps);//设置trQueryRunner qr = new QueryRunner();Connection conn = JdbcUtils.getConnection();StringBuilder cntSql = new StringBuilder("select count(*) from stu");StringBuilder whereSql = new StringBuilder(" where 1=1");List<Object> params = new ArrayList<Object>();int id = s.getId();if(id!=0){whereSql.append(" and id like ?");params.add("%" +id+ "%");}String name = s.getName();if(name!=null && !name.trim().isEmpty()){whereSql.append(" and name like ?");params.add("%" +name+ "%");}String sex = s.getSex();if(sex!=null && !sex.trim().isEmpty()){whereSql.append(" and sex=?");params.add(sex);}int age = s.getAge();if(age!=0){whereSql.append(" and age like ?");params.add("%" +age+ "%");}Number num =(Number)qr.query(conn,cntSql.append(whereSql).toString(), new ScalarHandler<Object>(), params.toArray());int tr = num.intValue();pb.setTr(tr);//当删除最后一页时进行判断 跳转前一页pc = pc>pb.getTp()?pb.getTp():pc;pb.setPc(pc); // 得到beanList StringBuilder sql = new StringBuilder("select * from stu");StringBuilder limitSql = new StringBuilder(" limit ?,?");params.add((pc-1)*ps);params.add(ps);List<Stu> benaList = qr.query(conn, sql.append(whereSql).append(limitSql).toString(), new BeanListHandler<Stu>(Stu.class), params.toArray());pb.setBeanList(benaList);conn.close();return pb;}public void delete(int id) throws SQLException {QueryRunner qr = new QueryRunner();Connection conn = JdbcUtils.getConnection();String sql = "delete from stu where id=?";Object[] param = {id};qr.update(conn, sql, param);conn.close();}}


第三步:Servlet

这里我们用了一个BaseServlet,然后用一个StuServlet去继承它,用反射的原理进行方法调用。在Servlet调用dao的query方法得到了PageBean对象 pb,在Servlet中我加了一getUrl方法,获取了项目路径+Servlet路径+queryString的部分内容(条件截取),这个Url就得到了上一次查询条件的绝对路径和条件参数,然后保设置 PageBean的对象pb中,最后把pb保存在request域中,转发回index.jsp。而后面的delete方法,一样的先截取上次的查询条件,然后转发到查询页面,回到上次查询的页码。


package com.jie.servlet;import java.io.IOException;import java.sql.SQLException;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.jie.bean.PageBean;import com.jie.bean.Stu;import com.jie.dao.StuDao;public class StuServlet extends BaseServlet {private static final long serialVersionUID = 1L;StuDao dao = new StuDao();public void query(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {Stu s = new Stu();String id = request.getParameter("id");if (id != null && !id.trim().isEmpty()) {s.setId(Integer.parseInt(id));}String name = request.getParameter("name");if (name != null && !name.trim().isEmpty()) {s.setName(name);}String sex = request.getParameter("sex");if (sex != null && !sex.trim().isEmpty()) {s.setSex(sex);}String age = request.getParameter("age");if (age != null && !age.trim().isEmpty()) {s.setAge(Integer.parseInt(age));}int pc = Integer.parseInt(request.getParameter("pc"));int ps = 10;StuDao dao = new StuDao();try {PageBean<Stu> pb = dao.query(s, pc, ps);pb.setUrl(getUrl(request));request.setAttribute("pb", pb);request.getRequestDispatcher("/index.jsp").forward(request,response);} catch (SQLException e) {e.printStackTrace();}}public String getUrl(HttpServletRequest request) {String contextPath = request.getContextPath();String servletPath = request.getServletPath();String queryString = request.getQueryString();int index = queryString.indexOf("&pc=");String url = contextPath + servletPath + "?"+ queryString.substring(0, index);return url;}public void delete(HttpServletRequest request, HttpServletResponse response)throws NumberFormatException, SQLException, ServletException,IOException {String id = request.getParameter("id");dao.delete(Integer.parseInt(id));int index = request.getQueryString().indexOf("/StuServlet?method=query");String url = request.getQueryString().substring(index);System.out.println(url);request.getRequestDispatcher(url).forward(request, response);}}

package com.jie.servlet;import java.io.IOException;import java.lang.reflect.Method;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public abstract class BaseServlet extends HttpServlet {private static final long serialVersionUID = 1L;       @Override    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {    request.setCharacterEncoding("utf-8");    //获取参数,根据参数调用的方法    String methodName =  request.getParameter("method");    if(methodName==null||methodName.trim().isEmpty()) {    throw new RuntimeException("没有传递参数,无法确定调用的方法");    }    //得到当前类的对象    Class clazz = this.getClass();    Method method = null;    try { method = clazz.getMethod(methodName,HttpServletRequest.class, HttpServletResponse.class);} catch (Exception e) {e.printStackTrace();}    //调用方法    try {method.invoke(this, request,response);} catch (Exception e) {
e.printStackTrace();}        }}

最后:我们来看看JSP页面

我们导入JSTL标签库,然后用forEach循环,遍历pb(PageBean对象)的值,我把上一页,下一页,页码等的超链值都换成了${pb.url}+pc,从而达到了保留条件的目的。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <base href="<%=basePath%>">        <title>My JSP 'index.jsp' starting page</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0">    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"><!--<link rel="stylesheet" type="text/css" href="styles.css">--><style type="text/css">body{background:rgb(230,230,230);}table td{width:100px;height: 30px;text-align: center;}.menu{width:520px;height:40px;text-align:center;line-height:40px;}</style>  </head>    <body>     <form action="StuServlet" method="get">    <input type="hidden" name="method" value="query">        用户ID:<input type="text" name="id" />    姓名:<input type="text" name="name"/>      性别:<select name="sex">    <option value="">请选择性别</option>    <option value="男">男</option>    <option value="女">女</option>    </select>    年龄:<input type="text" name="age"/>    <input type="hidden" name="pc" value="1"/>    <input type="submit"/><br/>       </form>    <table border="1" cellspacing="0">    <c:forEach items="${pb.beanList}" var="Stu">    <tr>    <td>${Stu.id }</td>    <td>${Stu.name }</td>    <td>${Stu.sex }</td>    <td>${Stu.age }</td>    <td><a href="StuServlet?method=delete&id=${Stu.id }&queryUrl=${pb.url}&pc=${pb.pc}"/>删除</a></td>      </tr>    </c:forEach>    </table>    <div class="menu">    <a href="${pb.url}&pc=1">首页</a>    <c:if test="${pb.pc>1}">    <a href="${pb.url}&pc=${pb.pc-1}">上一页</a>    </c:if>        <c:choose>    <%--当总页数小于5 --%>    <c:when test="${pb.tp<=5}">    <c:set var="begin" value="1"></c:set>    <c:set var="end" value="${pb.tp}"></c:set>    </c:when>    <%--总页数大于5 --%>    <c:otherwise>    <c:set var="begin" value="${pb.pc-2}"></c:set>    <c:set var="end" value="${pb.pc+2}"></c:set>    <%--头溢出 --%>    <c:if test="${begin<1}">    <c:set var="begin" value="1"></c:set>    <c:set var="end" value="5"></c:set>    </c:if>    <%--尾溢出 --%>    <c:if test="${end>pb.tp}">    <c:set var="begin" value="${pb.tp-4}"></c:set>    <c:set var="end" value="${pb.tp}"></c:set>    </c:if>    </c:otherwise>    </c:choose>       <%--遍历循环页码表 --%>    <c:forEach var="i" begin="${begin}" end="${end}">    <c:choose>    <c:when test="${i eq pb.pc}">    ${i }    </c:when>    <c:otherwise>    <a href="${pb.url}&pc=${i }">${i }</a>    </c:otherwise>    </c:choose>    </c:forEach>      <c:if test="${pb.pc<pb.tp}">   <a href="${pb.url}&pc=${pb.pc+1}">下一页</a>    </c:if>    <a href="${pb.url}&pc=${pb.tp }">尾页</a>     ${pb.pc}/${pb.tp}     </div>  </body></html>

备注:数据库连接用的c3po

工具类

package com.jie.utils;import java.sql.Connection;import java.sql.SQLException;import javax.sql.DataSource;import com.mchange.v2.c3p0.ComboPooledDataSource;public class JdbcUtils {//配置文件的默认配置  必须给出c3p0-config.xmlprivate static ComboPooledDataSource dataSource = new ComboPooledDataSource();/** * 使用连接池返回一个连接对象 * @return * @throws SQLException */public static  Connection getConnection() throws SQLException{return dataSource.getConnection();}/** * 返回连接池 * @return */public static DataSource getDataSoutce(){return dataSource;}}
c3p0配置文件

<?xml version="1.0" encoding="UTF-8"?><c3p0-config><default-config><!-- 连接四大参数配置 --><property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb</property><property name="driverClass">com.mysql.jdbc.Driver</property><property name="user">root</property><property name="password">123</property><!-- 池参数配置 --><property name="acquireIncrement">3</property><property name="initialPoolSize">10</property><property name="minPoolSize">2</property><property name="maxPoolSize">10</property></default-config></c3p0-config>



原创粉丝点击