Java手写一个类似PageHelper的分页SQL

目前分页插件众所周知的莫过于和mybatis完美融合的PageHelper了,简单两行代码就实现了sql分页,配合PageInfo类,将数据总数量,页数页码以及分页结果集等前端需要的信息都配齐了;
但是!!!
一个项目不能一直用到mybatis的,总有用到JDBC的时候,PageHelper不对手写的JDBC代码分页,那这个时候只好动动手自己做一个类似的了。

测试环境

  1. Spring Boot:1.5.9
  2. PageInfo类
  3. JDBC工具类(传送门)

开始实践

1. 创建SpringBoot项目

如何创建一个SpringBoot项目这里就不做演示,IDEA中可以直接创建,只要记得在Pom文件中引入依赖

        <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency>

2. 创建PageInfo实体类

想一下需要什么属性,后台跟前端交互分页数据,前端用分页插件需要数据的结果集(List),需要总记录数(totalNum),需要当前页数(currentPage),需要每页显示多少数据(pageSize),需要总页数(totalPages),上一页(previousPage),下一页(nextPage)

好,知道了之后定一个类,取名PageInfo,将以上说的属性定义好,注意几个地方:
1. List、totalNum、currentPage、pageSize需要GetSet方法
2. totalPages、previousPage、nextPage不需要Set方法,只需要Get方法,因为这三个属性的值是通过计算出来的

import java.io.Serializable;
import java.util.List;public class PageInfo<T> implements Serializable{private List<T> list;    //保存页面数据private int totalNum;    //查询到的总记录数private int currentPage;       //用户当前看的页数private int pageSize;        //每页多少条显示数据private int totalPages;        //总页数private int previousPage;    //上一页private int nextPage;        //下一页public static PageInfo startPage(int currentPage, int pageSize){return new PageInfo(currentPage, pageSize);}public PageInfo(int currentPage, int pageSize) {this.currentPage = currentPage;this.pageSize = pageSize;}public void setList(List list) {this.list = list;}public void setTotalNum(int totalNum) {this.totalNum = totalNum;}public void setCurrentPage(int currentPage) {this.currentPage = currentPage;}public void setPageSize(int pageSize) {this.pageSize = pageSize;}public List getList() {return list;}public int getTotalNum() {return totalNum;}public int getCurrentPage() {return currentPage;}public int getPageSize() {return pageSize;}public int getTotalPages() {if (this.totalNum % this.pageSize == 0) {this.totalPages = this.totalNum / this.pageSize;} else {this.totalPages = this.totalNum / this.pageSize + 1;}return this.totalPages;}public int getPreviousPage() {if (currentPage == 1) {previousPage = 1;} else {previousPage = currentPage - 1;}return previousPage;}public int getNextPage() {if (currentPage == totalPages) {nextPage = totalPages;} else {nextPage = currentPage + 1;}return nextPage;}@Overridepublic String toString() {return "PageInfo{" +"list=" + list +", totalNum=" + totalNum +", currentPage=" + currentPage +", pageSize=" + pageSize +", totalPages=" + totalPages +", previousPage=" + previousPage +", nextPage=" + nextPage +'}';}
}

3. 写SQL语句

要准备一个JDBC工具类,博主自己写了一个自己用的,不嫌弃可以直接拿,在博客中有一篇文章是有的,这里我就用自己工具类里的一个方法getTableComment做个例子

理一下思路,要拿到page页数和size一页数据数量,肯定是传进来的,那要创建刚写好的PageInfo类,赋值currentPagepageSize,在SQL中要写上LIMIT ?,?,利用JDBC中PreparedStatement接口类的setInt方法,将参数放进分页条件中,成功分页后将数据取出装入PageInfo的List中,再写一个count(*)SQL,不带分页的查出总记录数,装入totalNum里,这个时候PageInfo类中前面四个属性的值都有了,后面的三个属性会自行的去运算,再将PageInfo这个类返回给前端

