通用分页-前台

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介: 通用分页-前台

一、使用

1.1 思路

要在 Eclipse 中自定义一个具有分页功能的分页标签,你可以按照以下思路进行:

1. 定义标签属性:确定需要的标签属性,比如数据列表、每页显示的记录数、当前页数等,可以定义对应的 JavaBean 即标签类。

2. 实现分页逻辑:在标签类中实现分页逻辑,包括计算总页数、根据当前页获取对应数据,处理页码的合法性验证等。

3. 生成分页导航:在标签类中使用字符串拼接或模板引擎生成分页导航的 HTML 代码,可以使用链接、按钮或其他方式进行展现。

4. 注册标签:在标签类所在的项目中,通过标签库文件或在 JSP 页面中的 `<%@ taglib %>` 指令注册自定义标签,让其可以在 JSP 页面中使用。

5. 在 JSP 页面中使用标签:在需要进行分页的 JSP 页面中,使用自定义标签,传入相应的属性值,将标签和分页数据进行关联。

6. 在 JSP 页面中接收分页请求:在相应的 JSP 页面中,处理分页导航的点击事件,获取用户选择的页码,将其传递给后台处理,刷新页面显示。

7. 后台处理分页请求:在后台根据接收到的页码和其他条件,从数据源中获取对应的分页数据,将其传递给 JSP 页面进行页面更新。

通过以上思路,你可以自定义一个具有分页功能的分页标签,并在 Eclipse 中进行开发和调试。注意根据你的具体项目需求,可能需要结合相关框架或技术栈来完成整个流程。

1.2 分析

要在 Eclipse 中自定义一个具有分页功能的分页标签,你需要进行以下分析:

1. 功能需求分析:明确分析出你所需的分页功能,比如上一页、下一页、首页、尾页、跳转到指定页等。

2. 标签属性分析:确定你的自定义分页标签需要哪些属性来实现分页功能,比如数据列表、每页显示的记录数、当前页数等。

3. 数据获取分析:了解如何获取到需要进行分页的数据列表,可以是从后端数据库中查询、从接口获取等。

4. 分页逻辑分析:考虑分页的逻辑处理,如如何计算总页数、如何根据当前页获取对应数据、如何处理页码的合法性验证等。

5. 前端展示分析:确定分页标签在页面中的展现形式,如使用链接、按钮或其他方式,以及如何通过跳转、异步加载等实现分页切换。

完成以上分析,你可以根据自己的具体需求,设计和实现一个适用于你项目的分页标签,提供给页面使用。注意,自定义分页标签的实现需要结合你所使用的技术栈和框架来进行具体编码,比如在 Java Web 项目中,可以使用 JSP、Servlet、JSTL 或自定义标签库等进行实现。

1.3 流程

在 Eclipse 中自定义一个具有分页功能的分页标签的流程如下:

1. 创建一个 Java 类,用于定义自定义分页标签。

2. 定义标签属性,并生成对应的 setter 方法,用于接收页面传递的属性值。常见的属性可以包括数据列表、每页记录数、当前页数等。

3. 实现标签类的 doTag() 方法,在该方法中完成分页逻辑和分页导航的生成。

4. 在 doTag() 方法中计算总页数,并根据当前页数和每页记录数获取当前页的数据。可以使用 Java 的集合类或数据库查询等方式来获取数据。

5. 根据分页导航的设计,生成相关的 HTML 代码,可以使用字符串拼接或模板引擎来生成。这段 HTML 代码包含分页的链接、按钮或其他交互元素。

6. 将生成的分页导航代码通过 JspWriter 输出到页面中,完成分页导航的展示。

7. 注册自定义标签,以便在 JSP 页面中使用。可以通过在标签库文件(.tld)中添加标签声明,或在 JSP 页面的 `<%@ taglib %>` 指令中引入标签库。

8. 在 JSP 页面中使用自定义标签,设置相应的属性值,如数据列表、每页记录数、当前页数等。

9. 根据分页导航的点击事件,获取用户选择的页码,将其传递给后台进行处理,刷新页面显示。

10. 在后台处理分页请求的逻辑中,根据接收到的页码和其他条件,从数据源中获取对应的分页数据,将其传递给 JSP 页面进行页面更新。

