通用分页详解【上】

简介: 通用分页详解【上】

一、通用分页是什么呢?

       Java通用分页是一种用于将数据列表按照指定条件划分为若干页并进行分页展示的技术。通常在Java后台网站开发中,会在查询数据库时设置分页参数,包括页码和每页数据量等,然后通过对数据查询结果进行筛选,排序并进行切片操作,最终将指定页码的数据返回给前端进行展示。通用分页的好处是可以重复使用,无需重复编写分页代码。

二、应用场景

  • 在前端页面上展示大量数据时,通过分页展示可以提高页面的加载速度,优化用户体验。
  • 在后台管理系统中,通过对数据进行分页展示,可以方便管理员查看、管理和处理数据,提高工作效率。
  • 在大型数据库查询中,使用分页技术可以减轻服务器压力,提高响应速度。
  • 在大数据量的高并发场景中,使用分页技术可以提高系统的响应速度并保证系统稳定性。

三、为什么要学习它呢        

       学习Java通用分页对于后端Java开发人员来说是非常重要的。首先,分页技术是Web应用中最基础的技术之一,常用于在前端页面上展示数据,通过对数据进行分页展示,可以使页面数据更加清晰明了,提高用户体验。其次,掌握通用分页技术可以让你更好的理解数据库查询和ORM框架的工作原理,在处理大量数据时,分页技术可以帮助你优化查询速度,提高系统的性能和响应速度。最后,在实际项目中,通用分页技术是非常常用的技术,学习它可以让你更快更好地理解业务需求并快速实现对应功能,提高工作效率。

四、pageBean

PageBean通常是一个JavaBean对象,也称为分页对象,用于封装后端应用程序中的分页数据。它包含了当前页码、每页大小、总页数、总记录数等分页相关信息,同时还包含了当前页面显示的数据列表。在Java的后端开发中,通常使用分页技术进行数据显示和处理,PageBean对象在分页技术中起到了起到了非常重要的作用。

PageBean对象通常包含以下属性:

  • currentPage:当前页码。
  • pageSize:每页显示的数据条数。
  • totalCount:总记录数。
  • totalPage:总页数。
  • dataList:当前页码的数据列表。

PageBean对象通过分页查询的方法进行构建,对于不同的分页实现方式,PageBean对象的构建方式也有所不同。例如在使用MyBatis框架中进行分页查询时,可以通过设置分页插件和Mapper中的方法来构建PageBean对象。

PageBean对象可以将分页相关的信息封装在一起,方便后端传递数据到前端进行展示。同时也可以方便进行分页查询的具体实现。在实际的项目开发中,经常需要使用分页技术对数据进行处理。

等一下会带大家去封装pageBean进行实操

五、为什么要去封装pageBean以及封装它的优点

1.为什么要封装

  1. 简化分页操作:通过封装PageBean对象,可以将分页查询和展示相关的属性和方法封装在一起,可以方便地使用这些属性和方法进行分页操作,避免了重复代码的编写。
  2. 方便传递分页数据:PageBean对象可以将分页查询所得到的数据一起封装成一个对象,方便将这些数据传递到前端页面进行展示,也可以方便在后端应用中进行数据处理。
  3. 方便进行动态分页:封装PageBean对象可以方便动态修改查询结果的分页大小、查询页码等相关信息,从而实现动态的分页查询结果展示。
  4. 提高代码可读性:使用封装好的PageBean对象可以提高代码的可读性和可维护性,让代码更加易懂,也可以在后续升级和维护时更容易地进行修改。

2.封装了的优点

  1. 简化代码:封装PageBean对象可以将分页相关的属性和方法封装在一个对象中,避免了重复代码的编写,使得代码更加简洁。
  2. 增强代码复用性:封装PageBean可以方便地实现代码复用,将分页数据的处理与业务逻辑分离,使得代码具有更好的可重用性。
  3. 易于维护:代码的维护是任何程序开发过程中必不可少的任务,而封装PageBean可以提高代码的可读性、可维护性和可扩展性,减少了代码的冗余和重复,使得代码更加易于维护。
  4. 方便调试:封装PageBean可以将分页相关的数据和方法进行封装,方便定位和调试出现问题的地方。
  5. 提高程序性能:封装PageBean可以减少数据传输的大小,从而提高程序的运行效率。

六、通用分页实例

1.这里我就以书为对象实体

package com.ctb.entity;
/**
 * 实体--书
 * 
 * @author biao
 *
 */
public class Book {
  private int bid;
  private String bname;
  private float 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() {
    // TODO Auto-generated constructor stub
  }
  public Book(int bid, String bname, float price) {
    super();
    this.bid = bid;
    this.bname = bname;
    this.price = price;
  }
  @Override
  public String toString() {
    return "Book [bid=" + bid + ", bname=" + bname + ", price=" + price + "]";
  }
}

2.我们需要连接数据库,存储一些数据。我所用的是MySQL,当然也可用其它数据库存储数据

3.在这封装了字符串判断是否为空和防止中文乱码的类

字符串判断

package com.ctb.utils;
/**
 * 字符串判断是否为空
 * @author biao
 *
 */
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.ctb.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.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();
    }
  }
}

