2020-03-24 11:33发布
代码如下
Java手写一个类似PageHelper的分页SQL
目前分页插件众所周知的莫过于和mybatis完美融合的PageHelper了,简单两行代码就实现了sql分页,配合PageInfo类,将数据总数量,页数页码以及分页结果集等前端需要的信息都配齐了;但是!!!一个项目不能一直用到mybatis的,总有用到JDBC的时候,PageHelper不对手写的JDBC代码分页,那这个时候只好动动手自己做一个类似的了。
测试环境
SpringBoot:1.5.9PageInfo类JDBC工具类(传送门)
开始实践
创建SpringBoot项目
如何创建一个SpringBoot项目这里就不做演示,IDEA中可以直接创建,只要记得在Pom文件中引入依赖
mysql
mysql-connector-java
runtime
2.创建PageInfo实体类
想一下需要什么属性,后台跟前端交互分页数据,前端用分页插件需要数据的结果集(List),需要总记录数(totalNum),需要当前页数(currentPage),需要每页显示多少数据(pageSize),需要总页数(totalPages),上一页(previousPage),下一页(nextPage)
好,知道了之后定一个类,取名PageInfo,将以上说的属性定义好,注意几个地方:1.List、totalNum、currentPage、pageSize需要Get和Set方法2.totalPages、previousPage、nextPage不需要Set方法,只需要Get方法,因为这三个属性的值是通过计算出来的
importjava.io.Serializable;
importjava.util.List;
publicclassPageInfoimplementsSerializable{
privateListlist;//保存页面数据
privateinttotalNum;//查询到的总记录数
privateintcurrentPage;//用户当前看的页数
privateintpageSize;//每页多少条显示数据
privateinttotalPages;//总页数
privateintpreviousPage;//上一页
privateintnextPage;//下一页
publicstaticPageInfostartPage(intcurrentPage,intpageSize){
returnnewPageInfo(currentPage,pageSize);
}
publicPageInfo(intcurrentPage,intpageSize){
this.currentPage=currentPage;
this.pageSize=pageSize;
publicvoidsetList(Listlist){
this.list=list;
publicvoidsetTotalNum(inttotalNum){
this.totalNum=totalNum;
publicvoidsetCurrentPage(intcurrentPage){
publicvoidsetPageSize(intpageSize){
publicListgetList(){
returnlist;
publicintgetTotalNum(){
returntotalNum;
publicintgetCurrentPage(){
returncurrentPage;
publicintgetPageSize(){
returnpageSize;
publicintgetTotalPages(){
if(this.totalNum%this.pageSize==0){
this.totalPages=this.totalNum/this.pageSize;
}else{
this.totalPages=this.totalNum/this.pageSize+1;
returnthis.totalPages;
publicintgetPreviousPage(){
if(currentPage==1){
previousPage=1;
previousPage=currentPage-1;
returnpreviousPage;
publicintgetNextPage(){
if(currentPage==totalPages){
nextPage=totalPages;
nextPage=currentPage+1;
returnnextPage;
@Override
publicStringtoString(){
return"PageInfo{"+
"list="+list+
",totalNum="+totalNum+
",currentPage="+currentPage+
",pageSize="+pageSize+
",totalPages="+totalPages+
",previousPage="+previousPage+
",nextPage="+nextPage+
'}';
3.写SQL语句
要准备一个JDBC工具类,博主自己写了一个自己用的,不嫌弃可以直接拿,在博客中有一篇文章是有的,这里我就用自己工具类里的一个方法getTableComment做个例子
理一下思路,要拿到page页数和size一页数据数量,肯定是传进来的,那要创建刚写好的PageInfo类,赋值currentPage和pageSize,在SQL中要写上LIMIT?,?,利用JDBC中PreparedStatement接口类的setInt方法,将参数放进分页条件中,成功分页后将数据取出装入PageInfo的List中,再写一个count(*)SQL,不带分页的查出总记录数,装入totalNum里,这个时候PageInfo类中前面四个属性的值都有了,后面的三个属性会自行的去运算,再将PageInfo这个类返回给前端
publicstaticPageInfogetTableComment(DbConfigdbConfig,Integerpage,Integersize){
//连接数据库
Connectionconnection=getConnection(dbConfig);
List>tableComment=newArrayList<>();
//赋值currentPage和pageSize
PageInfopageInfo=PageInfo.startPage(page,size);
StringBuilderbuilder=newStringBuilder();
builder.append("SELECT")
.append("a.data_typejdbcType,")
.append("b.TABLE_NAME,b.TABLE_COMMENT")
.append("FROMinformation_schema.COLUMNSa")
.append("LEFTJOININFORMATION_SCHEMA.KEY_COLUMN_USAGEASpONa.table_schema=p.table_schema")
.append("LEFTJOININFORMATION_SCHEMA.TABLESbONa.table_schema=b.TABLE_SCHEMA")
.append("ANDb.TABLE_NAME=a.TABLE_NAME")
.append("ANDa.table_name=p.TABLE_NAMEANDa.COLUMN_NAME=p.COLUMN_NAME")
.append("ANDp.constraint_name='PRIMARY'")
.append("WHEREb.table_schema=").append("'"+dbConfig.getDataBase()+"'")
.append("ANDp.COLUMN_NAMEISNULL='true'").append("ORDERBYb.TABLE_NAME")
.append("LIMIT?,?");
try{
PreparedStatementstatement=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);
ResultSetresultSet=statement.executeQuery();
while(resultSet.next()){
StringjdbcType=resultSet.getString("jdbcType").toUpperCase();
if(jdbcType.equals("VARCHAR")){
jdbcType="String";
jdbcType="Integer";
Mapmap=newHashMap<>(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);
StringBuildercount=newStringBuilder();
count.append("SELECT")
.append("COUNT(*)")
.append("ANDP.COLUMN_NAMEISNULL='true'");
statement=connection.prepareStatement(count.toString());
resultSet=statement.executeQuery();
if(resultSet.next()){
pageInfo.setTotalNum(resultSet.getInt(1));
logger.info("查询成功"+tableComment);
}catch(SQLExceptione){
e.printStackTrace();
}finally{
if(connection!=null){
closeConnection(connection);
connection=null;
returnpageInfo;
4.写一个接口做测试
新建一个Controller,写一个接口调用JDBC方法,将PageInfo类返回前端
@GetMapping("/tableComment")
publicPageInfotableComment(DbConfigdbConfig,
@RequestParam(defaultValue="1",required=false)Integerpage,
@RequestParam(defaultValue="10",required=false)Integersize){
PageInfopageInfo=DataBaseUtil.getTableComment(dbConfig,page,size);
启动项目,调用一下这个接口,查看一下返回的数据对不对,这里我默认一页十条
好,数据返回的没问题,该有的数据都拿到了,手写一个SQL分页的大致思路就是这样。
看评论区大神
python中单行注释采用 #开头示例:#this is a comment二、批量、多行注释符号多行注释是用三引号,例如:输入''' '''或者 ,将要注释的代码插在中间三、Windows下的IDLE的注释快捷键是Alt+3,取消注释是Alt+4四、python中文注释方法...
apply
标准库Python拥有一个强大的标准库。Python语言的核心只包含数字、字符串、列表、字典、文件等常见类型和函数,而由Python标准库提供了系统管理、网络通信、文本处理、数据库接口、图形系统、XML处理等额外的功能。Python标准库的主要功能有:1.文本处理,包...
Python Lambda函数是没有任何名称的函数。它们也称为匿名或无名功能。 lambda一词不是名称,而是关键字。此关键字指定后面的函数是匿名的。现在您已经知道这些匿名函数指的是什么,让我们进一步了解一下如何编写这些Python Lambda函数。...
Linux操作系统是基于UNIX操作系统发展而来的一种克隆系统,它诞生于1991 年的 [Linux桌面] 10 月5 日(这是第一次正式向外公布的时间)。以后借助于Internet网络,并通过全世界各地计算机爱好者的共同努力,已成为今天世界上使用最多的一种UNIX 类操作系统,...
深度学习工程师就业路径目前,成为深度学习工程师有两条路径:一是通过春秋两季的校园招聘,另一种是借助社会招聘跨行业转型。前述文章曾经将深度学习工程师分为算法工程师、后端工程师和前端工程师。综合目前市面上各大公司招聘和咨询报告结果,目前工作3-5...
零基础学编程,用python入门是个不错的选择,虽然国内基本上还是以c语言作为入门开发语言,但在国外,已经有很多的学校使用python作为入门编程语言。此外,python在机器学习,人工智能领域也非常流行,算得上是算法工程师的标配编程语言。...
包是一个有层次的文件目录结构,它定义了由n个模块或n个子包组成的python应用程序执行环境。通俗一点:包是一个包含__init__.py 文件的目录,该目录下一定得有这个__init__.py文件和其它模块或子包。python库是参考其它编程语言的说法,就是指python中的完成...
1、len(mapping) 返回映射的长度(键-值对的个数)2、hash(obj) 返回obj的哈希值>>> myDict = {'name':'earth', 'port':'80'} >>> len(myDict) 2 >>> hash('name') 1...
常用内建属性说明触发方式__init__构造初始化函数创建实例后,赋值时使用,在__new__后__new__生成实例所需属性创建实例时__class__实例所在的类实例.__class____str__实例字符串表示(可读性)print(类实例),如没实现则使用repr结果__repr__实例字符串表示...
‘‘‘关键字:False:bool数据类型True:bool数据类型None:表示数据的内容为空and:逻辑运算符:与or:逻辑运算符:或not:逻辑运算符:非in:身份运算符,判断变量是否在序列中is :成员运算符,判断变量是否为某个类的实例del:删除变量或序列的值assert:列...
函数注释语法函数注释包括:参数注释:以冒号(:)标记返回值注释:以 -> 标记语法结构大体如下:1、def foo(a: expression, b: expression = 5) -> expression:2、 ...在伪语法中,参数看起来像:identifier [: expression] [= expression]。也就是说,参数...
OpenDoor变量的命名: year_month_day = 2020-7-24 这样写以后都会写很多单词,比较麻烦,可以用ymd代替,然后在第一行或者句尾添加注释说明 a, b, c =1,2, 3 这样的赋值在python中也是可以用的
Python 使用井号#作为单行注释的符号,语法格式为:# 注释内容从井号#开始,直到这行结束为止的所有内容都是注释。Python 解释器遇到#时,会忽略它后面的整行内容。说明多行代码的功能时一般将注释放在代码的上一行多行注释指的是一次性注释程序中多行的内容...
在IDLE中,常用 Alt + 3 给当前行进行注释 Alt + 4 取消当前行的注释在Pycharm中,常用 Ctrl + / 将所选部分快速注释,再按一次 Ctrl + / 可以将所选部分注释取消...
最多设置5个标签!
代码如下
Java手写一个类似PageHelper的分页SQL
目前分页插件众所周知的莫过于和mybatis完美融合的PageHelper了,简单两行代码就实现了sql分页,配合PageInfo类,将数据总数量,页数页码以及分页结果集等前端需要的信息都配齐了;但是!!!一个项目不能一直用到mybatis的,总有用到JDBC的时候,PageHelper不对手写的JDBC代码分页,那这个时候只好动动手自己做一个类似的了。
测试环境
SpringBoot:1.5.9PageInfo类JDBC工具类(传送门)
开始实践
创建SpringBoot项目
如何创建一个SpringBoot项目这里就不做演示,IDEA中可以直接创建,只要记得在Pom文件中引入依赖
2.创建PageInfo实体类
想一下需要什么属性,后台跟前端交互分页数据,前端用分页插件需要数据的结果集(List),需要总记录数(totalNum),需要当前页数(currentPage),需要每页显示多少数据(pageSize),需要总页数(totalPages),上一页(previousPage),下一页(nextPage)
好,知道了之后定一个类,取名PageInfo,将以上说的属性定义好,注意几个地方:1.List、totalNum、currentPage、pageSize需要Get和Set方法2.totalPages、previousPage、nextPage不需要Set方法,只需要Get方法,因为这三个属性的值是通过计算出来的
importjava.io.Serializable;
importjava.util.List;
publicclassPageInfoimplementsSerializable{
privateListlist;//保存页面数据
privateinttotalNum;//查询到的总记录数
privateintcurrentPage;//用户当前看的页数
privateintpageSize;//每页多少条显示数据
privateinttotalPages;//总页数
privateintpreviousPage;//上一页
privateintnextPage;//下一页
publicstaticPageInfostartPage(intcurrentPage,intpageSize){
returnnewPageInfo(currentPage,pageSize);
}
publicPageInfo(intcurrentPage,intpageSize){
this.currentPage=currentPage;
this.pageSize=pageSize;
}
publicvoidsetList(Listlist){
this.list=list;
}
publicvoidsetTotalNum(inttotalNum){
this.totalNum=totalNum;
}
publicvoidsetCurrentPage(intcurrentPage){
this.currentPage=currentPage;
}
publicvoidsetPageSize(intpageSize){
this.pageSize=pageSize;
}
publicListgetList(){
returnlist;
}
publicintgetTotalNum(){
returntotalNum;
}
publicintgetCurrentPage(){
returncurrentPage;
}
publicintgetPageSize(){
returnpageSize;
}
publicintgetTotalPages(){
if(this.totalNum%this.pageSize==0){
this.totalPages=this.totalNum/this.pageSize;
}else{
this.totalPages=this.totalNum/this.pageSize+1;
}
returnthis.totalPages;
}
publicintgetPreviousPage(){
if(currentPage==1){
previousPage=1;
}else{
previousPage=currentPage-1;
}
returnpreviousPage;
}
publicintgetNextPage(){
if(currentPage==totalPages){
nextPage=totalPages;
}else{
nextPage=currentPage+1;
}
returnnextPage;
}
@Override
publicStringtoString(){
return"PageInfo{"+
"list="+list+
",totalNum="+totalNum+
",currentPage="+currentPage+
",pageSize="+pageSize+
",totalPages="+totalPages+
",previousPage="+previousPage+
",nextPage="+nextPage+
'}';
}
}
3.写SQL语句
要准备一个JDBC工具类,博主自己写了一个自己用的,不嫌弃可以直接拿,在博客中有一篇文章是有的,这里我就用自己工具类里的一个方法getTableComment做个例子
理一下思路,要拿到page页数和size一页数据数量,肯定是传进来的,那要创建刚写好的PageInfo类,赋值currentPage和pageSize,在SQL中要写上LIMIT?,?,利用JDBC中PreparedStatement接口类的setInt方法,将参数放进分页条件中,成功分页后将数据取出装入PageInfo的List中,再写一个count(*)SQL,不带分页的查出总记录数,装入totalNum里,这个时候PageInfo类中前面四个属性的值都有了,后面的三个属性会自行的去运算,再将PageInfo这个类返回给前端
publicstaticPageInfogetTableComment(DbConfigdbConfig,Integerpage,Integersize){
//连接数据库
Connectionconnection=getConnection(dbConfig);
List
//赋值currentPage和pageSize
PageInfopageInfo=PageInfo.startPage(page,size);
StringBuilderbuilder=newStringBuilder();
builder.append("SELECT")
.append("a.data_typejdbcType,")
.append("b.TABLE_NAME,b.TABLE_COMMENT")
.append("FROMinformation_schema.COLUMNSa")
.append("LEFTJOININFORMATION_SCHEMA.KEY_COLUMN_USAGEASpONa.table_schema=p.table_schema")
.append("LEFTJOININFORMATION_SCHEMA.TABLESbONa.table_schema=b.TABLE_SCHEMA")
.append("ANDb.TABLE_NAME=a.TABLE_NAME")
.append("ANDa.table_name=p.TABLE_NAMEANDa.COLUMN_NAME=p.COLUMN_NAME")
.append("ANDp.constraint_name='PRIMARY'")
.append("WHEREb.table_schema=").append("'"+dbConfig.getDataBase()+"'")
.append("ANDp.COLUMN_NAMEISNULL='true'").append("ORDERBYb.TABLE_NAME")
.append("LIMIT?,?");
try{
PreparedStatementstatement=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);
ResultSetresultSet=statement.executeQuery();
while(resultSet.next()){
StringjdbcType=resultSet.getString("jdbcType").toUpperCase();
if(jdbcType.equals("VARCHAR")){
jdbcType="String";
}else{
jdbcType="Integer";
}
Mapmap=newHashMap<>(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);
StringBuildercount=newStringBuilder();
count.append("SELECT")
.append("COUNT(*)")
.append("FROMinformation_schema.COLUMNSa")
.append("LEFTJOININFORMATION_SCHEMA.KEY_COLUMN_USAGEASpONa.table_schema=p.table_schema")
.append("LEFTJOININFORMATION_SCHEMA.TABLESbONa.table_schema=b.TABLE_SCHEMA")
.append("ANDb.TABLE_NAME=a.TABLE_NAME")
.append("ANDa.table_name=p.TABLE_NAMEANDa.COLUMN_NAME=p.COLUMN_NAME")
.append("ANDp.constraint_name='PRIMARY'")
.append("WHEREb.table_schema=").append("'"+dbConfig.getDataBase()+"'")
.append("ANDP.COLUMN_NAMEISNULL='true'");
statement=connection.prepareStatement(count.toString());
resultSet=statement.executeQuery();
if(resultSet.next()){
pageInfo.setTotalNum(resultSet.getInt(1));
}
logger.info("查询成功"+tableComment);
}catch(SQLExceptione){
e.printStackTrace();
}finally{
if(connection!=null){
closeConnection(connection);
connection=null;
}
}
returnpageInfo;
}
4.写一个接口做测试
新建一个Controller,写一个接口调用JDBC方法,将PageInfo类返回前端
@GetMapping("/tableComment")
publicPageInfotableComment(DbConfigdbConfig,
@RequestParam(defaultValue="1",required=false)Integerpage,
@RequestParam(defaultValue="10",required=false)Integersize){
PageInfopageInfo=DataBaseUtil.getTableComment(dbConfig,page,size);
returnpageInfo;
}
启动项目,调用一下这个接口,查看一下返回的数据对不对,这里我默认一页十条
好,数据返回的没问题,该有的数据都拿到了,手写一个SQL分页的大致思路就是这样。
看评论区大神
相关问题推荐
python中单行注释采用 #开头示例:#this is a comment二、批量、多行注释符号多行注释是用三引号,例如:输入''' '''或者 ,将要注释的代码插在中间三、Windows下的IDLE的注释快捷键是Alt+3,取消注释是Alt+4四、python中文注释方法...
apply
标准库Python拥有一个强大的标准库。Python语言的核心只包含数字、字符串、列表、字典、文件等常见类型和函数,而由Python标准库提供了系统管理、网络通信、文本处理、数据库接口、图形系统、XML处理等额外的功能。Python标准库的主要功能有:1.文本处理,包...
Python Lambda函数是没有任何名称的函数。它们也称为匿名或无名功能。 lambda一词不是名称,而是关键字。此关键字指定后面的函数是匿名的。现在您已经知道这些匿名函数指的是什么,让我们进一步了解一下如何编写这些Python Lambda函数。...
Linux操作系统是基于UNIX操作系统发展而来的一种克隆系统,它诞生于1991 年的 [Linux桌面] 10 月5 日(这是第一次正式向外公布的时间)。以后借助于Internet网络,并通过全世界各地计算机爱好者的共同努力,已成为今天世界上使用最多的一种UNIX 类操作系统,...
深度学习工程师就业路径目前,成为深度学习工程师有两条路径:一是通过春秋两季的校园招聘,另一种是借助社会招聘跨行业转型。前述文章曾经将深度学习工程师分为算法工程师、后端工程师和前端工程师。综合目前市面上各大公司招聘和咨询报告结果,目前工作3-5...
零基础学编程,用python入门是个不错的选择,虽然国内基本上还是以c语言作为入门开发语言,但在国外,已经有很多的学校使用python作为入门编程语言。此外,python在机器学习,人工智能领域也非常流行,算得上是算法工程师的标配编程语言。...
包是一个有层次的文件目录结构,它定义了由n个模块或n个子包组成的python应用程序执行环境。通俗一点:包是一个包含__init__.py 文件的目录,该目录下一定得有这个__init__.py文件和其它模块或子包。python库是参考其它编程语言的说法,就是指python中的完成...
1、len(mapping) 返回映射的长度(键-值对的个数)2、hash(obj) 返回obj的哈希值>>> myDict = {'name':'earth', 'port':'80'} >>> len(myDict) 2 >>> hash('name') 1...
常用内建属性说明触发方式__init__构造初始化函数创建实例后,赋值时使用,在__new__后__new__生成实例所需属性创建实例时__class__实例所在的类实例.__class____str__实例字符串表示(可读性)print(类实例),如没实现则使用repr结果__repr__实例字符串表示...
‘‘‘关键字:False:bool数据类型True:bool数据类型None:表示数据的内容为空and:逻辑运算符:与or:逻辑运算符:或not:逻辑运算符:非in:身份运算符,判断变量是否在序列中is :成员运算符,判断变量是否为某个类的实例del:删除变量或序列的值assert:列...
函数注释语法函数注释包括:参数注释:以冒号(:)标记返回值注释:以 -> 标记语法结构大体如下:1、def foo(a: expression, b: expression = 5) -> expression:2、 ...在伪语法中,参数看起来像:identifier [: expression] [= expression]。也就是说,参数...
OpenDoor变量的命名: year_month_day = 2020-7-24 这样写以后都会写很多单词,比较麻烦,可以用ymd代替,然后在第一行或者句尾添加注释说明 a, b, c =1,2, 3 这样的赋值在python中也是可以用的
Python 使用井号#作为单行注释的符号,语法格式为:# 注释内容从井号#开始,直到这行结束为止的所有内容都是注释。Python 解释器遇到#时,会忽略它后面的整行内容。说明多行代码的功能时一般将注释放在代码的上一行多行注释指的是一次性注释程序中多行的内容...
在IDLE中,常用 Alt + 3 给当前行进行注释 Alt + 4 取消当前行的注释在Pycharm中,常用 Ctrl + / 将所选部分快速注释,再按一次 Ctrl + / 可以将所选部分注释取消...