精通SpringBoot--分页查询功能的实现

2022-10-19,,,

本文将介绍如何实现分页查询功能,推荐使用github的pagehelper插件实现(事实上大家基本都是这么干的),但本文的实现方式和大多数不同,废话少说,现在就带着大家看看区别在哪里。
先看pom.xml依赖:相当简单的mybatis-spring依赖+mysql+pagehelper+fastjson

 <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.44</version>
</dependency> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--pageHelper-->
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency> </dependencies>

application.yml配置

spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/javashop
driver-class-name: com.mysql.jdbc.Driver
http:
encoding:
charset: utf-8
enabled: true
mybatis:
type-aliases-package: com.developlee.mybatispagehelper.domain
mapper-locations: classpath:/mapper/*.xml
pagehelper:
helper-dialect: mysql
reasonable: true
support-methods-arguments: true
params: count=countSql

撸代码了,先从controller开始,开干!随便写个简单点的

@RestController
public class UserController { @Autowired
private UserServiceImpl userService; @PostMapping("/queryList")
public ResponseEntity queryList(@RequestBody UserEntity userEntity) {
List<UserEntity> userEntities = userService.findUserList(userEntity);
return new ResponseEntity( new PageEntity<>(userEntities), HttpStatus.OK);
}
}

仔细看,是不是发现并_没有PageHelper.startPage(int num, int size)_这句话?当然没有最好,每次分页查询都写这句,是不是很烦。。。还有_PageEntity是个啥_?不要着急,让我们慢慢揭开面纱。
servicedao还有userMapper.xml没什么好讲的,就是为了userService.findList能正常查出个list数组来。代码懒得贴了,占位置,相信大家也都会。
Next,就是重点了, 看看UserEntity实体做了什么。

public class UserEntity extends BaseEntity {
private Long id;
private String username;
private String password;
private String mobile; public Long getId() {
return id;
} public void setId(Long id) {
this.id = id;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public String getMobile() {
return mobile;
} public void setMobile(String mobile) {
this.mobile = mobile;
}
}

OMG,继承了一个BaseEntity,那BaseEntity有哪些内容呢,其实相当easy,就是些我们要传的page参数.

public abstract class BaseEntity {

    //分页大小
private Integer pageSize;
//分页开始
private Integer pageNum; private Integer total; //排序类型DESC or AES
private String sort; private String orderBy; @JSONField(serialize = false)
public Integer getPageSize() {
return pageSize;
} public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
} @JSONField(serialize = false)
public Integer getPageNum() {
return pageNum;
} public void setPageNum(Integer pageNum) {
this.pageNum = pageNum;
} @JSONField(serialize = false)
public Integer getTotal() {
return total;
} public void setTotal(Integer total) {
this.total = total;
} @JSONField(serialize = false)
public String getOrderBy() {
return orderBy;
} public void setOrderBy(String orderBy) {
this.orderBy = orderBy;
} @JSONField(serialize = false)
public String getSort() {
return sort;
} public void setSort(String sort) {
this.sort = sort;
}
}

注意哦,这些个参数返回给前端时都不需要给的哦。所以用了@JSONField(serialize=false) 来搞定。

讲到这,似乎没什么神奇之处,呃呃呃,是的,这些都是为了传参数。看看PageEntity ,这才是今天的主角儿~~~


import com.github.pagehelper.Page; import java.io.Serializable;
import java.util.Collection;
import java.util.List; /**
* 对Page<E>结果进行包装
* <p/>
* 新增分页的多项属性
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public class PageEntity<T> implements Serializable {
private static final long serialVersionUID = 1L;
//当前页
private int currentPage;
//每页的数量
private int pageSize;
//总记录数
private long total;
//总页数
private int pages;
//结果集
private List<T> list;
//是否为第一页
private boolean isFirstPage = false;
//是否为最后一页
private boolean isLastPage = false; public PageEntity() {
} /**
* 包装Page对象
*
* @param list
*/
public PageEntity(List<T> list) {
if (list instanceof Page) {
Page page = (Page) list;
this.currentPage = page.getPageNum();
this.pageSize = page.getPageSize(); this.pages = page.getPages();
this.list = page;
this.total = page.getTotal();
} else if (list instanceof Collection) {
this.currentPage = 1;
this.pageSize = list.size();
this.pages = 1;
this.list = list;
this.total = list.size();
}
if (list instanceof Collection) {
//判断页面边界
judgePageBoudary();
}
} /**
* 判定页面边界
*/
private void judgePageBoudary() {
isFirstPage = currentPage == 1;
isLastPage = currentPage == pages;
} public int getCurrentPage() {
return currentPage;
} public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
} public int getPageSize() {
return pageSize;
} public void setPageSize(int pageSize) {
this.pageSize = pageSize;
} public long getTotal() {
return total;
} public void setTotal(long total) {
this.total = total;
} public int getPages() {
return pages;
} public void setPages(int pages) {
this.pages = pages;
} public List<T> getList() {
return list;
} public void setList(List<T> List) {
this.list = List;
} public boolean isIsFirstPage() {
return isFirstPage;
} public void setIsFirstPage(boolean isFirstPage) {
this.isFirstPage = isFirstPage;
} public boolean isIsLastPage() {
return isLastPage;
} public void setIsLastPage(boolean isLastPage) {
this.isLastPage = isLastPage;
} @Override
public String toString() {
final StringBuffer sb = new StringBuffer("PageEntity{");
sb.append("currentPage=").append(currentPage);
sb.append(", pageSize=").append(pageSize);
sb.append(", total=").append(total);
sb.append(", pages=").append(pages);
sb.append(", list=").append(list);
sb.append(", isFirstPage=").append(isFirstPage);
sb.append(", isLastPage=").append(isLastPage);
sb.append(", navigatepageNums=");
sb.append('}');
return sb.toString();
}
}

