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

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

先上效果图:


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



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

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

第一步: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;
	}
	@Override
	public 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{		
		//创建pb	
		PageBean<Stu> pb = new PageBean<Stu>();
		//设置已有条件  ps
		
		pb.setPs(ps);
		//设置tr
		QueryRunner 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.xml
	private 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>



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值