11. 在 Eclipse 中进行开发和调试,确保分页标签的正常工作。

通过以上流程,你可以在 Eclipse 中自定义一个具有分页功能的分页标签,并将其应用于你的项目中。注意,具体实践过程中可能会涉及到其他技术和框架,根据你的项目要求和开发环境来进行调整和扩展。

二、实例

2.1 mysql连接类

config.properties文件 中user是本人的账号,pwd是mysql密码

#mysql
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis_ssm?useUnicode=true&characterEncoding=UTF-8&useSSL=false
user=root
pwd=123456

DBAccess类对mysql数据库进行连接访问

package com.CloudJun.utils;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/**
 * @author Cloud.Jun
 * @com.CloudJun.utils
 * @DBAccess(说明):提供了一组获得或关闭数据库对象的方法
 */
public class DBAccess {
  private static String driver;
  private static String url;
  private static String user;
  private static String password;
  static {// 静态块执行一次,加载 驱动一次
    try {
      InputStream is = DBAccess.class
          .getResourceAsStream("config.properties");
      Properties properties = new Properties();
      properties.load(is);
      driver = properties.getProperty("driver");
      url = properties.getProperty("url");
      user = properties.getProperty("user");
      password = properties.getProperty("pwd");
      Class.forName(driver);
    } catch (Exception e) {
      e.printStackTrace();
      throw new RuntimeException(e);
    }
  }
  /**
   * 获得数据连接对象
   * 
   * @return
   */
  public static Connection getConnection() {
    try {
      Connection conn = DriverManager.getConnection(url, user, password);
      return conn;
    } catch (SQLException e) {
      e.printStackTrace();
      throw new RuntimeException(e);
    }
  }
  public static void close(ResultSet rs) {
    if (null != rs) {
      try {
        rs.close();
      } catch (SQLException e) {
        e.printStackTrace();
        throw new RuntimeException(e);
      }
    }
  }
  public static void close(Statement stmt) {
    if (null != stmt) {
      try {
        stmt.close();
      } catch (SQLException e) {
        e.printStackTrace();
        throw new RuntimeException(e);
      }
    }
  }
  public static void close(Connection conn) {
    if (null != conn) {
      try {
        conn.close();
      } catch (SQLException e) {
        e.printStackTrace();
        throw new RuntimeException(e);
      }
    }
  }
  public static void close(Connection conn, Statement stmt, ResultSet rs) {
    close(rs);
    close(stmt);
    close(conn);
  }
  public static boolean isOracle() {
    return "oracle.jdbc.driver.OracleDriver".equals(driver);
  }
  public static boolean isSQLServer() {
    return "com.microsoft.sqlserver.jdbc.SQLServerDriver".equals(driver);
  }
  public static boolean isMysql() {
    return "com.mysql.cj.jdbc.Driver".equals(driver);
  }
  public static void main(String[] args) {
    Connection conn = DBAccess.getConnection();
    System.out.println(conn);
    DBAccess.close(conn);
    System.out.println("isOracle:" + isOracle());
    System.out.println("isSQLServer:" + isSQLServer());
    System.out.println("isMysql:" + isMysql());
    System.out.println("数据库连接(关闭)成功");
  }
}

2.2 实体类

Book书籍类

package com.CloudJun.entity;
/**
 * @author Cloud.Jun
 * @com.CloudJun.entity
 * @Book(说明):书(实体类)
 */
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;
  }
  public Book(int bid, String bname, float price) {
    super();
    this.bid = bid;
    this.bname = bname;
    this.price = price;
  }
  public Book() {
    super();
  }
}

2.3 方法类

BaseDao通用分页类

package com.CloudJun.dao;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import com.CloudJun.utils.DBAccess;
import com.CloudJun.utils.PageBean;
/**
 * @author Cloud.Jun
 * @com.CloudJun.dao
 * @BaseDao(说明):通用的分页方法功能类
 */