Watch Out!构造函数PageEntiy(List list) 这里头对pageHelper的Page进行了进一步的完善。看看pageHelper的Page类

public class Page<E> extends ArrayList<E> implements Closeable {
private static final long serialVersionUID = 1L;
private int pageNum;
private int pageSize;
private int startRow;
private int endRow;
private long total;
private int pages;
private boolean count;
private Boolean reasonable;
private Boolean pageSizeZero;
private String countColumn;
private String orderBy;
private boolean orderByOnly;
//多余不贴了。。。
}

光说不练空把式,postman 工具测试一波看看。

我擦,什么情况,说好的不要这些page参数呢,为什么list里头还是有?嗯哼,SpringBoot默认的消息格式转换,也就是messgeConvert,很明显,我们使用了fastjson ,自然MessageConvert也要改造成用fastjson的。
springboot2.0中实现WebMvcConfiguer接口,然后覆盖该方法

/**
* @author Lensen
* @desc
* @since 2018/8/25 21:45
*/
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
//消息格式转换
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//1.需要定义一个convert转换消息的对象;
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
//2.添加fastJson的配置信息,比如:是否要格式化返回的json数据;
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat,
SerializerFeature.WriteMapNullValue,
SerializerFeature.WriteNullStringAsEmpty,
SerializerFeature.DisableCircularReferenceDetect,
SerializerFeature.WriteNullListAsEmpty,
SerializerFeature.WriteDateUseDateFormat);
//3处理中文乱码问题
List<MediaType> fastMediaTypes = new ArrayList<>();
fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
//4.在convert中添加配置信息.
fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);
fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
//5.将convert添加到converters当中.
converters.add(fastJsonHttpMessageConverter);
}
}

@EnableWebMvc别忘了,忘了就不会生效的(我一开始就**忘记了)
在测试,走起

完美~ 代码里我根本不用写PageHelper.startPage(int pageNum, int pageSize)这句话,直接专注自己的逻辑。

精通SpringBoot--分页查询功能的实现的相关教程结束。

《精通SpringBoot--分页查询功能的实现.doc》

下载本文的Word格式文档,以方便收藏与打印。