通用分页的详解(Java后端常用)

简介: 通用分页的详解(Java后端常用)

一.通用分页

1.1通用分页是什么?

JSP通用分页(JSP Universal Pagination)是指在JSP网页开发中,应用一些通用的技术实现数据分页功能

1.2使用通用分页有什么好处?

使用分页,每次就会处理一小块的数据,JSP通用分页技术可以简化数据分页功能的开发,提升开发效率,使得网站的用户交互更加友好。当我们需要在网页中展示大量的数据时,可以将数据进行分页处理,避免一次性将所有数据都展示出来,从而避免页面加载速度慢或者出现内存溢出等问题。使用JSP通用分页技术可以方便地实现数据分页功能,开发人员可以根据具体业务需求,灵活地设置每页显示的数量和页面导航条的样式,提高网站的用户体验

1.3经常在哪使用通用分页?

JSP通用分页技术可以在任何需要分页展示数据的网页中使用,比如商品列表、文章列表、用户列表等。

  1. 商品列表页面:在电商网站中,一般需要展示大量的商品信息,使用JSP通用分页可以避免一次性将所有商品信息都展示出来,提高页面加载速度,同时方便用户浏览和选择。
  2. 文章列表页面:在新闻网站或博客网站中,也需要展示大量的文章信息,使用JSP通用分页可以将文章信息进行分页处理,避免页面加载过慢或出现内存溢出等问题。
  3. 用户列表页面:在管理系统或人才招聘网站中,需要展示大量的用户信息,使用JSP通用分页也可以方便地实现数据分页展示,方便管理员或招聘方查看和管理。
  4. 其他列表页面:在各种需要展示数据的场景中,使用JSP通用分页可以方便开发人员实现数据的分页展示,提高用户体验。

需要注意的是,JSP通用分页技术通常需要与数据库进行交互,因此需要熟悉JDBC等相关技术,同时在编写JSP页面和JavaBean时也需要一定的开发经验。

二.往常的通用分页实现及代码

实现思路:先封装一个分页工具类保存页码、一页的条目、总记录数以及是否分页,然后当成参数传递到Dao层的分页方法中,再将需要查询的关键词或是类别传递即可,但是这种分页查询方式非常的冗杂,下面看一下实现的代码!!

分页工具类

package com.lya.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 + "]";
  }
}

Dao层

package com.lya.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.lya.entity.Book;
import com.lya.util.DBAccess;
import com.lya.util.PageBean;
import com.lya.util.StringUtils;
/**
 * S阶段写法与使用BaseDao之后的对比
 * 
 * @author :JAVA-李永安
 * @date :2023年6月27日 上午10:53:47
 */
