通用分页集模糊,全部查询,分页查询为一体(2)演示,优化上篇通用查询分页

简介: 通用分页集模糊,全部查询,分页查询为一体(2)演示,优化上篇通用查询分页

前言:

上次发布了一篇关于通用查询分页,这篇这继上篇加优化以及演示,比上篇更加清晰明了,

有些只给了代码但是没有详细分析的请看上篇博客,谢谢!


一.分页

Java的分页功能通常在Web开发中用于展示数据列表的分页显示。这种场景下,数据量可能非常庞大,如果一次性将所有记录都展示出来,会导致页面加载缓慢,用户体验不佳。

分页功能可以将数据分为多个页面展示,每个页面仅包含一定数量的记录,大大提高了页面加载速度和响应时间,增强了用户体验。此外,分页功能还可以支持用户自行选择每页显示的记录数和跳转到指定页面的功能,更加满足用户的需求。

二.分页的步骤

  1.       编写一份要展示数据的属性,实体类
  2.        定义需要的属性或者关于分页的方法,放在分页工具类里面  PageBean.java,这个方法里面的东西,比较难,看下面的核心思想
  3.       编写通用Dao方法,我运用了BaseDao方法(这个方法我在上篇已经写了)
  4.        写助手类,主要就是进行拼接展示
  5.        自定义标签,编写tld文件
  6.        编写前端展示页面 jsp文件,导入自定义标签库
  7.        servlet类,获取数据并进行保存,然后回显给前端 jsp文件
  8.        最后执行,展示效果

我们来看看分页的核心思想是什么?

前面也说了这篇是优化上篇我所写的通用查询,主要优化了PageBean

  •        增加了一个属性URL,来保存上一次发送的请求地址
  •        增加了一个属性ParamMap,来保存模糊查询所携带的参数
  •        增加三个方法 :最大页,下一页,上一页
  • 最后初始化pageBean方法

       实体类的代码:

package com.yinzi.entity;
public class Book {
  private int bid;
  private String bname;
  private float price;
  @Override
  public String toString() {
    return "Book [bid=" + bid + ", bname=" + bname + ", price=" + price + "]";
  }
  public int getBid() {
    return bid;
  }
  public void setBid(int bid) {
    this.bid = bid;
  }
  public String getBname() {
    return bname;
  }
  public void setBname(String bname) {
    this.bname = bname;
  }
  public float getPrice() {
    return price;
  }
  public void setPrice(float price) {
    this.price = price;
  }
}

三.分页工具类

       老规矩,还是先上整体代码,再分析

分页工具类代码:

package com.yinzi.utils;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
/**
 * 分页工具类
 *
 */