4.封装pageBean类

package com.ctb.utils;
/**
 * 分页工具类
 * @author biao
 *
 */
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 + "]";
  }
}

5.封装baseDao通用分页模糊查询的方法

1.为减少代码量,提高效率,baseDao就体现出来啦,在下面也会有所介绍。

2.在basedao中分页查询方法里我们只需传入sql语句,实体,分页工具类三个参数。

3.在此功能中我们需编写查询总记录条数的方法和分页模糊查询后查询出数据的方法

4.在获取每个类的属性也会不一样,所以我们用到反射机制,动态获取所有属性

package com.ctb.utils;
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;
/**
 * 
 * @author biao
 *
 * @param <T>   泛型
 */
public class BaseDao<T> {
  /**
   * 通用分页模糊查询
   * @param sql       sql语句
   * @param class1    类对象
   * @param pageBean      分页工具
   * @return   list     集合
   * @throws Exception    异常
   */
  public List<T> executeQuery(String sql,Class class1,PageBean pageBean) throws Exception{
    //集合
    List<T> list = new ArrayList<T>();
    //连接对象
    Connection con = null;
    //执行对象
    PreparedStatement pst = null;
    //结果集对象
    ResultSet rs = null;
    if(pageBean != null && pageBean.isPagination()) {//判断
      String countSQL = getCountSQL(sql);
      con = DBAccess.getConnection();
      pst = con.prepareStatement(countSQL);
      rs = pst.executeQuery();
      if(rs.next()) {
        pageBean.setTotal(rs.getObject("n").toString());
      }
      String pageSQL = getPageSQL(sql,pageBean);
      con = DBAccess.getConnection();
      pst = con.prepareStatement(pageSQL);
      rs = pst.executeQuery();
    }else {
      con = DBAccess.getConnection();
      pst = con.prepareStatement(sql);
      rs = pst.executeQuery();
    }
    while(rs.next()) {
        //通过反射机制动态获取属性
      T t = (T) class1.newInstance();
      //拿到class1对应的所有属性对象
      Field[] fields = class1.getDeclaredFields();
      for (Field f : fields) {
        f.setAccessible(true);//打开权限
        f.set(t, rs.getObject(f.getName()));
      }
      list.add(t);
    }
    return list;
  }
  /**
   * 最终查询出的数据sql语句
   * @param sql 原查询sql
   * @param pageBean
   * @return
   */
  private String getPageSQL(String sql, PageBean pageBean) {
    return sql+" limit "+pageBean.getStartIndex()+","+pageBean.getRows();
  }
  /**
   * 查询符合条件的总记录数SQL语句
   * @param 原查询sql
   * @return
   */
  private String getCountSQL(String sql) {
    return "SELECT count(1) as n from ("+sql+") t";
  }
}

6.书籍“分页模糊查询所有”方法

package com.ctb.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.ctb.entity.Book;
import com.ctb.utils.BaseDao;
import com.ctb.utils.DBAccess;
import com.ctb.utils.PageBean;
import com.ctb.utils.StringUtils;
/**
 *
 * @author biao
 *
 */
public class BookDao extends BaseDao<Book>{
  /**
   * 分页模糊查询---封装basedao前
   * @param book  实体对象
   * @param pageBean  分页工具
   * @return  list  集合
   * @throws Exception   异常
   */
  public List<Book> list1(Book book,PageBean pageBean) throws Exception{
    List<Book> list = new ArrayList<Book>();
    Connection con = DBAccess.getConnection();
    String sql = "select * from t_mvc_book where 1=1 ";
    String bname = book.getBname();
    if(StringUtils.isNotBlank(bname)) {
      sql += " and bname like '%"+bname+"%'";
    }
    PreparedStatement pst = con.prepareStatement(sql);
    ResultSet rs = pst.executeQuery();
    while(rs.next()) {
      Book b = new Book(rs.getInt("bid"),rs.getString("bname"),rs.getFloat("price"));
      list.add(b);
    }
    return list;
  }
  /**
   * 分页模糊查询 --简便--封装baseDao后
   * @param book
   * @param pageBean
   * @return
   * @throws Exception
   */
  public List<Book> list2(Book book,PageBean pageBean) 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.executeQuery(sql, Book.class, pageBean);
  }
  //测试
  public static void main(String[] args) throws Exception {
    BookDao bookDao = new BookDao();
    Book book = new Book();
    book.setBname("是否");
    PageBean pageBean = new PageBean();
    List<Book> list = bookDao.list1(book, pageBean);
    for (Book b : list) {
      System.out.println(b);
    }
  }
  //junit测试
  @Test
  public void test() throws Exception {
    BookDao bookDao = new BookDao();
    Book book = new Book();
    book.setBname("圣墟");
    PageBean pageBean = new PageBean();
    List<Book> list = bookDao.list2(book, pageBean);
    for (Book b : list) {
      System.out.println(b);
    }
  }
  @Test
  public void test1() throws Exception {
    BookDao bookDao = new BookDao();
    Book book = new Book();
    book.setBname("圣墟");
    PageBean pageBean = new PageBean();
    //pageBean.setPagination(false);//不分页
    pageBean.setPage(2);
    List<Book> list = bookDao.list2(book, pageBean);
    for (Book b : list) {
      System.out.println(b);
    }
    System.out.println(pageBean);
  }
}