public class BookDaoS extends BaseDao<Book> {
  /**
   * 未使用BaseDao
   * 
   * @param book
   * @param pagebeam
   * @return
   * @throws Exception
   */
  public List<Book> ckbook1(Book book, PageBean pagebeam) throws Exception {
    Connection conn = DBAccess.getConnection();
    String sql = "select * from t_mvc_book where 1=1";
    String bname = book.getBname();
    // StringUtils.isNotBlank(bname)------用于判断bname是否为空
    if (StringUtils.isNotBlank(bname)) {
      sql += " and bname like '%" + bname + "%'";
    }
    PreparedStatement stmt = conn.prepareStatement(sql);
    List<Book> list = new ArrayList<Book>();
    ResultSet rs = stmt.executeQuery();
    while (rs.next()) {
      Book b = new Book();
      b.setBid(rs.getInt("bid"));
      b.setBname(rs.getString("bname"));
      b.setPrice(rs.getFloat("price"));
      list.add(b);
    }
    return list;
  }
  public static void main(String[] args) {
    BookDaoS bookDaoS = new BookDaoS();
    Book book = new Book();
    book.setBname("斗");
    PageBean pagebeam = new PageBean();
    List<Book> ckbook = null;
    try {
      ckbook = new BookDaoS().ckbook2(book, pagebeam);
    } catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    for (Book book2 : ckbook) {
      System.out.println(book2);
    }
  }

实现效果:

 

但是这种分页查询方式非常的冗杂,下面我们用一种简单的方法下实现简化它!!!

三、通用分页的讲解(思路+具体实现代码)

实现通用分页思路分析:

首先我们得知道通用分页必须要有的参数属性:是否分页,页码,页大小,总记录数

1.所有分页代码都大同小异,只有sql语句和遍历结果集的区域代码不一致,所以我们只需要将这里稍加改动,就可以变成我们的通用分页。

2.我们通用的basedao里面要判断是否分页,如果不需要分页的话就进行“原sql”查询即可,需要分页,就将模糊查询的总记录数计算出来以及回显最终展示的数据即可。其次就是遍历结果集的时候,因为我们不知道将来传递进来的是什么对象,所以可以用到反射的机制获取属性。

 

3.具体实现的代码(内有详细注解)

①编写BaseDao(通用分页)

package com.lya.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.lya.entity.Book;
import com.lya.util.DBAccess;
import com.lya.util.PageBean;
import com.lya.util.StringUtils;
/**
 * 通用的增删改查(分页的显示)
 * 
 * @author :JAVA-李永安
 * @date :2023年6月27日 上午11:38:42
 */
public class BaseDao<T> {
  /**
   * @param sql
   *            sql语句
   * @param cla
   *            类对象
   * @param pagebeam
   *            分页工具类
   * @return
   * @throws Exception
   */
  public List<T> excuteQuery(String sql, Class cla, PageBean pagebeam) throws Exception {
    Connection conn = null;
    PreparedStatement stmt = null;
    ResultSet rs = null;
    List<T> list = new ArrayList<T>();
    // 这里我们考虑两种情况:
    // (一)需要使用分页,
    if (pagebeam != null && pagebeam.isPagination()) {
      // 这里定义分页的两个重要的属性:
      // countSQL(执行待条件sql后的记录数),sql参数在调用时拼写
      // pageSQl(执行待条件sql后返回的内容),sql参数在调用时拼写,pagebeam参数是传递起始参数的
      String countSQL = getCountSQL(sql);
      conn = DBAccess.getConnection();
      stmt = conn.prepareStatement(countSQL);
      rs = stmt.executeQuery();
      // 当我们查询一次countSQL后就得到单个数据---我们用if不用while
      if (rs.next()) {
        pagebeam.setTotal(rs.getObject("n").toString());
      }
      String pageSQl = getPageSQl(sql, pagebeam);
      conn = DBAccess.getConnection();
      stmt = conn.prepareStatement(pageSQl);
      rs = stmt.executeQuery();
      System.out.println(countSQL+"  "+pageSQl);
    }
    // (二)不需要使用分页
    else {
      conn = DBAccess.getConnection();
      stmt = conn.prepareStatement(sql);
      rs = stmt.executeQuery();
    }
    while (rs.next()) {
      // 使用反射(拿到类的属性值)
      T t = (T) cla.newInstance();// 实例类类
      Field[] fd = cla.getDeclaredFields();// 获取属性
      for (Field f : fd) {// 遍历fd
        f.setAccessible(true);// 打开权限
        f.set(t, rs.getObject(f.getName()));// 为T设置属性值
      }
      list.add(t);
    }
    return list;
  }
  /**
   * 执行待条件sql后的记录数
   * 
   * @param sql
   * @return
   */
  private String getCountSQL(String sql) {
    // TODO Auto-generated method stub
    // SELECT count(*) as a FROM(SELECT * FROM`t_mvc_book` where Bname like '%圣%')t
    return "SELECT count(1) as n FROM(" + sql + ")t";
  }
  /**
   * 执行待条件sql后返回的内容
   * 
   * @param sql
   * @return
   */
  private String getPageSQl(String sql, PageBean pagebeam) {
    // TODO Auto-generated method stub
    // SELECT * FROM `t_mvc_book` where Bname like '%圣%' limit 0,10
//    return "'" + sql + "' limit '" + pagebeam.getStartIndex() + "' , '" + pagebeam.getRows() + "'  ";
    return sql + " limit " + pagebeam.getStartIndex() + "," + pagebeam.getRows();
  }
}

②具体实现类(以book为例)

package com.lya.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.lya.entity.Book;
import com.lya.util.DBAccess;
import com.lya.util.PageBean;
import com.lya.util.StringUtils;
/**
 * S阶段写法与使用BaseDao之后的对比
 * 
 * @author :JAVA-李永安
 * @date :2023年6月27日 上午10:53:47
 */
public class BookDaoS extends BaseDao<Book> {
  /**
   * 未使用BaseDao
   * 
   * @param book
   * @param pagebeam
   * @return
   * @throws Exception
   */
  public List<Book> ckbook1(Book book, PageBean pagebeam) throws Exception {
    Connection conn = DBAccess.getConnection();
    String sql = "select * from t_mvc_book where 1=1";
    String bname = book.getBname();
    // StringUtils.isNotBlank(bname)------用于判断bname是否为空
    if (StringUtils.isNotBlank(bname)) {
      sql += " and bname like '%" + bname + "%'";
    }
    PreparedStatement stmt = conn.prepareStatement(sql);
    List<Book> list = new ArrayList<Book>();
    ResultSet rs = stmt.executeQuery();
    while (rs.next()) {
      Book b = new Book();
      b.setBid(rs.getInt("bid"));
      b.setBname(rs.getString("bname"));
      b.setPrice(rs.getFloat("price"));
      list.add(b);
    }
    return list;
  }
  /**
   * 使用BaseDao
   * 
   * @param book
   * @param pagebeam
   * @return
   * @throws Exception
   */
  public List<Book> ckbook2(Book book, PageBean pagebeam) throws Exception {
    String sql = "select * from t_mvc_book where 1=1";
    String bname = book.getBname();
    // StringUtils.isNotBlank(bname)------用于判断bname是否为空
    if (StringUtils.isNotBlank(bname)) {
      sql += " and bname like '%" + bname + "%'";
    }
    // super用法
    return super.excuteQuery(sql, Book.class, pagebeam);
  }
  public static void main(String[] args) {
    BookDaoS bookDaoS = new BookDaoS();
    Book book = new Book();
    book.setBname("斗");
    PageBean pagebeam = new PageBean();
    List<Book> ckbook = null;
    try {
      ckbook = new BookDaoS().ckbook2(book, pagebeam);
    } catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    for (Book book2 : ckbook) {
      System.out.println(book2);
    }
  }
  @Test
  public void test1() throws Exception {
    System.out.println("test1======");
    BookDaoS bookDaoS = new BookDaoS();
    Book book = new Book();
    book.setBname("圣");
    PageBean pagebeam = new PageBean();
    List<Book> ckbook = new BookDaoS().ckbook1(book, pagebeam);
    for (Book book2 : ckbook) {
      System.out.println(book2);
    }
  }
  @SuppressWarnings("unused")
  @Test
  public void test2() throws Exception {
    System.out.println("test2======");
    BookDaoS bookDaoS = new BookDaoS();
    Book book = new Book();
    book.setBname("圣");
    PageBean pagebeam = new PageBean();
    List<Book> ckbook = new BookDaoS().ckbook2(book, pagebeam);
    for (Book book2 : ckbook) {
      System.out.println(book2);
    }
  }
  @Test
  public void test3() throws Exception {
    System.out.println("test3======");
    BookDaoS bookDaoS = new BookDaoS();
    Book book = new Book();
    book.setBname("圣");
    PageBean pagebeam = new PageBean();
    List<Book> ckbook = new BookDaoS().ckbook2(book, pagebeam);
    for (Book book2 : ckbook) {
      System.out.println(book2);
    }
    System.out.println(pagebeam);
  }
}

③实现效果

以上我们就能实现通用的分页功能了,若有不明白的可以评论留言,我会及时为大家解答!

四,JUnit框架的使用

4.1JUnit框架是什么?

JUnit是一个轻量级的Java应用程序测试框架,可用于编写和运行自动化测试

4.2JUnit框架有什么优势

通过JUnit,开发人员可以在编写代码时预先编写测试逻辑并运行测试来验证代码的正确性。JUnit使用简单,它可以帮助开发人员快速编写和运行测试用例,同时提供了标准的断言和测试结果报告工具。