public class PageBean {
  private int page = 1;// 页码
  private int rows = 10;// 页大小
  private int total = 0;// 总记录数
  // 上一次查询的url
  private String url;
  // 上一次查询所携带的查询条件
  private Map<String, String[]> parameterMap = new HashMap<String, String[]>();
  // 对pagebean进行初始化
  public void setRequest(HttpServletRequest req) {
    // 初始化jsp页面传递过来的当前页
    this.setPage(req.getParameter("page"));
    // 初始化jsp页面传递过来的页大小
    this.setRows(req.getParameter("rows"));
    // 初始化jsp页面传递过来是否分页
    this.setPagination(req.getParameter("pagination"));
    // 保留上一次的查询请求
    this.setUrl(req.getRequestURL().toString());
    // 保留上一次的查询条件
    this.setParameterMap(req.getParameterMap());
  }
  public String getUrl() {
    return url;
  }
  public void setUrl(String url) {
    this.url = url;
  }
  public Map<String, String[]> getParameterMap() {
    return parameterMap;
  }
  public void setParameterMap(Map<String, String[]> parameterMap) {
    this.parameterMap = parameterMap;
  }
  private void setPagination(String pagination) {
    // 只有填写了false字符串,才代表不分页
    this.setPagination(!"false".equals(pagination));
  }
  private void setRows(String rows) {
    if (StringUtils.isNotBlank(rows))
      this.setRows(Integer.valueOf(rows));
  }
  private void setPage(String page) {
    if (StringUtils.isNotBlank(page))
      this.setPage(Integer.valueOf(page));
  }
  private boolean pagination = true;// 是否分页
  public PageBean() {
    super();
  }
  public int getPage() {
    return page;
  }
  public void setPage(int page) {
    this.page = page;
  }
  public int getRows() {
    return rows;
  }
  public void setRows(int rows) {
    this.rows = rows;
  }
  public int getTotal() {
    return total;
  }
  public void setTotal(int total) {
    this.total = total;
  }
  public void setTotal(String total) {
    this.total = Integer.parseInt(total);
  }
  public boolean isPagination() {
    return pagination;
  }
  public void setPagination(boolean pagination) {
    this.pagination = pagination;
  }
  /**
   * 获得起始记录的下标
   * 
   * @return
   */
  public int getStartIndex() {
    return (this.page - 1) * this.rows;
  }
  @Override
  public String toString() {
    return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination + "]";
  }
  // 上一页
  public int getPrevPage() {
    return this.page > 1 ? this.page - 1 : this.page;
  }
  // 下一页
  public int getNextPage() {
    return this.page < this.getMaxPage() ? this.page + 1 : this.page;
  }
  // 最大页
  public int getMaxPage() {
    return this.total % this.rows == 0 ? this.total / this.rows : (this.total / this.rows) + 1;
  }
}

       3.1  详解分页工具类

这里我每一行都打了注释,都是很详细的,这一步就是初始化,在初始化时,需要定义三个方法

然后编写分页所需要的方法

四.助手类

       这里主要都是拼接,展示,然后编写分页的功能

package com.yinzi.servlet;
import java.io.IOException;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
import com.yinzi.utils.PageBean;
public class BookTag extends BodyTagSupport {
  //定义一个分页的属性
  private PageBean pageBean;
  public PageBean getPageBean() {
    return pageBean;
  }
  public void setPageBean(PageBean pageBean) {
    this.pageBean = pageBean;
  }
  @Override
  public int doStartTag() throws JspException {
    JspWriter out = pageContext.getOut();
    try {
      //拼接
      out.print(toHTML());
    } catch (Exception e) {
      e.printStackTrace();
    }
    return super.doStartTag();
  }
  /**
   * 拼接的方法
   * @return
   */
  private String toHTML() {
    StringBuffer sb = new StringBuffer();
//    form
    sb.append("<form action=\""+pageBean.getUrl()+"\" id=\"pageBeanForm\" method=\"post\">");
    sb.append(" <input type=\"hidden\" name=\"page\">");
    Map<String, String[]> paramMap = pageBean.getParameterMap();
    if(paramMap != null && paramMap.size() > 0) {
      Set<Entry<String, String[]>> entrySet = paramMap.entrySet();
      for (Entry<String, String[]> entry : entrySet) {
        String name = entry.getKey();
        String[] value = entry.getValue();
        if(value != null && value.length > 0) {
          for (String val : value) {
             if(!"page".equals(entry.getKey())){
               sb.append(" <input type=\"hidden\" name=\""+name+"\" value=\""+val+"\">");
             }
          }
        }
      }
    }
    sb.append("</form>");
//    分页条
    sb.append("<ul class=\"pagination justify-content-center\">");
    sb.append(" <li class=\"page-item "+(pageBean.getPage() == 1 ? "disabled" : "")+"\"><a class=\"page-link\"");
    sb.append(" href='javascript:gotoPage(1)'>首页</a></li>");
    sb.append(" <li class=\"page-item "+(pageBean.getPage() == 1 ? "disabled" : "")+"\"><a class=\"page-link\"");
    sb.append(" href='javascript:gotoPage("+pageBean.getPrevPage()+")'>&lt;</a></li>");
    sb.append(" <li class=\"page-item\"><a class=\"page-link\" href=\"#\">"+pageBean.getPage()+"</a></li>");
    sb.append(" <li class=\"page-item "+(pageBean.getPage() == pageBean.getMaxPage() ? "disabled" : "")+"\"><a class=\"page-link\" href=\"javascript:gotoPage("+pageBean.getNextPage()+")\">&gt;</a></li>");
    sb.append(" <li class=\"page-item "+(pageBean.getPage() == pageBean.getMaxPage() ? "disabled" : "")+"\"><a class=\"page-link\" href=\"javascript:gotoPage("+pageBean.getMaxPage()+")\">尾页</a></li>");
    sb.append(" <li class=\"page-item go-input\"><b>到第</b><input class=\"page-link\"");
    sb.append(" type=\"text\" id=\"skipPage\" name=\"\" /><b>页</b></li>");
    sb.append(" <li class=\"page-item go\"><a class=\"page-link\"");
    sb.append(" href=\"javascript:skipPage()\">确定</a></li>");
    sb.append(" <li class=\"page-item\"><b>共"+pageBean.getTotal()+"条</b></li>");
    sb.append(" </ul>");
//    分页功能js代码
    sb.append("<script type='text/javascript'>");
    sb.append(" function gotoPage(page) {");
    sb.append("   document.getElementById('pageBeanForm').page.value = page;");
    sb.append("   document.getElementById('pageBeanForm').submit();");
    sb.append(" }");
    sb.append(" function skipPage() {");
    sb.append("   var page = document.getElementById('skipPage').value;");
    sb.append("   if (!page || isNaN(page) || parseInt(page) < 1");
    sb.append("   || parseInt(page) > 1122) {");
    sb.append("     alert('请输入1~N的数字');");
    sb.append("   return;");
    sb.append("   }");
    sb.append("   gotoPage(page);");
    sb.append(" }");
    sb.append("</script>");
    return sb.toString();
  }
}

