Java通用分页

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS SQL Server,基础系列 2核4GB
简介: Java通用分页

1.什么是通用分页

通用分页是一种在Java Web开发中广泛使用的技术,它用于处理大量数据并将它们分成多个页面进行显示。通用分页通常包括一个分页组件和分页查询方法,该方法使用分页参数查询并返回指定页面和指定数量的数据结果。通常可以设置每页显示的数据数量,当前页面的页码以及总共的数据数量等。

通用分页的主要目的是为了更方便地浏览并处理大量数据。使用通用分页可以减轻服务器负担,提高数据处理效率和页面加载速度,同时也能使数据更加直观和易于管理。在开发中,通用分页通常会配合前端框架一起使用,以实现更好的用户体验。

2.反射完成通用的查询功能

编写一组获得或关闭数据库对象的方法:

package com.xiaoye.util;
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;
/**
 * 提供了一组获得或关闭数据库对象的方法
 * 
 */
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("数据库连接(关闭)成功");
  }
}

编写一个能够连接数据库的方法:

编写一个私有的构造方法:

package com.xiaoye.util;
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);
  }
}

编写一个分页工具类:

package com.xiaoye.util;
/**
 * 分页工具类
 *
 */
public class PageBean {
  private int page = 1;// 页码
  private int rows = 10;// 页大小
  private int total = 0;// 总记录数
  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 + "]";
  }
}

编写一个过滤器(凡是被过滤器处理的都变成了 中文乱码处理):

package com.xiaoye.util;
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.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 过滤器
 * 凡是被过滤器处理的都变成了 中文乱码处理
 * 
 */
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();
    }
  }
}

编写实体类BOOK:

package com.xiaoye.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;
  }
}

 

编写BookDao :

public List<Book> list1(Book book, PageBean bean) throws Exception {
    List<Book> list = new ArrayList<Book>();
    Connection conn = DBAccess.getConnection();
    String sql = "select * from t_mvc_book where 1=1";
    String bname = book.getBname();
    // 判断bname不为空的情况下才进行
    if (StringUtils.isNotBlank(bname)) {
      sql += " and bname LIKE '%" + bname + "%'";
    }
    PreparedStatement ps = conn.prepareStatement(sql);
    ResultSet rs = ps.executeQuery();
    while (rs.next()) {
      Book b = new Book();
      b.setBid(rs.getInt("bid"));
      b.setBname(rs.getString("bname"));
      b.setPrice(rs.getFloat("price"));
      l.add(b);
    }
    return l;
  }

输出结果:

编写basedao:

代码重复:必须要写的

Connection conn =  DBAccess.getConnection(); 
      PreparedStatement ps = conn.prepareStatement(sql); 
      ResultSet rs = ps.executeQuery();

流程重复:

创建表对应的实体类对象,将查询出来的结果集添加到实例化对象的属性中,已经被填充的实体对象,加入到集合中

Book b=new Book();
      b.setBid(rs.getInt("bid"));
      b.setBname(rs.getString("bname"));
      b.setPrice(rs.getFloat("price"));
      l.add(b);

创建一个basedao泛型basedao:

package com.xiaoye.util;
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.xiaoye.entity.Book;
public class BaseDao<T> {
public List<T> executeQuery(String sql,Class clz,PageBean p) throws Exception{
    List<T> list = new ArrayList<T>();
    Connection conn = DBAccess.getConnection();
    PreparedStatement ps = conn.prepareStatement(sql);
    ResultSet rs = ps.executeQuery();
    while(rs.next()) {
      T t = (T) clz.newInstance();
      //拿到clz对应的所有属性对象
      Field[] fields = clz.getDeclaredFields();
      for (Field f : fields) {
        f.setAccessible(true);//打开访问权限
        f.set(t, rs.getObject(f.getName()));
      }
      list.add(t);
    }
    return list;
  }
}

到BOOKDAO进行代码测试:

public List<Book> list2(Book book,PageBean pegeBean) throws Exception{
    String sql ="select * from t_mvc_book where 1=1";
    String bname = book.getBname();
    if(StringUtils.isNotBlank(bname)) {
      sql +=" and bname like '%"+bname+"%'";
    }
    return super.exrcuteQuery(sql, Book.class, pegeBean);
  }

使用main方法测试:

  public static void main(String[] args) throws Exception {
    BookDao bookDao=new BookDao();
    Book book=new Book();
    book.setBname("圣墟");
    PageBean pageBen=new PageBean();
    List<Book> list = bookDao.list(book, pageBen);
    for (Book b : list) {
      System.out.println(b);
    }
  }

输出结果:

4.junit单元测试:

JUnit是一个Java语言的单元测试框架,用于编写和运行自动化测试,JUnit提供了测试框架,用于测试Java代码的各种方面,包括方法的返回值和异常处理

在bookDao里面建立两个test:

@Test 
  public void test() throws Exception {
    System.out.println("test1..");
    BookDao bookDao=new BookDao();
    Book book=new Book();
    book.setBname("圣墟");
    PageBean pageBen=new PageBean();
    List<Book> list = bookDao.list1(book, pageBen);
    for (Book b : list) {
      System.out.println(b);
  }
  } 
  @Test 
  public void test2() throws Exception {
    System.out.println("test2..");
    BookDao bookDao=new BookDao();
    Book book=new Book();
    book.setBname("圣墟");
    PageBean pageBen=new PageBean();
    List<Book> list = bookDao.list2(book, pageBen);
    for (Book b : list) {
      System.out.println(b);
  }
  } 

