更新时间:2020/11/6 17:36,更新完基本内容
本文现对目前常见的java分页工具进行一次总结与记录,主要是基于自己的主观来进行总结,本文会持续更新,不断地扩充
注意:本文仅为记录学习轨迹,如有侵权,联系删除
这个工具只要是使用过mybatis的人基本都听过,这个工具个人觉得只适用于mytatis这个持久层框架,而且在使用上有很多的坑。
新建springboot项目之后,引入对应的pom坐标依赖
<!-- mybatis-spring-boot-starter :整合-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<!--Druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
<!--log4j:日志框架,建议引入-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--pageHelper分页工具-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.10</version>
</dependency>
引进坐标依赖后需要进行yml文件的配置
#参考链接:https://www.cnblogs.com/hellokuangshen/p/12497041.html
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test1?userSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
password: 123
username: root
#切换为druid数据源
type: com.alibaba.druid.pool.DruidDataSource
#Spring Boot 默认是不注入这些属性值的,需要自己绑定
#druid 数据源专有配置
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
#配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
#如果允许时报错 java.lang.ClassNotFoundException: org.apache.log4j.Priority
#则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
#需要导入log4j依赖
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
# PageHelper分页插件
pagehelper:
helperDialect: mysql
reasonable: true #开启优化,如果开启优化,在分页页码结果没有数据的时候,会显示有数据的页码数据
supportMethodsArguments: true #是否支持接口参数来传递分页参数,默认false
pageSizeZero: false #pageSize=0 返回所有
params: count=countSql
mybatis:
mapper-locations: classpath*:mapper/**/*.xml
在使用之前必须要注意一件事,pageHelper只适用于mybatis,如果没有经过mybayis直接进行分页就会分页失败
@Override
public PageInfo<User> pageQuery() {
/** * 注意顺序不能乱,PageHelper.startPage设置完之后,下一句必须用mapper进行查询, * 也就是说userMapper.queryAll();这个语句必须放在PageHelper.startPage的下一句,不然分页失败 * 然后再 new PageInfo<>(list);返回分页结果 * * * 同时注意:mybatis的sql语句后面不能有";"结束符号 */
//设置分页参数,当前页数1,每页数据条数5条
PageHelper.startPage(1, 5);
//查询数据
List<User> list = userMapper.queryAll();
//分页查询
PageInfo<User> userPageInfo = new PageInfo<>(list);
return userPageInfo;
}
@Override
public PageInfo<User> queryQueryAllByUserDto(UserDto userDto) {
/** * 多条件的分页查询,查询条件用UserDto封装好 */
//分页参数默认值
Integer pageNum = 1;
Integer pageSize = 10;
if (userDto != null && userDto.getPageIndex() != null) {
pageNum = userDto.getPageIndex();
}
if (userDto != null && userDto.getPageSize() != null) {
pageSize = userDto.getPageSize();
}
//分页参数设置
PageHelper.startPage(pageNum,pageSize);
//多条件查询
List<User> userList = userMapper.queryAllByUserDto(userDto);
//分页
PageInfo<User> page = new PageInfo<>(userList);
return page;
}
同时注意查询的sql语句不能有分号,不然会分页失败
注意上面语句的使用顺序,不然会分页失败,同时注意sql语句的结尾不能有“;”符号
出现分页失败的情况有很多种,例如不是用的mybatis框架,语句的调用顺序不对或者用的mybatis但是sql语句后面用了分号结束sql等
public PageInfo<User> pageQuery() {
/** * 这种使用分页会失败,因为语句的调用顺序不对 */
//查询数据
List<User> list = userMapper.queryAll();
//设置分页参数,当前页数1,每页数据条数5条
PageHelper.startPage(1, 5);
//分页查询
PageInfo<User> userPageInfo = new PageInfo<>(list);
return userPageInfo;
}
分页失败,设置的分页参数失效
这个插件是mybats-plus用的一个分页插件,它在mybatis-plus里面有现应的集成,所以这个要结合mybatis-plus一起使用。
新建完springboot项目后,引入项目的坐标依赖
<!--Druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
<!--log4j-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
<!--mybatis-plus代码生成器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.0</version>
</dependency>
<!--mybatis-plus代码生成器默认模板-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.2</version>
</dependency>
<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.7</version>
</dependency>
mybatis-plus的分页配置可以参考mybatis-plus官网,这里给出我这边的配置
新建config包,创建配置类
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/** * @ClassName : MybatisPlusConfig * @Description : mybatis-plus配置分页插件 * @Author : CJH * @Date: 2020-11-05 17:14 */
@MapperScan("com.zsc.mapper")
@Configuration
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
// paginationInterceptor.setLimit(500);
// 开启 count 的 join 优化,只针对部分 left join
paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return paginationInterceptor;
}
}
然后是yml的文件配置
#参考链接:https://www.cnblogs.com/hellokuangshen/p/12497041.html
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test1?userSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
password: 123
username: root
#切换为druid数据源
type: com.alibaba.druid.pool.DruidDataSource
#Spring Boot 默认是不注入这些属性值的,需要自己绑定
#druid 数据源专有配置
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
#配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
#如果允许时报错 java.lang.ClassNotFoundException: org.apache.log4j.Priority
#则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
#需要导入log4j依赖
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
mybatis-plus:
mapper-locations: classpath*:/mapper/**/*.xml
它的使用在mybatis-plus中已经有集成了,使用的时候也必须按照它的说明来使用,按照官网,这个分页工具的使用要结合mybatis-plus的条件构造器来使用,下面给出两个例子,一个是简单的分页查询,一个是多条件分页查询
package com.zsc.service.impl;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zsc.dto.UserDto;
import com.zsc.entity.User;
import com.zsc.mapper.UserMapper;
import com.zsc.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/** * <p> * user 服务实现类 * </p> * * @author 最强菜鸟 * @since 2020-11-04 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Resource
private UserMapper userMapper;
@Override
public Page<User> pageQuery() {
//设置分页的当前页以及每页的数据条数
Page<User> userPage = new Page<>(1,5);
//通过条件构造器设置设置要查询的数据,条件构造器什么都不设置的情况下默认查询所有
QueryWrapper<User> userQueryWrapper= new QueryWrapper<>();
//分页查询用selectPage这个方法
Page<User> page = userMapper.selectPage(userPage, userQueryWrapper);
return page;
}
@Override
public Page<User> pageQueryByUserDto(UserDto userDto) {
//设置请求页数,默认1页5条数据
Page<User> userPage = new Page<>(1,5);
if (userDto.getPageIndex()!=null) {
userPage.setCurrent(userDto.getPageIndex());
}
if(userDto.getPageSize() != null){
userPage.setSize(userDto.getPageSize());
}
//条件构造器构造查询条件
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
//主要是name,age,password三个字段构成的多条件查询
if(!StringUtils.isEmpty(userDto.getName())){
userQueryWrapper.like("name",userDto.getName());
}
if(userDto.getAge() != null){
userQueryWrapper.like("age",userDto.getAge());
}
if(!StringUtils.isEmpty(userDto.getPassword())){
userQueryWrapper.like("password",userDto.getPassword());
}
//分页查询
Page<User> page = userMapper.selectPage(userPage, userQueryWrapper);
return page;
}
}
上面的两个分页工具分别对应mytatis和mybatis-plus框架,只有在对应的框架下使用才有分页效果,但有些时候我们只是写一个简单的增删改查,甚至都不是springboot项目和maven项目,就只是用最传统的jdbc连接进行数据库操作,这个时候就需要用到我们的自定义分页工具类了,下面的这个工具类是在网上找的一个个人觉得比较好的一个工具类,然后进行了相应的修改,得到一个最符合自己需求的一个分页工具类。
这里创建了一个普通的java项目,新建一个config包用来存放该分页工具类
package com.zsc.utils;
import java.util.ArrayList;
import java.util.List;
/** * @ClassName : PageUtil * @Description : 自定义分类工具 * @Author : CJH * @Date: 2020-11-06 10:36 */
public class PageUtil<T> {
/** * 要分页的list数据 */
private List<T> myList;
/** * 请求的页号,默认第1页 */
private int pageNum = 1;
/** * 每页条数,默认10条 */
private int pageSize = 10;
/** * 分页后的数据 */
private List<T> data;
/** * 分页后的总页数 */
private int pageCount;
/** * 总数据条数 */
private int recordCount;
public boolean isHasPrePage() {
return isHasPrePage;
}
public void setHasPrePage(boolean hasPrePage) {
isHasPrePage = hasPrePage;
}
public boolean isHasNextPage() {
return isHasNextPage;
}
public void setHasNextPage(boolean hasNextPage) {
isHasNextPage = hasNextPage;
}
/** * 上一页 */
private int prePageIndex;
/** * 下一页 */
private int nextPageIndex;
/** * 是否第一页 */
private boolean firstPage; // 是否第一页
/** * 是否最后一页 */
private boolean lastPage; // 是否最后一页
/** * 是否有上一页 * * @return */
private boolean isHasPrePage;
/** * 是否有下一页 * * @return */
private boolean isHasNextPage;
// /**
// * 返回分页结果集合
// *
// * @return
// */
// public PageUtil<T> getResult() {
// PageUtil<T> p = new PageUtil<>();
//
// //总数据条数
// p.setRecordCount(this.recordCount);
//
// //总页数
// p.setPageCount(this.pageCount);
//
//
// //每页的数据条数
// p.setPageSize(this.pageSize);
//
// //是否有上一页
// p.setHasPrePage(this.isHasPrePage);
//
// //是否有下一页
// p.setHasNextPage(this.isHasNextPage);
//
// //上一页页码
// p.setPrePageIndex(this.prePageIndex);
//
// //下一页页码
// p.setNextPageIndex(this.nextPageIndex);
//
// //分页数据
// p.setData((ArrayList<T>) this.data);
//
// //请求的页数
// p.setPageNum(this.pageNum);
//
// return p;
// }
/** * 设置请求的页数 * * @param pageNum */
public void setPageNum(int pageNum) {
// 每当页数改变,都会调用这个函数,筛选代码可以写在这里
this.pageNum = pageNum;
// 上一页,下一页确定
prePageIndex = pageNum - 1;
nextPageIndex = pageNum + 1;
// 是否第一页,最后一页
if (pageNum == 1) {
firstPage = true;
} else {
firstPage = false;
}
if (pageNum == pageCount) {
lastPage = true;
} else {
lastPage = false;
}
// 筛选工作
data = new ArrayList<T>();
for (int i = (pageNum - 1) * pageSize; i < pageNum
* pageSize
&& i < recordCount; i++) {
data.add(myList.get(i));
}
}
/** * 返回请求页数 * * @return */
public int getPageNum() {
return pageNum;
}
/** * 返回要分页的list数据 * * @return */
public List<T> getMyList() {
return myList;
}
@Override
public String toString() {
return "{" +
"recordCount=" + recordCount+
", pageCount=" + pageCount +
", pageNum=" + pageNum +
", pageSize=" + pageSize +
", isPrePage=" + isHasPrePage +
", isNextPage=" + isHasNextPage +
", prePageIndex=" + prePageIndex +
", nextPageIndex=" + nextPageIndex +
", data=" + data +
'}';
}
/** * 设置要分页的数据 * * @param myList */
public PageUtil<T> setMyList(List<T> myList) {
this.myList = myList;
// 计算条数
recordCount = myList.size();
// 计算页数
if (recordCount % pageSize == 0) {
pageCount = recordCount / pageSize;
} else {
pageCount = recordCount / pageSize + 1;
}
//计算是否有上一页
if(pageNum == 1){
isHasPrePage = false;
}else{
isHasPrePage = true;
}
//计算是否有下一页
if(pageNum == pageCount){
isHasNextPage = false;
}else {
isHasNextPage = true;
}
// 筛选工作
data = new ArrayList<T>();
for (int i = (pageNum - 1) * pageSize; i < pageNum
* pageSize
&& i < recordCount; i++) {
data.add(myList.get(i));
}
return this;
}
/** * 返回每页请求的数据条数 * * @return */
public int getPageSize() {
return pageSize;
}
/** * 设置每页的请求条数 * * @param pageSize */
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
/** * 返回分页后的数据 * * @return */
public List<T> getData() {
return data;
}
public void setData(ArrayList<T> data) {
this.data = data;
}
public int getPageCount() {
return pageCount;
}
public void setPageCount(int pageCount) {
this.pageCount = pageCount;
}
public int getRecordCount() {
return recordCount;
}
public void setRecordCount(int recordCount) {
this.recordCount = recordCount;
}
public int getNextPageIndex() {
return nextPageIndex;
}
public void setNextPageIndex(int nextPageIndex) {
this.nextPageIndex = nextPageIndex;
}
public int getPrePageIndex() {
return prePageIndex;
}
public void setPrePageIndex(int prePageIndex) {
this.prePageIndex = prePageIndex;
}
public boolean isFirstPage() {
return firstPage;
}
public void setFirstPage(boolean firstPage) {
this.firstPage = firstPage;
}
public boolean isLastPage() {
return lastPage;
}
public void setLastPage(boolean lastPage) {
this.lastPage = lastPage;
}
}
下面给出两个例子,其中User类是自定义的类
package com.zsc.service;
import com.zsc.entity.User;
import com.zsc.utils.PageUtil;
import java.util.ArrayList;
import java.util.List;
/** * @ClassName : PageService * @Description : * @Author : CJH * @Date: 2020-11-06 13:05 */
public class PageService {
static List<String> getListString(){
ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < 36; i++) {
list.add("hello"+i);
}
return list;
}
static List<User> getListUser(){
ArrayList<User> list = new ArrayList<User>();
for (int i = 0; i < 36; i++) {
User user = new User(i,"zs"+i,10+i,"男");
list.add(user);
}
return list;
}
public static void main(String[] args) {
//例子1
List<String> listString = getListString();
PageUtil<String> pageUtil = new PageUtil<>();
//请求页数
pageUtil.setPageNum(1);
//每页是数据条数
pageUtil.setPageSize(4);
//将要分页的数据传入,得到返回的分页结果
PageUtil<String> list = pageUtil.setMyList(listString);
System.out.println("list = " + list);
//例子2
List<User> listUser = getListUser();
PageUtil<User> userPageUtil = new PageUtil<>();
userPageUtil.setPageNum(1);
userPageUtil.setPageSize(10);
PageUtil<User> userPageUtil1 = userPageUtil.setMyList(listUser);
System.out.println("userPageUtil1 = " + userPageUtil1);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/186286.html原文链接:https://javaforall.cn