public static PageInfo getTableComment(DbConfig dbConfig, Integer page, Integer size) {//连接数据库Connection connection = getConnection(dbConfig);List<Map<String, Object>> tableComment = new ArrayList<>();//赋值currentPage和pageSizePageInfo pageInfo = PageInfo.startPage(page, size);StringBuilder builder = new StringBuilder();builder.append("SELECT ").append("a.data_type jdbcType,").append("b.TABLE_NAME, b.TABLE_COMMENT").append(" FROM information_schema.COLUMNS a ").append("LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS p ON a.table_schema = p.table_schema ").append("LEFT JOIN INFORMATION_SCHEMA.TABLES b ON a.table_schema = b.TABLE_SCHEMA ").append("AND b.TABLE_NAME = a.TABLE_NAME ").append("AND a.table_name = p.TABLE_NAME AND a.COLUMN_NAME = p.COLUMN_NAME ").append("AND p.constraint_name = 'PRIMARY' ").append("WHERE b.table_schema = ").append("'" + dbConfig.getDataBase() + "'").append(" AND p.COLUMN_NAME IS NULL = 'true'").append(" ORDER BY b.TABLE_NAME ").append("LIMIT ?,?");try {PreparedStatement statement = connection.prepareStatement(builder.toString());statement.setQueryTimeout(60000);//通过分页公式计算下一页在哪一行开始//如1,10,1-1 = 0,那第一条开始显示下面十条,第一页//如2,10,(2-1)乘以10 = 10,那就是第十条开始显示下面十条,第二页statement.setInt(1, (page -1) * size);statement.setInt(2, size);ResultSet resultSet = statement.executeQuery();while (resultSet.next()) {String jdbcType = resultSet.getString("jdbcType").toUpperCase();if (jdbcType.equals("VARCHAR")){jdbcType = "String";}else {jdbcType = "Integer";}Map<String, Object> map = new HashMap<>(16);map.put("tableName", resultSet.getString("TABLE_NAME"));map.put("comment", resultSet.getString("TABLE_COMMENT"));map.put("jdbcType", jdbcType);tableComment.add(map);}pageInfo.setList(tableComment);StringBuilder count = new StringBuilder();count.append("SELECT ").append("COUNT(*)").append(" FROM information_schema.COLUMNS a ").append("LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS p ON a.table_schema = p.table_schema ").append("LEFT JOIN INFORMATION_SCHEMA.TABLES b ON a.table_schema = b.TABLE_SCHEMA ").append("AND b.TABLE_NAME = a.TABLE_NAME ").append("AND a.table_name = p.TABLE_NAME AND a.COLUMN_NAME = p.COLUMN_NAME ").append("AND p.constraint_name = 'PRIMARY' ").append("WHERE b.table_schema = ").append("'" + dbConfig.getDataBase() + "'").append(" AND P.COLUMN_NAME IS NULL = 'true'");statement = connection.prepareStatement(count.toString());resultSet = statement.executeQuery();if (resultSet.next()){pageInfo.setTotalNum(resultSet.getInt(1));}logger.info("查询成功" + tableComment);} catch (SQLException e) {e.printStackTrace();} finally {if (connection != null) {closeConnection(connection);connection = null;}}return pageInfo;}

4. 写一个接口做测试

新建一个Controller,写一个接口调用JDBC方法,将PageInfo类返回前端

    @GetMapping("/tableComment")public PageInfo tableComment(DbConfig dbConfig, @RequestParam(defaultValue = "1",required = false) Integer page,@RequestParam(defaultValue = "10",required = false) Integer size){PageInfo pageInfo = DataBaseUtil.getTableComment(dbConfig, page, size);return pageInfo;}

启动项目,调用一下这个接口,查看一下返回的数据对不对,这里我默认一页十条

好,数据返回的没问题,该有的数据都拿到了,手写一个SQL分页的大致思路就是这样。

Java 手写一个SQL分页相关推荐

  1. 用Java手写一个微型下载资源网站

    文章目录 手写一个微型下载资源网站[Java实现用户注册.登陆.下载功能] 一.技术栈 二.流程分析图 注册 登陆 下载 三.案例实现效果 首页 注册 登陆 下载网主页 壁纸下载 书籍下载 影视下载 ...

  2. java手写一个分页的方法_java web手写实现分页功能

    现在很多流行的框架,都可以很快的把分页效果做出来,但是作为一名程序员你必须得知道手写分页的流程: 场景效果: 一.分页的思路 首先我们得知道写分页代码的思路,保持思路清晰,才能行云流水的去写代码,其实 ...

  3. 用 Java 手写一个植物大战僵尸简易版!

    点击上方"终端研发部",选择"星标" 回复"资源",领取全网最火的Java核心知识总结~ 公众号后台回复"学习",获取作 ...

  4. 使用 JAVA 手写一个录屏GUI程序

    使用JAVAFX模块写的GUI程序,供学习使用. 先上一下动态效果图展示,下面分别是主界面和菜单界面,实现的功能有转GIF(需要用到ffmpeg),压缩视频,定时录屏等. 代码部分 public fi ...

  5. Java 手写一个简单计算器(1)

    用java的awt和swing实现了界面, 结构比较简单,用GridLayout布局实现 文本框+3行按钮+3行按钮: 按钮用字符串数组和for循环 后两个用JPanel存放 然后加到框架中即可 由于 ...

  6. 第二季:5公平锁/非公平锁/可重入锁/递归锁/自旋锁谈谈你的理解?请手写一个自旋锁【Java面试题】

    第二季:5值传递和引用传递[Java面试题] 前言 推荐 值传递 说明 题目 24 TransferValue醒脑小练习 第二季:5公平锁/非公平锁/可重入锁/递归锁/自旋锁谈谈你的理解?请手写一个自 ...

  7. 手写一个栈 java,数据结构|用java自己手写实现一个栈

    javaDEMO 本网站记录了最全的各种JavaDEMO ,保证下载,复制就是可用的,包括基础的, 集合的, spring的, Mybatis的等等各种,助力你从菜鸟到大牛,记得收藏哦~~ https ...

  8. 手写一个原神祈愿分析工具

    手写一个原神祈愿分析工具 之前一直通过游创工坊来进行祈愿抽卡数据分析,但是广告太多,而且担心auth_key泄露,于是自己花了一天时间动手实现了个数据分析工具,数据永久保存在本地,没有信息泄露风险,话 ...

  9. 肝一波 ~ 手写一个简易版的Mybatis,带你深入领略它的魅力!

    零.准备工作 <dependencies><dependency><groupId>mysql</groupId><artifactId>m ...

最新文章

  1. js页面跳转或重定向
  2. 597个智慧城市相关试点将临大考
  3. android自定义弹框效果合集,android 自定义弹出框AlertDialog ,很炫的哦
  4. 下拉列表框Spinner
  5. 【深度学习】sigmoid - 二次代价函数 - 交叉熵 - logistic回归 - softmax
  6. XML Schema全接触 (这里主要介绍W3C的Schema标准语法)
  7. python下载matplotlib.finance模块_关于Matplotlib中No module named 'matplotlib.finance'的解决办法...
  8. 一种用javascript实现的比较兼容的回到顶部demo + 阻止事件冒泡
  9. 阿里开源自研语音识别模型 DFSMN,准确率高达96.04%
  10. HTML5触摸事件演化tap事件
  11. 非华为手机可以用鸿蒙吗,【图片】华为鸿蒙系统的厉害之处在于 你可能非用不可 !【手机吧】_百度贴吧...
  12. Objective-C 一些很基础的总结
  13. QT4.7.3在dm6446平台上的移植[转]--make[1]: *** [assistant_cs.qm] Error 2
  14. 苹果决定不修复 Big Sur 和 Catalina 中的这两个0day
  15. fastReport 绑定DataBand数据源后还是打印出一条数据
  16. C语言输出素数表(1-100)前100个
  17. 3cdaemon漏洞挖掘 Exploit
  18. 2021-08-01 武大账号访问知网
  19. mybatis基础(上)
  20. 重磅!图森王乃岩团队最新工作—TridentNet:处理目标检测中尺度变化新思路

热门文章

  1. ios apple语音性别_iOS 14:Apple终于听了
  2. 最长回文子串(Java实现)
  3. matplotlib可视化番外篇bar()--带误差棒的柱状图
  4. 学习笔记5:mysql高可用(主从复制监控)
  5. WIN7 32位 SP1 安装VS2010失败,解决过程记录
  6. git fork代码保持与原代码同步
  7. 关于佳能打印机墨盒的一些操作
  8. 攻防世界-misc-流量分析1
  9. RHEL6.0下LVS-DR+ipvsadm实现服务集群
  10. 安全技术(Security)