public class BaseDao<T> {
  public  List<T> executeQuery(String sql,Class c,PageBean pb) throws Exception{
    //实例化集合为容器,装载返回接收的数据
    List<T> list = new ArrayList<T>();
    //定义连接对象
    Connection conn = null;
    //执行对象
    PreparedStatement pr = null;
    //结果集对象
    ResultSet rs = null;
    //判断是否分页,为null或者为""都是不进行分页
    if(pb.isPagination() && pb!=null) {
      //获取查询总数量(数据)后的sql语句
      String count= getCount(sql);
      //进行mysql数据库连接
      conn=DBAccess.getConnection();
      //执行sql语句
      pr= conn.prepareStatement(count);
      //返回所执行后的结果集
      rs=pr.executeQuery();
      //将总记录数赋值给分页工具类
      if(rs.next()) {
        pb.setTotal(rs.getObject("n").toString());
      }
      //初始下标,从哪里开始(从第几条数据开始)
      String pagesize=getPagesize(sql,pb);
      //进行mysql数据库连接
      conn=DBAccess.getConnection();
      //执行sql语句
      pr= conn.prepareStatement(pagesize);
      //返回所执行后的结果集
      rs=pr.executeQuery();
    }else {
      //进行mysql数据库连接
      conn=DBAccess.getConnection();
      //执行sql语句
      pr = conn.prepareStatement(sql);
      //返回所执行后的结果
      rs = pr.executeQuery();
    }
    //循环集合集
    while(rs.next()) {
      //进行反射(通过类名获取实例对象)
      T t = (T) c.newInstance();
      //返回该类中所有的变量(属性),不包括继承的成员变量和静态变量。
      Field[] fields = c.getDeclaredFields();
      //循环所有变量(属性)
      for (Field field : fields) {
        //打开变量的私有权限
        field.setAccessible(true);
        //设置属性值(获取该对象[t]的属性,根据field.getName()的方法获取该对象属性名称后进行属性值赋值)
        field.set(t, rs.getObject(field.getName()));
      }
      //增加进容器(集合)
      list.add(t);
    }
    return list;//最后返回容器(集合)
  }
  /**
   * 方法功能:计算分页显示多少条数据
   * @param sql 根据传过来的sql语句再进行条件查询
   * @param pb 分页工具类
   * @return
   */
  public String getPagesize(String sql, PageBean pb) {
    return sql + " LIMIT "+pb.getStartIndex()+","+pb.getRows();
  }
  /**
   * @param sql 查询传过来的sql语句再进行查询总数据条数(总记录)
   * @return 查询总数量的sql语句
   */
  public String getCount(String sql) {
    return "SELECT COUNT(1) as n from("+sql+") t";
  }
}

BookDao书籍类的Dao层(数据访问层)类

package com.CloudJun.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import com.CloudJun.entity.Book;
import com.CloudJun.utils.DBAccess;
import com.CloudJun.utils.PageBean;
import com.CloudJun.utils.StringUtils;
/**
 * @author Cloud.Jun
 * @com.CloudJun.dao
 * @BookDao(说明):Book的模糊查询方法类继承通用分页方法类
 */
public class BookDao extends BaseDao<Book>{
  public List<Book> getlist(Book b, PageBean pb) throws Exception {
    // 实例化集合为容器,装载返回接收的数据
    List<Book> list = new ArrayList<Book>();
    // 进行mysql数据库连接
    Connection conn = DBAccess.getConnection();
    // 定义sql语句
    String sql = "select * from t_mvc_book where 1=1 ";
    // 当关键词不为空的时候,拼接模糊查询的sql语句
    String bname = b.getBname();
    if (StringUtils.isNotBlank(bname)) {
      sql += "  and bname like '%" + bname + "%'";
    }
    // 执行sql语句
    PreparedStatement pr = conn.prepareStatement(sql);
    // 返回所执行后的结果
    ResultSet rs = pr.executeQuery();
    while (rs.next()) {
      // 将结果集加入实体
      Book book = new Book(rs.getInt(1), rs.getString(2), rs.getFloat(3));
      // 将实体加入list集合
      list.add(book);
    }
    if (list != null) {
      DBAccess.close(conn, pr, rs);
    }
    return list;// 最后返回容器(集合)
  }
  @Test
  public void Text() throws Exception {
    Book book = new Book();
    book.setBname("圣墟");
    PageBean pb = new PageBean();
    List<Book> list = new BookDao().getlist(book, pb);
    for (Book bo : list) {
      System.out.println(bo);
    }
  }
  public List<Book> BaseDaoText(Book book,PageBean pb) throws Exception {
    // 定义sql语句
    String sql = "select * from t_mvc_book where 1=1 ";
    // 当关键词不为空的时候,拼接模糊查询的sql语句
    String bname = book.getBname();
    if (StringUtils.isNotBlank(bname)) {
      sql += "  and bname like '%" + bname + "%'";
    }
    return  executeQuery(sql, book.getClass(), pb);
  }
  @Test
  public void Text2() throws Exception {
    Book book = new Book();
    book.setBname("圣墟");
    PageBean pb = new PageBean();
    //测试是否分页
//    pb.setPagination(false);
    //测试显示在页面多少条
//    pb.setRows(20);
    //测试初始页码
    pb.setPage(2);
    List<Book> list = new BookDao().BaseDaoText(book, pb);
    for (Book bo : list) {
      System.out.println(bo);
    }
  } 
}