五.编写tld文件

<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
    version="2.0">
  <description>JSTL 1.1 core library</description>
  <display-name>JSTL core</display-name>
  <tlib-version>1.1</tlib-version>
  <short-name>y</short-name>
  <uri>http://yinzi</uri>
  <tag>
    <!-- 标签库标签的名字 -->
    <name>page</name>
   <!--  对应的助手类 -->
    <tag-class>com.yinzi.servlet.BookTag</tag-class>
   <!--  代表JSP标签 -->
    <body-content>JSP</body-content>
    <!-- 属性 -->
      <attribute>
       <!--  属性名称 -->
       <name>pageBean</name>
        <!-- 是否为必填项 -->
         <required>true</required> 
       <!--  是否支持EL表达式 -->
       <rtexprvalue>true</rtexprvalue> 
   </attribute>
  </tag>
</taglib>

六,前端展示页面和Servlet界面

       前端页面代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>  
<%@ taglib uri="http://yinzi" prefix="y" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link
  href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css"
  rel="stylesheet">
<script
  src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.js"></script>
<title>书籍列表</title>
<style type="text/css">
.page-item input {
  padding: 0;
  width: 40px;
  height: 100%;
  text-align: center;
  margin: 0 6px;
}
.page-item input, .page-item b {
  line-height: 38px;
  float: left;
  font-weight: 400;
}
.page-item.go-input {
  margin: 0 10px;
}
</style>
</head>
<body>
  <!-- 搜索框 -->
  <form class="form-inline" action="${pageContext.request.contextPath }/BookServlet.do" method="post">
    <div class="form-group mb-2">
      <input type="text" class="form-control-plaintext" name="bname"
        placeholder="请输入书籍名称">
    </div>
    <button type="submit" class="btn btn-primary mb-2">查询</button>
  </form>
  <!-- 表格内容 -->
  <table class="table table-striped ">
    <thead>
      <tr>
        <th scope="col">书籍ID</th>
        <th scope="col">书籍名</th>
        <th scope="col">价格</th>
      </tr>
    </thead>
    <tbody>
      <c:forEach items="${books}" var="b">
      <tr>
        <td>${b.bid }</td>
        <td>${b.bname }</td>
        <td>${b.price }</td>
      </tr>
      </c:forEach>
    </tbody>
  </table>
  <y:page pageBean="${pageBean }"></y:page>
