PageHelper 号称是史上最简单的分页插件,不需要写分页SQL,几乎不需要改变你未分页的代码,就可以实现分页功能
1、新增依赖
<!-- 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.3.0</version>
</dependency>
2、新增配置
application-dev.yml
pagehelper:
helper-dialect: mysql
reasonable: true
support-methods-arguments: true
params: count=countsql
参数解释:
helper-dialect:指定数据库,不指定的话会默认自动检测数据库类型
reasonable:是否启用分页合理化。如果启用,当pagenum<1时,会自动查询第一页的数据,当pagenum>pages时,自动查询最后一页数据;不启用的,以上两种情况都会返回空数据
support-methods-arguments: 支持分页参数写在mapper接口的方法中
2、修改控制器
/**
* 查询用户列表
* fetch("http://localhost:8080/users?pageNum=1&pageSize=10")
*
*
* @return
*/
@RequestMapping(value = "/users",method = RequestMethod.GET)
public CommonResult list(@RequestParam(value = "pageNum",required = false,defaultValue = "1") Integer pageNum ,
@RequestParam(value = "pageSize",required = false,defaultValue = "10") Integer pageSize
){
PageHelper.startPage(pageNum,pageSize);
List<User> userList = userService.findListByPage(pageNum,pageSize);
PageInfo<User> pageInfo =new PageInfo<>(userList,pageSize);
return CommonResult.success("分页查询用户数据成功",pageInfo);
}
3、查看效果
可以通过控制台日志,查看分页效果,通过分页组件PageHelper 分页之后,你自己的写的SQL语句就会被拦截改造成带有limit ? 样式的SQL
必须要配置日志,否则在控制台看不到SQL语句。
#新增日志
logging:
level:
org.lanqiao: debug
file:
name: ./logs/myapp.log
4、循环依赖问题
PageHelper引入后,启动可能会报循环依赖问题,网上说可能是PageHelper版本低的问题 , 从SpringBoot2.6版本开始,如果你的项目里还存在循环依赖,SpringBoot将拒绝启动!所以怎么解决呢 ?
spring.main.allow-circular-references: true 一种高版本妥协的办法 。
allow-circular-references
spring:
datasource:
url: jdbc:mysql://localhost:3306/world?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
main:
allow-circular-references: true
跨域配置
根据浏览器的同源策略规定:浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域。在前后端分离的模式下,前后端的域名是不一致的,此时就会发生跨域访问问题
package com.example.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@EnableWebMvc
public class CorsConfig implements WebMvcConfigurer {
/**
* Cors 全局配置
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").
allowedOrigins("*").allowCredentials(true).
allowedHeaders("*").allowedMethods("*").maxAge(3600);
}
}
SpringBoot使用PageHelper报错Relying upon circular references is discouraged and they are prohibited by
SpringBoot使用PageHelper报错Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.
在SpringBoot2.6.4版本做项目的时间,中间用到了PageHelper做分页处理,引入依赖之后启动项目的时间报了上面的错误
原因是SprinBoot与PageHelper的版本冲突导致的,使用SpringBoot2.6及以上版本,对应的PageHelper版本应该在1.4.1及以上。
以及这里使用的是pagehelper-spring-boot-starter,不要搞错了
<!--分页插件PageHelper-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.1</version>
</dependency>
这里还遇见了一个小bug,就是从网上粘贴依赖过来的时间,可能是特殊符号导致的,pom文件没有报错,但是启动项目的时间报Element ‘plugin’ cannot have character [children], because the type’s content type is element-only
这是因为特殊符号导致的,把特殊符号去掉之后就可以了
创建application.yml文件,并添加如下配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/pagehelperdemodat?useUnicode=true&characterEncoding=UTF-8
username: root
password: th123456
driver-class-name: com.mysql.cj.jdbc.Driver
thymeleaf:
prefix: classpath:/templates/
check-template-location: true
suffix: .html
mode: HTML
encoding: UTF-8
cache: false
mybatis:
mapper-locations: classpath*:mapper/*.xml
pagehelper:
helper-dialect: mysql
params: count=countSql
reasonable: true
support-methods-arguments: true
2、创建数据库
CREATE DATABASE pagehelperdemodat;
USE pagehelperdemodat;
CREATE TABLE users(
id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'id主键',
username VARCHAR(20) NOT NULL COMMENT '用户名',
PASSWORD VARCHAR(20) NOT NULL COMMENT'用户密码'
);
INSERT INTO users (username,PASSWORD) VALUES("小开心1","123456");
INSERT INTO users (username,PASSWORD) VALUES("小开心2","123456");
INSERT INTO users (username,PASSWORD) VALUES("小开心3","123456");
INSERT INTO users (username,PASSWORD) VALUES("小开心4","123456");
INSERT INTO users (username,PASSWORD) VALUES("小开心5","123456");
INSERT INTO users (username,PASSWORD) VALUES("小开心6","123456");
INSERT INTO users (username,PASSWORD) VALUES("小开心7","123456");
INSERT INTO users (username,PASSWORD) VALUES("小开心8","123456");
3、相关文件内容
User.java
package com.xiaokaixin.pagehelper.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* @Author xiaokaixin
* @Date 2021/9/11 18:01
* @Version 1.0
*/
@Data
@AllArgsConstructor
public class User {
private Integer id;
private String username;
private String password;
}
UserDao.java
package com.xiaokaixin.pagehelper.dao;
import com.xiaokaixin.pagehelper.entity.User;
import java.util.List;
/**
* @Author xiaokaixin
* @Date 2021/9/11 18:01
* @Version 1.0
*/
public interface UserDao {
// 查询所以用户
List<User> getAllUser();
}
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xiaokaixin.pagehelper.dao.UserDao">
<select id="getAllUser" resultType="com.xiaokaixin.pagehelper.entity.User">
select * from users
</select>
</mapper>
UserService
package com.xiaokaixin.pagehelper.service;
import com.xiaokaixin.pagehelper.entity.User;
import java.util.List;
/**
* @Author xiaokaixin
* @Date 2021/9/11 18:05
* @Version 1.0
*/
public interface UserService {
// 查询所以用户
List<User> getAllUser();
}
UserServiceImpl
package com.xiaokaixin.pagehelper.service.impl;
import com.xiaokaixin.pagehelper.dao.UserDao;
import com.xiaokaixin.pagehelper.entity.User;
import com.xiaokaixin.pagehelper.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Author xiaokaixin
* @Date 2021/9/11 18:05
* @Version 1.0
*/
@Service
public class UserServiceImpl implements UserService {
@Autowired
UserDao userDao;
@Override
public List<User> getAllUser() {
return userDao.getAllUser();
}
}
UserController
package com.xiaokaixin.pagehelper.controller;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xiaokaixin.pagehelper.entity.User;
import com.xiaokaixin.pagehelper.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
* @Author xiaokaixin
* @Date 2021/9/11 18:08
* @Version 1.0
*/
@Controller
public class UserController {
@Autowired
UserService userService;
@GetMapping("/")
public String findUser(Model model, @RequestParam(defaultValue = "1",value = "pageNum") Integer pageNum){
String orderBy = "id asc";
PageHelper.startPage(pageNum,5,orderBy);
List<User> list = userService.getAllUser();
PageInfo<User> pageInfo = new PageInfo<User>(list);
model.addAttribute("pageInfo",pageInfo);
return "index";
}
}
4、相关参数说明
//当前页
private int pageNum;
//每页的数量
private int pageSize;
//当前页的数量
private int size;
//当前页展示的数据的起始行
private int startRow;
//当前页展示的数据的结束行
private int endRow;
//总记录数--所需要进行分页的数据条数
private long total;
//总页数
private int pages;
//页面展示的结果集,比如说当前页要展示20条数据,则此list为这20条数据
private List<T> list;
//前一页页码
private int prePage;
//下一页页码
private int nextPage;
//是否为第一页,默认为false,是第一页则设置为true
private boolean isFirstPage ;
//是否为最后一页默认为false,是最后一页则设置为true
private boolean isLastPage ;
//是否有前一页,默认为false,有前一页则设置为true
private boolean hasPreviousPage ;
//是否有下一页,默认为false,有后一页则设置为true
private boolean hasNextPage ;
//导航页码数,所谓导航页码数,就是在页面进行展示的那些1.2.3.4...
//比如一共有分为两页数据的话,则将此值设置为2
private int navigatePages;
//所有导航页号,一共有两页的话则为[1,2]
private int[] navigatepageNums;
//导航条上的第一页页码值
private int navigateFirstPage;
//导航条上的最后一页页码值
private int navigateLastPage;
5、index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>分页测试</title>
</head>
<body>
<H3>查询所有用户</H3>
<table border="1">
<tr>
<th>id</th>
<th>name</th>
<th>password</th>
</tr>
<tr th:each="user:${pageInfo.list}">
<td th:text="${user.id}"></td>
<td th:text="${user.username}"></td>
<td th:text="${user.password}"></td>
</tr>
</table>
<p>当前 <span th:text="${pageInfo.pageNum}"></span> 页,总 <span th:text="${pageInfo.pages}"></span> 页,共 <span th:text="${pageInfo.total}"></span> 条记录</p>
<a th:href="@{/}">首页</a>
<a th:href="@{/(pageNum=${pageInfo.hasPreviousPage}?${pageInfo.prePage}:1)}">上一页</a>
<a th:href="@{/(pageNum=${pageInfo.hasNextPage}?${pageInfo.nextPage}:${pageInfo.pages})}">下一页</a>
<a th:href="@{/(pageNum=${pageInfo.pages})}">尾页</a>
</body>
</html>