  1. 易于学习和使用:JUnit使用简单,开发人员只需要编写单元测试代码并运行测试即可对代码进行测试。
  2. 可用于各种项目:JUnit适用于各种Java应用程序,无论是Web应用程序,还是桌面应用程序。
  3. 提高代码的质量:通过JUnit,开发人员可以在编写代码时预先编写测试用例,从而提高代码的质量和可靠性。
  4. 快速反馈:JUnit通过执行测试用例来验证代码的正确性,可以在开发人员修改代码时快速反馈测试结果,提高开发效率。

JUnit是一个开源框架可以在任何Java开发环境中使用,如Eclipse、NetBeans、IntelliJ IDEA等。由于JUnit的广泛应用,许多Java开发工具都集成了JUnit,以便开发人员快速创建和运行测试用例。

4.3JUnit框架具体使用步骤:我以eclipse为例

4.3.1创建项目先配置JUnit框架

4.3.2到eclipse配置中进行相关操作

4.3.3到eclipse配置中进行相关操作(建议选中4的版本!)

4.3.3到类中进行实际操作

@test是JUnit的标准

运行效果:

五,SQL中limit

5.5.1limit是什么?

在SQL中,LIMIT是一种用于限制查询结果集返回的行数的操作。在支持LIMIT语法的数据库中,通常将其作为查询语句的最后一部分,语法格式一般为:

select * from 数据表名 where ...like ‘%...%’ limit 从...开始 ,显示...的行数

5.5.2limit怎么使用?

以下是我以navicat 连接mysql 使用的limit查询

需要注意的是,LIMIT只是限制了返回结果的行数,并不影响数据库中原始数据的行数。LIMIT并非所有数据库都支持,不同的数据库有不同的实现方式。例如,MySQL中支持LIMIT语法,而Oracle数据库中没有LIMIT语法,而是使用ROWNUM实现类似的功能。另外,在使用LIMIT时,应考虑查询效率和性能问题,以免影响查询速度和系统的响应能力。

六,isNotEmpty()和isNotBlank()的用法及区别

相同点:

isNotEmpty()和isNotBlank() 都是Apache Commons Lang库(一个Java开源库)中StringUtils工具包下两个判断字符串是否为空的方法

方法常用于数据校验、字符串处理、表单验证等场景中,可以减轻开发人员的工作量,提高代码的可读性和健壮性。

不同点:isNotBlank()还需要判断length是否>0

具体使用:

isNotBlank:判断某字符串是否不为空且长度不为0   如果为空返回false

这篇通用分页的分享就到这里,若有不明白的可以评论留言,我会及时为大家解答!

目录
相关文章
|
25天前
|
前端开发 小程序 Java
uniapp上传图片 前端以及java后端代码实现
uniapp上传图片 前端以及java后端代码实现
35 0
|
2月前
|
Web App开发 SQL Java
javaweb实现分页(二)
javaweb实现分页(二)
20 1
|
2月前
|
Web App开发 Java 关系型数据库
java中部的分页实现(二)
java中部的分页实现(二)
17 1
|
2月前
Mybatis+mysql动态分页查询数据案例——分页工具类(Page.java)
Mybatis+mysql动态分页查询数据案例——分页工具类(Page.java)
25 1
|
24天前
|
消息中间件 Java 微服务
构建高性能微服务架构:Java后端实践
【4月更文挑战第8天】 在当今互联网应用的快速迭代与高并发挑战下,微服务架构以其灵活性和扩展性成为众多企业技术选型的宠儿。本文将深入探讨在Java后端开发中,如何构建一个高性能的微服务系统,涵盖从基础架构设计、关键技术选型到性能优化策略的全方位分析。我们将透过实际案例,剖析微服务实践中的最佳模式与常见陷阱,为后端开发人员提供一份实操指南。
|
3天前
|
安全 Java 开发者
构建高效微服务架构:后端开发的新范式Java中的多线程并发编程实践
【4月更文挑战第29天】在数字化转型的浪潮中,微服务架构已成为软件开发的一大趋势。它通过解耦复杂系统、提升可伸缩性和促进敏捷开发来满足现代企业不断变化的业务需求。本文将深入探讨微服务的核心概念、设计原则以及如何利用最新的后端技术栈构建和部署高效的微服务架构。我们将分析微服务带来的挑战,包括服务治理、数据一致性和网络延迟问题,并讨论相应的解决方案。通过实际案例分析和最佳实践的分享,旨在为后端开发者提供一套实施微服务的全面指导。 【4月更文挑战第29天】在现代软件开发中,多线程技术是提高程序性能和响应能力的重要手段。本文通过介绍Java语言的多线程机制,探讨了如何有效地实现线程同步和通信,以及如
|
24天前
|
JSON 前端开发 Java
⚠⚠⚠java后端开发中,前后端联调过程一些常见的低级/低端问题汇总⚠⚠⚠
⚠⚠⚠java后端开发中,前后端联调过程一些常见的低级/低端问题汇总⚠⚠⚠
|
24天前
|
安全 Java 持续交付
构建高性能微服务架构:Java后端的实践之路
【4月更文挑战第8天】 在现代软件开发领域,微服务架构已经成为提高系统可维护性、扩展性和技术栈独立性的关键解决方案。本文将深入探讨如何利用Java后端技术构建一个高性能的微服务系统。我们将重点讨论微服务设计原则、系统拆分策略、关键性能优化技巧以及安全性考虑。通过实际案例分析,揭示如何在保证系统稳定性的同时实现敏捷开发和部署。
|
2月前
|
SQL 前端开发 Java
Java后端进阶之路: JavaWeb(四)
Java后端进阶之路: JavaWeb
35 1
|
XML SQL Java
Java后端进阶之路: JavaWeb(三)
Java后端进阶之路: JavaWeb
34 1