SpringBoot整合PageHelper插件实现分页查询


       左上方关注“Thinking曹勾选设为星标”

前言

Java Web项目开发过程中,查询接口是大量存在的,当调用查询接口将数据展示到前端页面时(H5、PC、移动端), 难免遇到查询接口数据量过大需要进行分页查询,分页查询的形式有多种多样,说不上简单,也算不上复杂;因为在MySQL中使用limit关键字就可以实现分页效果。

例如:

select oidnumber, 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)这样一行代码即可实现分页查询,非常简单。

  • MyBatis 分页插件 PageHelper支持如下分页方式:SpringBoot整合PageHelper插件实现分页查询

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(15);
   List<Order> orderList = orderService.selectAll();
   return RestResponse.success("查询成功", orderList);
}

二、整合PageHelper

  • 项目完整目录结构如下SpringBoot整合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<Timplements 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>(200null, 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(010);
        return RestResponse.success("查询成功", orderList);
    }

    /**
     * 查询多条订单数据
     * http://127.0.0.1:8082/openApi/order/selectAll
     * @return
     */

    @GetMapping("/selectAll")
    public RestResponse selectAll() {
        PageHelper.startPage(15);
        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.classargs);
    }
}

四、测试

测试之前,先看一下表里面的数据有哪些:

SpringBoot整合PageHelper插件实现分页查询
在这里插入图片描述

1. 新增订单

  • URL:http://127.0.0.1:8082/openApi/order/insertOrder
  • SpringBoot整合PageHelper插件实现分页查询
    在这里插入图片描述

2. 分页查询

  • URL:http://127.0.0.1:8082/openApi/order/selectAll
  • SpringBoot整合PageHelper插件实现分页查询
    在这里插入图片描述

五、源码

https://github.com/Thinkingcao/SpringBootLearning/tree/master/springboot-pageHelper

六、参考文档

https://github.com/pagehelper/Mybatis-PageHelper/blob/master/README_zh.md


如果觉得文章还不错,识别下图二维码,关注公众号「Thinking曹」,在通往Java架构的路上我想与你一同前行,共同进步SpringBoot整合PageHelper插件实现分页查询


SpringBoot整合PageHelper插件实现分页查询


        喜欢你就点个在看吧,点赞也可以来一下哦




原文始发于微信公众号(Thinking曹):SpringBoot整合PageHelper插件实现分页查询

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/26837.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!