2.4 工具类

StringUtils 帮助类

package com.CloudJun.utils;
/**
 * @author Cloud.Jun
 * @com.CloudJun.utils
 * @StringUtils(说明):帮助类
 */
public class StringUtils {
  // 私有的构造方法,保护此类不能在外部实例化
  private StringUtils() {
  }
  /**
   * 如果字符串等于null或去空格后等于"",则返回true,否则返回false
   * @param s
   * @return
   */
  public static boolean isBlank(String s) {
    boolean b = false;
    if (null == s || s.trim().equals("")) {
      b = true;
    }
    return b;
  }
  /**
   * 如果字符串不等于null或去空格后不等于"",则返回true,否则返回false
   * 
   * @param s
   * @return
   */
  public static boolean isNotBlank(String s) {
    return !isBlank(s);
  }
}

EncodingFiter 字符码过滤:解决中文乱码

package com.CloudJun.utils;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * @author Cloud.Jun
 * @com.CloudJun.utils
 * @EncodingFiter(说明):中文乱码处理(类)
 */
@WebFilter("*.do")
public class EncodingFiter implements Filter {
  private String encoding = "UTF-8";// 默认字符集
  public EncodingFiter() {
    super();
  }
  public void destroy() {
  }
  public void doFilter(ServletRequest request, ServletResponse response,
      FilterChain chain) throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse res = (HttpServletResponse) response;
    // 中文处理必须放到 chain.doFilter(request, response)方法前面
    res.setContentType("text/html;charset=" + this.encoding);
    if (req.getMethod().equalsIgnoreCase("post")) {
      req.setCharacterEncoding(this.encoding);
    } else {
      Map map = req.getParameterMap();// 保存所有参数名=参数值(数组)的Map集合
      Set set = map.keySet();// 取出所有参数名
      Iterator it = set.iterator();
      while (it.hasNext()) {
        String name = (String) it.next();
        String[] values = (String[]) map.get(name);// 取出参数值[注:参数值为一个数组]
        for (int i = 0; i < values.length; i++) {
          values[i] = new String(values[i].getBytes("ISO-8859-1"),
              this.encoding);
        }
      }
    }
    chain.doFilter(request, response);
  }
  public void init(FilterConfig filterConfig) throws ServletException {
    String s = filterConfig.getInitParameter("encoding");// 读取web.xml文件中配置的字符集
    if (null != s && !s.trim().equals("")) {
      this.encoding = s.trim();
    }
  }
}

2.5 标签帮助类

PageTag 类

package com.CloudJun.utils;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
/**
 * @author Cloud.Jun
 * @com.CloudJun.entity
 * @PageTag(说明):标签帮助类
 */