</body>
</html>

servlet代码:

package com.yinzi.servlet;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.yinzi.dao.BookDao;
import com.yinzi.entity.Book;
import com.yinzi.utils.PageBean;
@WebServlet("/BookServlet.do")
public class BookServlet extends HttpServlet {
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doPost(request, response);
  }
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //实例化dao方法,来调用查询的方法
    BookDao bookDao = new BookDao();
    //实例化分页工具类,调取初始化方法
    PageBean pageBean = new PageBean();
    pageBean.setRequest(request);
    //实例化实体类
    Book book = new Book();
    //获取模糊查询的参数
    book.setBname(request.getParameter("bname"));
    try {
      //调用查询的方法
      List<Book> list = bookDao.queryAll(book , pageBean);
      //保存
      request.setAttribute("books", list);
      request.setAttribute("pageBean", pageBean);
      //跳转
      request.getRequestDispatcher("/book.jsp").forward(request, response);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

详解Servlet:基本上都是调用方法,注释每一行都有

最后展示效果:

00a24ae7a4fa4634ba002ffcbd8457b4.png

相关文章
|
前端开发 Java 测试技术
通用分页【上】
JUnit是流行的、开源的Java单元测试框架,它提供了一种简单而强大的方式来测试Java应用程序中的单元代码。JUnit测试通常涉及创建和运行测试用例,而测试用例是一组独立的测试步骤,用于验证代码是否按照预期工作。JUnit测试通常分为以下四个步骤:定义测试用例:定义每个测试方法所需的输入参数以及期望的输出结果;编写测试代码:编写测试方法并使用断言(Assertion)来验证代码是否按照预期工作;运行测试用例:通常使用JUnit测试浏览器或者其他测试工具来运行测试用例;查看测试结果。
|
SQL 前端开发 Java
通用分页-后台
通用分页-后台
91 0
|
4月前
|
缓存 监控 前端开发
大量数据如何做分页处理
【8月更文挑战第13天】面对大量数据分页,可从数据库与应用两方面着手:数据库端利用内置分页功能如MySQL的`LIMIT`与`OFFSET`,及SQL Server的`ROW_NUMBER()`;优化查询,精选字段并为常用排序字段加索引。应用端采用缓存已分页数据、异步加载新页及前端懒加载技术。同时限制最大页数并持续监控优化性能,确保高效查询与良好用户体验。
130 0
|
前端开发 数据管理 Java
通用分页(下)
通用分页(下)
43 0
|
算法 JavaScript Java
通用分页【下】(将分页封装成标签)
调试()是指在软件开发过程中,通过识别、定位和解决程序错误或问题的过程。调试的目的是找出代码中的错误、异常或不正常的行为,并修复它们,以确保程序能够按照预期的方式运行。调试是一个重要的开发技巧,可以帮助开发人员理解程序的执行过程、找出错误的原因,并从中学习和改进。调试可以使用不同的工具和技术来辅助,例如打印输出、日志记录、调试器(debugger)等。调试是开发过程中不可或缺的一部分,可以帮助开发人员提高代码质量、加快解决问题的速度,并优化程序的性能和可靠性。
|
监控 前端开发 算法
通用分页(前端)
通用分页(前端)
46 1
|
Java 数据库
通用分页之详解】
通用分页之详解】
41 1
|
7月前
|
前端开发 关系型数据库 MySQL
通用分页详解
通用分页详解
61 0
|
存储 前端开发 Java
详解通用分页(前端)
详解通用分页(前端)
60 0
|
前端开发
通用分页02(前台分页)
通用分页02(前台分页)
61 0