查询结果:

test1的结果

七、封装BaseDao的好处

  1. 提高代码复用性:BaseDAO将一些通用的增、删、改、查等方法进行了封装,可以减少代码的重复编写,并且可以提高代码的复用性。
  2. 降低代码耦合性:BaseDAO中一些基本的操作方法比如增、删、改、查等都是独立存在的,即使系统中对数据访问方式有所改动,数据操作的代码部分可以最小程度上的受到影响,达到降低代码耦合性的目的。
  3. 简化代码:BaseDAO中的方法都是经过封装后的代码,可以让在实现具体业务时的代码更加简洁明了。
  4. 易于维护:BaseDAO的封装可以方便后期开发人员的使用和维护,可以减少时间成本和维护成本。
  5. 提高程序的可扩展性和易于维护性:BaseDAO的封装可以提高程序的可扩展性和易于维护性,当系统出现新的数据对象或者改变了数据存取的方式时,只需要简单地继承BaseDAO或重新实现某个功能体现即可。

八、单元测试框架JUnit4

1.简介

JUnit 4是Java语言中广泛使用的单元测试框架,它是JUnit框架的第四个主要版本。JUnit 4是一个用于编写和运行测试的框架,旨在让Java程序员能够更加方便地编写自动化测试和单元测试,并提高代码的质量和可读性。

2.特点

  1. 注解支持:JUnit 4引入了注解的概念,使用注解来标识测试方法、测试类等,使代码更加简洁易读,并且可以方便地扩展测试框架。
  2. 参数化测试:JUnit 4支持参数化测试,可以使用不同的参数值运行测试方法,避免了编写多个测试方法的重复劳动。
  3. 断言API:JUnit 4引入了新的断言API,使得测试代码更加简洁易读,并且可以自定义断言规则。
  4. 可扩展性:JUnit 4框架设计更加灵活和可扩展,可以方便地增加自定义的测试规则和扩展插件。
  5. 易于集成:JUnit 4可以与其他Java开发框架如Maven、Ant等集成使用,方便进行持续集成和自动化测试。

3.基本使用

  1. 编写测试代码:定义一个测试类,使用注解@Test标注测试方法。测试方法中编写测试代码,包括初始化测试数据、调用被测试方法、断言结果是否正确等。
  2. 运行测试用例:启动JUnit测试运行器,运行测试用例。
  3. 分析测试结果:根据测试结果进行分析和修正代码。

通用分页就介绍到这啦,若有疑虑欢迎评论区留言


相关文章
|
8月前
|
SQL 前端开发 Java
通用分页-后台
通用分页-后台
73 0
|
9月前
|
前端开发 Java 测试技术
通用分页【上】
JUnit是流行的、开源的Java单元测试框架,它提供了一种简单而强大的方式来测试Java应用程序中的单元代码。JUnit测试通常涉及创建和运行测试用例,而测试用例是一组独立的测试步骤,用于验证代码是否按照预期工作。JUnit测试通常分为以下四个步骤:定义测试用例:定义每个测试方法所需的输入参数以及期望的输出结果;编写测试代码:编写测试方法并使用断言(Assertion)来验证代码是否按照预期工作;运行测试用例:通常使用JUnit测试浏览器或者其他测试工具来运行测试用例;查看测试结果。
|
7月前
|
前端开发 数据管理 Java
通用分页(下)
通用分页(下)
33 0
|
9月前
|
算法 JavaScript Java
通用分页【下】(将分页封装成标签)
调试()是指在软件开发过程中,通过识别、定位和解决程序错误或问题的过程。调试的目的是找出代码中的错误、异常或不正常的行为,并修复它们,以确保程序能够按照预期的方式运行。调试是一个重要的开发技巧,可以帮助开发人员理解程序的执行过程、找出错误的原因,并从中学习和改进。调试可以使用不同的工具和技术来辅助,例如打印输出、日志记录、调试器(debugger)等。调试是开发过程中不可或缺的一部分,可以帮助开发人员提高代码质量、加快解决问题的速度,并优化程序的性能和可靠性。
|
21天前
|
前端开发 关系型数据库 MySQL
通用分页详解
通用分页详解
38 0
|
6月前
|
前端开发
通用分页02(前台分页)
通用分页02(前台分页)
39 0
|
6月前
通用分页(后台分页)
通用分页(后台分页)
34 0
|
6月前
|
存储 前端开发 Java
详解通用分页(前端)
详解通用分页(前端)
17 0
|
6月前
|
前端开发 Java UED
通用分页集模糊,全部查询,分页查询为一体(2)演示,优化上篇通用查询分页
通用分页集模糊,全部查询,分页查询为一体(2)演示,优化上篇通用查询分页
|
6月前
|
SQL Java 关系型数据库
通用分页详细讲解(后端)
通用分页详细讲解(后端)
36 0