public class PageTag 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 (IOException e) {
            e.printStackTrace();
        }
        return SKIP_BODY;
    }
    private String toHTML() {
        StringBuilder sb = new StringBuilder();
//        这里拼接的是一个上一次发送的请求以及携带的参数,唯一改变的就是页码
        sb.append("<form id='pageBeanForm' action='"+pageBean.getUrl()+"' method='post'>");
//        sb.append("<input type='hidden' name='methodName' value='list'>");
        sb.append("<input type='hidden' name='page'>");
//        重要设置拼接操作,将上一次请求参数携带到下一次
        Map<String, String[]> paMap = pageBean.getPageMap();
        if(paMap !=null && paMap.size()>0){
            Set<Map.Entry<String, String[]>> entrySet = paMap.entrySet();
            for (Map.Entry<String, String[]> entry : entrySet) {
                for (String val : entry.getValue()) {
                    if(!"page".equals(entry.getKey())){
                        sb.append("<input type='hidden' name='"+entry.getKey()+"' value='"+val+"'>");
                    }
                }
            }
        }
        sb.append("</form>");
        int page = pageBean.getPage();
        int max = pageBean.getMaxPage();
        int before = page > 4 ? 4 : page-1;
        int after = 10 - 1 - before;
        after = page+after > max ? max-page : after;
//        disabled
        boolean startFlag = page == 1;
        boolean endFlag = max == page;
//        拼接分页条
        sb.append("<ul class='pagination'>");
        sb.append("<li class='page-item "+(startFlag ? "disabled" : "")+"'><a class='page-link' href='javascript:gotoPage(1)'>首页</a></li>");
        sb.append("<li class='page-item "+(startFlag ? "disabled" : "")+"'><a class='page-link' href='javascript:gotoPage("+pageBean.getPrevPage()+")'>&lt;</a></li>");
//        代表了当前页的前4页
        for (int i = before; i > 0 ; i--) {
            sb.append("<li class='page-item'><a class='page-link' href='javascript:gotoPage("+(page-i)+")'>"+(page-i)+"</a></li>");
        }
        sb.append("<li class='page-item active'><a class='page-link' href='javascript:gotoPage("+pageBean.getPage()+")'>"+pageBean.getPage()+"</a></li>");
//        代表了当前页的后5页
        for (int i = 1; i <= after; i++) {
            sb.append("<li class='page-item'><a class='page-link' href='javascript:gotoPage("+(page+i)+")'>"+(page+i)+"</a></li>");
        }
        sb.append("<li class='page-item "+(endFlag ? "disabled" : "")+"'><a class='page-link' href='javascript:gotoPage("+pageBean.getNextPage()+")'>&gt;</a></li>");
        sb.append("<li class='page-item "+(endFlag ? "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' type='text' id='skipPage' name='' /><b>页</b></li>");
        sb.append("<li class='page-item go'><a class='page-link' 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 || parseInt(page) > "+max+") {");
        sb.append("alert('请输入1~N的数字');");
        sb.append("return;");
        sb.append("}");
        sb.append("gotoPage(page);");
        sb.append("}");
        sb.append("</script>");
        return sb.toString();
    }
}

PageBean 工具类

package com.CloudJun.utils;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
/**
 * @author Cloud.Jun
 * @com.CloudJun.utils
 * @PageBean(说明):分页工具类
 */
public class PageBean {
  private int page = 1;// 页码
  private int rows = 10;// 页大小
  private int total = 0;// 总记录数
  private boolean pagination = true;// 是否分页
  private String url;
  private Map<String, String[]> pageMap;
  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.setPageMap(req.getParameterMap());
  }
  public void setPagination(String pagination) {
    // 只有填写了false字符串,才代表不分页
    this.setPagination(!"false".equals(pagination));
  }
  public void setRows(String rows) {
    if (StringUtils.isNotBlank(rows))
    this.setRows(Integer.valueOf(rows));
  }
  public void setPage(String page) {
    if (StringUtils.isNotBlank(page))
      this.setPage(Integer.valueOf(page));
  }
  // 上一页
  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;
  }
  public String getUrl() {
    return url;
  }
  public void setUrl(String url) {
    this.url = url;
  }
  public Map<String, String[]> getPageMap() {
    return pageMap;
  }
  public void setPageMap(Map<String, String[]> pageMap) {
    this.pageMap = pageMap;
  }
  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 + "]";
  }
}

2.6 描述文件(tld)

Tag.tld文件

<!DOCTYPE taglib
  PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
   "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<!-- 标签库描述符 -->
