左上方关注“Thinking曹”,勾选“设为星标”
前言
在Java Web
项目开发过程中,查询接口是大量存在的,当调用查询接口将数据展示到前端页面时(H5、PC、移动端), 难免遇到查询接口数据量过大需要进行分页查询,分页查询的形式有多种多样,说不上简单,也算不上复杂;因为在MySQL
中使用limit
关键字就可以实现分页效果。
例如:
select oid, number, pid, pname, pprice, uid, username
from t_order
limit #{offset}, #{limit}
MYSQL
实现分页查询主要通过offset
和 limit
这两个关键字段实现,需要在SQL
语句中加入limit
关键字,由于分页实现起来多种多样,最终实现效果都一样,所以这里给大家介绍一种非常简单好用的分页插件PageHelper
,在Java
代码中使用PageHelper
插件提供的方法就可以实现分页效果,相比在xml
中写分页的SQL语句
,PageHelper
在业务代码层面就可以简单实现,既然有现有的轮子,何必搬来用用呢?
一、PageHelper介绍
1. 什么是PageHelper
PageHelper
是一款好用的开源免费的Mybatis
第三方物理分页插件,只需要简单的几步配置集成到项目中,然后在业务代码Service中加入 PageHelper.startPage(pageNum, pageSize)
这样一行代码即可实现分页查询,非常简单。
2. 支持 MyBatis 3.1.0+
物理分页
该插件目前支持以下数据库的物理分页:
-
Oracle -
Mysql -
MariaDB -
SQLite -
Hsqldb -
PostgreSQL -
DB2 -
SqlServer(2005,2008) -
Informix -
H2 -
SqlServer2012 -
Derby -
Phoenix -
达梦数据库(dm) -
阿里云PPAS数据库 -
神通数据库 -
HerdDB 这里的数据库列表更新不及时,详情看这里:PageAutoDialect.java#L58
3. 如何使用PageHelper
PageHelper
提供了与SpringBoot
集成的Starter
,集成过程也是相对比较简单,集成完毕后,在Controller
层或者Service
层加入PageHelper.startPage(pageNum, pageSize);
即可实现分页效果,虽然Controller
层也可以,但是还是推荐在Service
业务层使用,这样比较规范。
例如:
/**
* 查询多条订单数据
* http://127.0.0.1:8082/openApi/order/selectAll
* @return
*/
@GetMapping("/selectAll")
public RestResponse selectAll() {
PageHelper.startPage(1, 5);
List<Order> orderList = orderService.selectAll();
return RestResponse.success("查询成功", orderList);
}
二、整合PageHelper
2.1 SpringBoot中使用PageHelper
-
在 pom.xml 中添加如下依赖:
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.3.0</version> <!-- version请查询官网最新发布版本 -->
</dependency>
具体的version
请在Maven仓
库中查询最新版本。
2.2 完整pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>springboot-pageHelper</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-pageHelper</name>
<description>SpringBoot整合PageHelper分页插件实现分页</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- web组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- lombok代码简化-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- mysql连接驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- fastjson解析器 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.56</version>
</dependency>
<!-- pagehelper分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<!-- processor -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
2.3 application.yml
#port端口配置
server:
port: 8082
#spring相关配置
spring:
#服务名
application:
name: product-service
#数据源配置,需要预先创建my-order数据库
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql:///my-order?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
username: root
password: 123456
# MyBatis配置
mybatis:
# 搜索指定包别名
typeAliasesPackage: com.example.**.entity
# 配置mapper的扫描,找到所有的mapper.xml映射文件
mapperLocations: classpath*:mapper/**/*Mapper.xml
# 加载全局的配置文件
configLocation: classpath:mybatis/mybatis-config.xml
# PageHelper分页插件
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
#log日志,配置SQL语句打印
logging:
level:
com.example.pagehelper.mapper: debug
org.springframework: warn
2.4 配置Mybatis策略
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="cacheEnabled" value="true" /> <!-- 全局映射器启用缓存 -->
<setting name="useGeneratedKeys" value="true" /> <!-- 允许 JDBC 支持自动生成主键 -->
<setting name="defaultExecutorType" value="REUSE" /> <!-- 配置默认的执行器 -->
<setting name="logImpl" value="SLF4J" /> <!-- 指定 MyBatis 所用日志的具体实现 -->
<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> 驼峰式命名 -->
</settings>
</configuration>
2.5 REST接口统一返回数据工具类
package com.example.pagehelper.result;
import java.io.Serializable;
/**
* REST接口统一返回数据工具类封装RestResponse
* @author: cao_wencao
* @param: <T>
*/
public class RestResponse<T> implements Serializable {
private static final long serialVersionUID = 3728877563912075885L;
private int code;
private String msg;
private T data;
public RestResponse(){
}
public RestResponse(int code, String message, T data) {
this.code = code;
this.setMsg(message);
this.data = data;
}
public RestResponse(int code, T data) {
this.code = code;
this.data = data;
}
public RestResponse(int code, String message) {
this.code = code;
this.setMsg(message);
}
/**
* 成功时-返回data
* @param <T>
* @return
*/
public static <T> RestResponse<T> success(T data){
return new RestResponse<T>(200, null, data);
}
/**
* 成功-不返回data
* @param <T>
* @return
*/
public static <T> RestResponse<T> success(String msg){
return new RestResponse<T>(200, msg);
}
/**
* 成功-返回data+msg
* @param <T>
* @return
*/
public static <T> RestResponse<T> success(String msg, T data){
return new RestResponse<T>(200, msg, data);
}
/**
* 失败
* @param <T>
* @return
*/
public static <T> RestResponse<T> fail(String msg){
return new RestResponse<T>(500, msg,null);
}
/**
* 失败-code
* @param <T>
* @return
*/
public static <T> RestResponse<T> fail(int code, String msg){
return new RestResponse<T>(code, msg,null);
}
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
public T getData() {
return data;
}
public void setCode(int code) {
this.code = code;
}
public void setMsg(String msg) {
this.msg = msg;
}
public void setData(T data) {
this.data = data;
}
@Override
public String toString() {
return "RestResponse{" + "code=" + code + ", msg='" + msg + ''' +", data=" + data +'}';
}
}
三、业务代码
3.1 Order实体类
package com.example.pagehelper.entity;
import java.io.Serializable;
/**
* (TOrder)实体类
*
* @author makejava
* @since 2020-11-12 14:30:20
*/
public class Order implements Serializable {
private static final long serialVersionUID = -19230576305027662L;
/**
* 订单ID
*/
private Integer oid;
/**
* 购买数量
*/
private Integer number;
/**
* 商品ID
*/
private Integer pid;
/**
* 商品名称
*/
private String pname;
/**
* 商品单价
*/
private Double pprice;
/**
* 用户ID
*/
private Integer uid;
/**
* 用户名
*/
private String username;
public Integer getOid() {
return oid;
}
public void setOid(Integer oid) {
this.oid = oid;
}
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
public Integer getPid() {
return pid;
}
public void setPid(Integer pid) {
this.pid = pid;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
public Double getPprice() {
return pprice;
}
public void setPprice(Double pprice) {
this.pprice = pprice;
}
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
3.2 OrderMapper.xml增删改查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.example.pagehelper.mapper.OrderMapper">
<resultMap id="BaseResultMap" type="com.example.pagehelper.entity.Order">
<!--@Table t_order-->
<result property="oid" column="oid" jdbcType="INTEGER"/>
<result property="number" column="number" jdbcType="INTEGER"/>
<result property="pid" column="pid" jdbcType="INTEGER"/>
<result property="pname" column="pname" jdbcType="VARCHAR"/>
<result property="pprice" column="pprice" jdbcType="NUMERIC"/>
<result property="uid" column="uid" jdbcType="INTEGER"/>
<result property="username" column="username" jdbcType="VARCHAR"/>
</resultMap>
<!--查询单个-->
<select id="queryById" resultMap="BaseResultMap">
select
oid, number, pid, pname, pprice, uid, username
from t_order
where oid = #{oid}
</select>
<!--查询指定行数据-->
<select id="queryAllByLimit" resultMap="BaseResultMap">
select
oid, number, pid, pname, pprice, uid, username
from t_order
limit #{offset}, #{limit}
</select>
<!--通过实体作为筛选条件查询-->
<select id="queryAll" resultMap="BaseResultMap">
select
oid, number, pid, pname, pprice, uid, username
from t_order
<where>
<if test="oid != null">
and oid = #{oid}
</if>
<if test="number != null">
and number = #{number}
</if>
<if test="pid != null">
and pid = #{pid}
</if>
<if test="pname != null and pname != ''">
and pname = #{pname}
</if>
<if test="pprice != null">
and pprice = #{pprice}
</if>
<if test="uid != null">
and uid = #{uid}
</if>
<if test="username != null and username != ''">
and username = #{username}
</if>
</where>
</select>
<!--新增所有列-->
<insert id="insert" keyProperty="oid" useGeneratedKeys="true">
insert into t_order(number, pid, pname, pprice, uid, username)
values (#{number}, #{pid}, #{pname}, #{pprice}, #{uid}, #{username})
</insert>
<!--通过主键修改数据-->
<update id="update">
update t_order
<set>
<if test="number != null">
number = #{number},
</if>
<if test="pid != null">
pid = #{pid},
</if>
<if test="pname != null and pname != ''">
pname = #{pname},
</if>
<if test="pprice != null">
pprice = #{pprice},
</if>
<if test="uid != null">
uid = #{uid},
</if>
<if test="username != null and username != ''">
username = #{username},
</if>
</set>
where oid = #{oid}
</update>
<!--通过主键删除-->
<delete id="deleteById">
delete from t_order where oid = #{oid}
</delete>
</mapper>
3.3 OrderMapper映射类
package com.example.pagehelper.mapper;
import com.example.pagehelper.entity.Order;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* (TOrder)表数据库访问层
*
* @author makejava
* @since 2020-11-12 14:30:22
*/
public interface OrderMapper {
/**
* 通过ID查询单条数据
*
* @param oid 主键
* @return 实例对象
*/
Order queryById(Integer oid);
/**
* 查询指定行数据
*
* @param offset 查询起始位置
* @param limit 查询条数
* @return 对象列表
*/
List<Order> queryAllByLimit(@Param("offset") int offset, @Param("limit") int limit);
/**
* 通过实体作为筛选条件查询
*
* @param order 实例对象
* @return 对象列表
*/
List<Order> queryAll(Order order);
/**
* 新增数据
*
* @param order 实例对象
* @return 影响行数
*/
int insert(Order order);
/**
* 修改数据
*
* @param order 实例对象
* @return 影响行数
*/
int update(Order order);
/**
* 通过主键删除数据
*
* @param oid 主键
* @return 影响行数
*/
int deleteById(Integer oid);
}
3.4 OrderService接口
package com.example.pagehelper.service;
import com.example.pagehelper.entity.Order;
import java.util.List;
/**
* (TOrder)表服务接口
*
* @author makejava
* @since 2020-11-12 14:30:23
*/
public interface OrderService {
/**
* 通过ID查询单条数据
*
* @param oid 主键
* @return 实例对象
*/
Order queryById(Integer oid);
/**
* 查询多条数据
*
* @param offset 查询起始位置
* @param limit 查询条数
* @return 对象列表
*/
List<Order> queryAllByLimit(int offset, int limit);
/**
* 查询所有数据
* @return
*/
List<Order> selectAll();
/**
* 新增数据
*
* @param order 实例对象
* @return 实例对象
*/
Order insert(Order order);
/**
* 修改数据
*
* @param order 实例对象
* @return 实例对象
*/
Order update(Order order);
/**
* 通过主键删除数据
*
* @param oid 主键
* @return 是否成功
*/
boolean deleteById(Integer oid);
}
3.5 OrderServiceImpl实现类
package com.example.pagehelper.service.impl;
import com.example.pagehelper.entity.Order;
import com.example.pagehelper.mapper.OrderMapper;
import com.example.pagehelper.service.OrderService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* (TOrder)表服务实现类
*
* @author makejava
* @since 2020-11-12 14:30:25
*/
@Service("orderService")
public class OrderServiceImpl implements OrderService {
@Resource
private OrderMapper orderMapper;
/**
* 通过ID查询单条数据
*
* @param oid 主键
* @return 实例对象
*/
@Override
public Order queryById(Integer oid) {
return this.orderMapper.queryById(oid);
}
/**
* 查询多条数据
*
* @param offset 查询起始位置
* @param limit 查询条数
* @return 对象列表
*/
@Override
public List<Order> queryAllByLimit(int offset, int limit) {
return this.orderMapper.queryAllByLimit(offset, limit);
}
/**
* 查询所有数据
* @return
*/
@Override
public List<Order> selectAll() {
return this.orderMapper.queryAll(null);
}
/**
* 新增数据
*
* @param order 实例对象
* @return 实例对象
*/
@Override
public Order insert(Order order) {
this.orderMapper.insert(order);
return order;
}
/**
* 修改数据
*
* @param order 实例对象
* @return 实例对象
*/
@Override
public Order update(Order order) {
this.orderMapper.update(order);
return this.queryById(order.getOid());
}
/**
* 通过主键删除数据
*
* @param oid 主键
* @return 是否成功
*/
@Override
public boolean deleteById(Integer oid) {
return this.orderMapper.deleteById(oid) > 0;
}
}
3.6 OrderController
重点注意在查询全部数据的接口里使用: PageHelper.startPage(1, 5)
即可完成我们需要的分页查询。
package com.example.pagehelper.controller;
import com.example.pagehelper.entity.Order;
import com.example.pagehelper.result.RestResponse;
import com.example.pagehelper.service.OrderService;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* (TOrder)表控制层
*
* @author makejava
* @since 2020-11-12 14:30:25
*/
@RestController
@RequestMapping("/openApi/order")
public class OrderController {
/**
* 服务对象
*/
@Autowired
private OrderService orderService;
/**
* 通过主键查询单条数据
* http://127.0.0.1:8082/openApi/order/findProductByPid/1
* @param id 主键
* @return 单条数据
*/
@GetMapping("/selectOne/{id}")
public RestResponse selectOne(@PathVariable("id") Integer id) {
Order order = this.orderService.queryById(id);
return RestResponse.success("查询成功", order);
}
/**
* 查询多条订单数据
* http://127.0.0.1:8082/openApi/order/selectAllOrder
* @return
*/
@GetMapping("/selectAllOrder")
public RestResponse selectAllOrder() {
List<Order> orderList = orderService.queryAllByLimit(0, 10);
return RestResponse.success("查询成功", orderList);
}
/**
* 查询多条订单数据
* http://127.0.0.1:8082/openApi/order/selectAll
* @return
*/
@GetMapping("/selectAll")
public RestResponse selectAll() {
PageHelper.startPage(1, 5);
List<Order> orderList = orderService.selectAll();
return RestResponse.success("查询成功", orderList);
}
/**
* 新增数据
* http://127.0.0.1:8082/openApi/order/insertOrder
* @param order 实例对象
* @return 实例对象
*/
@PostMapping("/insertOrder")
public RestResponse insert(@RequestBody Order order){
Order result = orderService.insert(order);
return RestResponse.success("新增成功", result);
}
/**
* 修改数据
* http://127.0.0.1:8082/openApi/order/updateOrder
* @param order 实例对象
* @return 实例对象
*/
@PostMapping("/updateOrder")
public RestResponse update(@RequestBody Order order){
Order result = orderService.update(order);
if (null== result){
return RestResponse.fail("修改失败");
}
return RestResponse.success("修改成功");
}
/**
* 通过主键删除数据
* http://127.0.0.1:8082/openApi/order/deleteOrderById/oid
* @param oid 主键
* @return 是否成功
*/
@PostMapping("/deleteOrderById/{oid}")
public RestResponse deleteById(@PathVariable("oid") Integer oid){
boolean flag = orderService.deleteById(oid);
if (!flag){
return RestResponse.fail("删除失败");
}
return RestResponse.success("删除成功");
}
}
3.7 启动类
package com.example.pagehelper;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 启动类
*/
@SpringBootApplication
@MapperScan(basePackages = {"com.example.pagehelper.**.mapper"})//扫描mybatis的所有**Mapper接口文件
public class PagehelperApplication {
public static void main(String[] args) {
SpringApplication.run(PagehelperApplication.class, args);
}
}
四、测试
测试之前,先看一下表里面的数据有哪些:

1. 新增订单
2. 分页查询
五、源码
https://github.com/Thinkingcao/SpringBootLearning/tree/master/springboot-pageHelper
六、参考文档
https://github.com/pagehelper/Mybatis-PageHelper/blob/master/README_zh.md
如果觉得文章还不错,识别下图二维码,关注公众号「Thinking曹」,在通往Java架构的路上我想与你一同前行,共同进步!
喜欢你就点个在看吧,点赞也可以来一下哦
原文始发于微信公众号(Thinking曹):SpringBoot整合PageHelper插件实现分页查询
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/26837.html