输出结果:

5.通用查询带分页:

在BaseDAO里面写两个方法:pegeBean   sql

package com.xiaoye.util;
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.xiaoye.entity.Book;
public class BaseDao<T> {
      /**
       * 
       * @param sql
       * @param c        Book.class
       * @param pegeBean
       * @return
       * @throws Exception
       */
  public List<T> exrcuteQuery(String sql,Class c,PageBean pegeBean) throws Exception{
    List<T> l=new ArrayList<T>();
    Connection con = null;
    PreparedStatement ps = null;
    ResultSet rs = null;
    if(pegeBean !=null && pegeBean.isPagination()) {
      String countSQL=getCountSQL(sql);
      con=DBAccess.getConnection();
       ps = con.prepareStatement(countSQL);
       rs = ps.executeQuery();
       if(rs.next()) {
         pegeBean.setTotal(rs.getObject("n").toString());
       }
      String pageSQL=getPageSQL(sql,pegeBean);
      con=DBAccess.getConnection();
       ps = con.prepareStatement(pageSQL);
       rs = ps.executeQuery();
    }else {
      con=DBAccess.getConnection();
       ps = con.prepareStatement(sql);
       rs = ps.executeQuery();
    }
    while(rs.next()) {
      T t=(T) c.newInstance();
      //拿到class对应的使用对象
      Field[] fields = c.getDeclaredFields();
      for (Field f : fields) {
        f.setAccessible(true);
//        System.out.println(f.getName());
        f.set(t, rs.getObject(f.getName()));
      }
      l.add(t);
    }
    return l;
  }
  /**
   * 拼接出最终展示出的数据sql
   * @param sql    原生sql
   * @param pegeBean
   * @return
   */
  private String getPageSQL(String sql, PageBean pegeBean) {
    return sql+" limit "+pegeBean.getStartIndex()+","+pegeBean.getRows();
  }
      /**
       * 拼接出查询符合条件的总记录sql
       * @param sql
       * @return
       */
  private String getCountSQL(String sql) {
    return "SELECT count(1) as n from  ("+sql+")   t";
  }
}

然后在BookDao里面在写一个Test:

@Test 
  public void test3() throws Exception {
    System.out.println("test3..");
    BookDao bookDao=new BookDao();
    Book book=new Book();
    book.setBname("圣墟");
    PageBean pageBen=new PageBean();
    //不需要分页
//    pageBen.setPagination(false);
    //查询第二页的数据
//    pageBen.setPage(2);
    List<Book> list = bookDao.list2(book, pageBen);
    for (Book b : list) {
      System.out.println(b);
  }
    System.out.println(pageBen);
  } 

输出结果:

不需要分页:

pageBen.setPagination(false);

输出结果:

查询第二页的数据:

pageBen.setPage(2);

输出结果:

没有用以上两种方法:

@Test 
  public void test3() throws Exception {
    System.out.println("test3..");
    BookDao bookDao=new BookDao();
    Book book=new Book();
    book.setBname("圣墟");
    PageBean pageBen=new PageBean();
    //不需要分页
//    pageBen.setPagination(false);
    //查询第二页的数据
//    pageBen.setPage(2);
    List<Book> list = bookDao.list2(book, pageBen);
    for (Book b : list) {
      System.out.println(b);
  }
    System.out.println(pageBen);
  } 

输出结果:


动起来你们的双手

 

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
7月前
|
Web App开发 SQL Java
javaweb实现分页(二)
javaweb实现分页(二)
|
7月前
|
Web App开发 Java 关系型数据库
java中部的分页实现(二)
java中部的分页实现(二)
|
7月前
|
SQL 关系型数据库 MySQL
javaweb中实现分页,持续更新……
javaweb中实现分页,持续更新……
|
7月前
Mybatis+mysql动态分页查询数据案例——分页工具类(Page.java)
Mybatis+mysql动态分页查询数据案例——分页工具类(Page.java)
|
SQL 前端开发 Java
java通用分页前端(2)
java通用分页前端(2)
68 0
|
2月前
|
Java 程序员 调度
Java|PageHelper 怎么自作主张帮我分页?
没有调用 PageHelper.startPage,查询怎么也被自动分页了?
13 2
|
7月前
|
存储 安全 Java
掌握8条泛型规则,打造优雅通用的Java代码
掌握8条泛型规则,打造优雅通用的Java代码
掌握8条泛型规则,打造优雅通用的Java代码
|
6月前
|
SQL 缓存 Java
Java框架之MyBatis 07-动态SQL-缓存机制-逆向工程-分页插件
Java框架之MyBatis 07-动态SQL-缓存机制-逆向工程-分页插件
|
7月前
|
Java 测试技术 Python
《手把手教你》系列技巧篇(五十八)-java+ selenium自动化测试-分页测试(详细教程)
【5月更文挑战第22天】本文介绍了自动化测试分页的实现方法。首先,文章提出了测试分页时关注的三个关键点:总页数、当前页数和页码导航的可用性。接着,作者分享了一个实用网站([https://www.jq22.com/](https://www.jq22.com/))以找到示例进行实践。在代码部分,展示了使用Java和Selenium进行自动化测试的示例代码,包括获取总页数、遍历所有页面及判断当前页面等操作。最后,简要总结了分页自动化测试的实现过程。
54 1
|
7月前
|
存储 安全 Java
12条通用编程原则✨全面提升Java编码规范性、可读性及性能表现
12条通用编程原则✨全面提升Java编码规范性、可读性及性能表现