<taglib xmlns="http://java.sun.com/JSP/TagLibraryDescriptor">
  <tlib-version>1.0</tlib-version>
  <jsp-version>1.2</jsp-version>
  <short-name>Simple Tags</short-name>
  <uri>http://mylxtag</uri>
  <tag>
     <!-- 标签名 -->
    <name>page</name>
    <!-- 标签助手类 -->
    <tag-class>com.CloudJun.entity.PageTag</tag-class>
    <!-- 标签的内容类型:empty表示空标签,JSP表示可以为任何合法的JSP元素 -->
    <body-content>JSP</body-content>
    <attribute>
      <!-- 属性名, PageTag类中的pageBean属性相匹配 -->
      <name>pageBean</name>
      <!-- 表示该属性为必要的属性 -->
      <required>true</required>
      <!-- 该属性可以接受EL表示式的值 -->
      <rtexprvalue>true</rtexprvalue>
    </attribute>
  </tag>
</taglib>

2.7 页面使用

jsp页面中

<%@ 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://mylxtag" prefix="z"%>
<!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 }/book.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>
<!-- books中为空进行跳转Servlet中调取方法获取数据在回来 -->
<c:if test="${empty books }">
<jsp:forward page="book.do"></jsp:forward>
</c:if>
  <table class="table table-striped">
    <thead>
      <tr>
        <th scope="col">书籍编号</th>
        <th scope="col">书籍名称</th>
        <th scope="col">书籍价格</th>
      </tr>
    </thead>
    <tbody>
      <!-- books中不为空进行循环遍历 -->
      <c:if test="${not empty books }">
      <c:forEach items="${books }" var="b">
        <tr>
          <td>${b.bid }</td>
          <td>${b.bname }</td>
          <td>${b.price }</td>
        </tr>
      </c:forEach>
      </c:if>
    </tbody>
  </table>
 <z:page pageBean="${pageBean }"></z:page>
</body>
</html>

作用:

通用分页标签的作用是在网页中添加分页功能,使长列表或查询结果能够按页进行展示,提高用户体验和页面的可读性。使用通用分页标签可以实现以下功能和好处:

1. 分隔数据:将大量数据分割成多个页面,每页只显示固定数量的数据,避免长列表的页面过于拥挤和混乱。

2. 简化导航:通过分页导航组件,用户可以轻松地跳转到下一页、上一页、首页或尾页,以及直接跳转到指定页面。

3. 改善页面加载速度:只加载当前页面所需的数据量,而不是一次性加载所有数据。这可以减少数据传输大小,加快页面加载速度。

4. 提升用户体验:用户可以更方便地浏览和浏览长列表,快速找到所需信息,同时避免页面过长造成的阅读困难。

5. 数据安全性:通过限制每页显示的数据量,可以减少敏感数据的曝光风险。

6. 可定制化:通用分页标签通常提供一些配置选项,让开发人员可以根据特定需求进行自定义,例如每页显示的数据量、分页样式、导航按钮的显示等。

总之,使用通用分页标签可以简化开发过程,并提供良好的用户体验,使得网页中的长列表或查询结果能够更加方便和有效地进行浏览、导航和展示。

三、测试

3.1 页面显示

3.2 名字查询

根据名称进行查询

查询结果

3.3 输入页面

根据指定页面进行查询

指定页面跳转后的结果

以上是没有进行一个界面的优化及布局,可以根据自己的喜好进行修改。

给我们带来

使用通用分页标签可以为您带来一些重要的收获:

1. 更好的用户体验:通过使用通用分页标签,您可以提供更流畅和易于导航的用户体验。用户可以轻松地浏览和浏览长列表或查询结果,以快速找到所需的信息,而不必滚动长页面。

2. 提高页面性能:通过将数据分割成多个页面,并仅一次加载当前页面所需的数据量,通用分页标签可以显著提高页面的加载速度和性能。这可以减少数据传输量,降低服务器负载,并为用户提供更快的响应时间。

3. 简化开发工作:通用分页标签通常提供易于使用的API和配置选项,使您能够简化分页功能的实现过程。您可以更快地集成和添加分页功能,无需从头编写和调试分页逻辑。

4. 支持数据可视化:通用分页标签通常与其他数据可视化组件(如表格、图表等)很好地集成,使您能够将分页功能与数据展示相结合。这有助于更好地呈现和解释数据,从而更有效地传达信息。

5. 提高网站的可扩展性:通过实现通用分页标签,您可以使您的网站更具可扩展性。当您需要处理更大量的数据或随用户需求进行动态加载时,分页功能可以帮助您有效地管理和展示数据。

综上所述,使用通用分页标签可以提供更好的用户体验、提高页面性能、简化开发工作,并支持数据可视化。它可以为您的网站带来更好的可用性、性能和可扩展性,从而提升用户满意度和网站的成功度。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
9月前
|
SQL 前端开发 Java
通用分页-后台
通用分页-后台
74 0
|
1天前
|
前端开发 JavaScript 数据库
分页,快捷链接表单,分页表单,常用软件开发之分页,快捷链接分页表单添加显示,可以做的分页统计,一个简单的添加页面,数据条理清晰呈现如何设计,如何修改成自己想要的,要会编写接口文档,一边写接口
分页,快捷链接表单,分页表单,常用软件开发之分页,快捷链接分页表单添加显示,可以做的分页统计,一个简单的添加页面,数据条理清晰呈现如何设计,如何修改成自己想要的,要会编写接口文档,一边写接口
|
8月前
|
前端开发 数据管理 Java
通用分页(下)
通用分页(下)
35 0
|
10月前
|
算法 JavaScript Java
通用分页【下】(将分页封装成标签)
调试()是指在软件开发过程中,通过识别、定位和解决程序错误或问题的过程。调试的目的是找出代码中的错误、异常或不正常的行为,并修复它们,以确保程序能够按照预期的方式运行。调试是一个重要的开发技巧,可以帮助开发人员理解程序的执行过程、找出错误的原因,并从中学习和改进。调试可以使用不同的工具和技术来辅助,例如打印输出、日志记录、调试器(debugger)等。调试是开发过程中不可或缺的一部分,可以帮助开发人员提高代码质量、加快解决问题的速度,并优化程序的性能和可靠性。
|
2月前
|
前端开发 关系型数据库 MySQL
通用分页详解
通用分页详解
41 0
|
7月前
|
存储 前端开发 Java
详解通用分页(前端)
详解通用分页(前端)
22 0
|
9月前
|
监控 前端开发 算法
通用分页(前端)
通用分页(前端)
29 1
|
7月前
|
SQL Java 关系型数据库
通用分页详细讲解(后端)
通用分页详细讲解(后端)
40 0
|
7月前
通用分页(后台分页)
通用分页(后台分页)
38 0
|
7月前
|
前端开发
通用分页02(前台分页)
通用分页02(前台分页)
44 0

热门文章

最新文章

  • 1
    流量控制系统,用正则表达式提取汉字
    25
  • 2
    Redis09-----List类型,有序,元素可以重复,插入和删除快,查询速度一般,一般保存一些有顺序的数据,如朋友圈点赞列表,评论列表等,LPUSH user 1 2 3可以一个一个推
    26
  • 3
    Redis08命令-Hash类型,也叫散列,其中value是一个无序字典,类似于java的HashMap结构,Hash结构可以将对象中的每个字段独立存储,可以针对每字段做CRUD
    25
  • 4
    Redis07命令-String类型字符串,不管是哪种格式,底层都是字节数组形式存储的,最大空间不超过512m,SET添加,MSET批量添加,INCRBY age 2可以,MSET,INCRSETEX
    27
  • 5
    S外部函数可以访问函数内部的变量的闭包-闭包最简单的用不了,闭包是内层函数+外层函数的变量,简称为函数套函数,外部函数可以访问函数内部的变量,存在函数套函数
    23
  • 6
    Redis06-Redis常用的命令,模糊的搜索查询往往会对服务器产生很大的压力,MSET k1 v1 k2 v2 k3 v3 添加,DEL是删除的意思,EXISTS age 可以用来查询是否有存在1
    30
  • 7
    Redis05数据结构介绍,数据结构介绍,官方网站中看到
    21
  • 8
    JS字符串数据类型转换,字符串如何转成变量,+号只要有一个是字符串,就会把另外一个转成字符串,- * / 都会把数据转成数字类型,数字型控制台是蓝色,字符型控制台是黑色,
    19
  • 9
    JS数组操作---删除,arr.pop()方法从数组中删除最后一个元素,并返回该元素的值,arr.shift() 删除第一个值,arr.splice()方法,删除指定元素,arr.splice,从第一
    19
  • 10
    定义好变量,${age}模版字符串,对象可以放null,检验数据类型console.log(typeof str)
    19