PageHelper 是一个非常流行的 MyBatis 分页插件,主要用于简化分页查询的实现。使用 PageHelper 可以在执行数据库查询时,自动处理分页参数,从而避免手动编写繁琐的分页逻辑。

今天就来学习一下PageHelper的相关知识和用法!

PageHelper

主要功能

  1. 分页查询:通过 PageHelper.startPage() 方法指定页码和每页的大小,之后执行的查询会自动分页。
  2. 排序功能:支持排序功能,分页查询时可以通过指定排序字段和排序方式来获得排序后的结果集。
  3. 简化分页逻辑:无需手动修改 SQL 语句,PageHelper 会自动为查询 SQL 添加分页逻辑,大大简化代码。
  4. 多数据库支持PageHelper 支持多种主流的数据库,如 MySQL、Oracle、PostgreSQL 等。

使用步骤

  1. 引入依赖

    pom.xml 中添加 PageHelper 依赖:

    <dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.2.0</version>
    </dependency>
  2. 配置拦截器

    在 MyBatis 配置文件或配置类中,注册 PageHelper 拦截器:

    @Bean
    public PageInterceptor pageHelper() {
    PageInterceptor pageInterceptor = new PageInterceptor();
    Properties properties = new Properties();
    properties.setProperty("helperDialect", "mysql"); // 数据库类型
    pageInterceptor.setProperties(properties);
    return pageInterceptor;
    }
  3. 分页查询使用示例

    在代码中使用 PageHelper.startPage() 方法来指定分页参数,后续的查询会自动带上分页信息:

    @Service
    public class UserService { @Autowired
    private UserMapper userMapper; public List<User> getUsers(int pageNum, int pageSize) {
    // 开启分页
    PageHelper.startPage(pageNum, pageSize);
    // 查询结果
    return userMapper.getAllUsers();
    }
    }
  4. 返回分页结果

    使用 PageInfo 来包装分页结果,包含分页信息和查询结果:

    List<User> userList = userMapper.getAllUsers();
    PageInfo<User> pageInfo = new PageInfo<>(userList);
    System.out.println(pageInfo.getTotal()); // 总记录数
    System.out.println(pageInfo.getList()); // 当前页的记录列表

核心方法

  • PageHelper.startPage(int pageNum, int pageSize):指定页码和每页大小,之后的查询会自动分页。
  • PageHelper.orderBy(String orderBy):设置排序规则,如 "id desc",按 id 倒序排列。
  • PageInfo<T>:封装分页结果信息,包含总记录数、总页数、当前页的记录等。

总结

PageHelper 提供了一种简洁的方式来实现 MyBatis 的分页查询,自动处理分页逻辑并简化代码,同时支持多种数据库和排序功能,是 MyBatis 用户进行分页查询的一个常用工具。

SpringBoot中的PageHelper

pagehelper-spring-boot-starterPageHelper 的 Spring Boot 自动配置版本,能够更简便地集成 PageHelper,特别是在 Spring Boot 项目中。相比于手动配置 PageHelper,使用 pagehelper-spring-boot-starter 可以进一步简化配置和使用过程。

使用步骤

  1. 引入依赖

    在 Spring Boot 项目的 pom.xml 中添加 pagehelper-spring-boot-starter 依赖:

    <dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.4.6</version>
    </dependency>
  2. 自动配置

    引入 pagehelper-spring-boot-starter 后,不需要手动配置 PageHelper 拦截器,Spring Boot 会自动配置好分页插件。

  3. 在查询方法中使用

    使用 PageHelper.startPage() 方法指定分页参数,在执行查询时,结果会自动分页。

    示例代码:

    @Service
    public class UserService { @Autowired
    private UserMapper userMapper; // 分页获取用户列表
    public PageInfo<User> getUsers(int pageNum, int pageSize) {
    // 设置分页参数
    PageHelper.startPage(pageNum, pageSize);
    // 执行查询,得到结果集
    List<User> users = userMapper.getAllUsers();
    // 使用PageInfo来封装分页信息
    return new PageInfo<>(users);
    }
    }
  4. 返回分页结果

    PageInfoPageHelper 提供的工具类,用于封装分页信息,如总记录数、总页数、当前页数据等。可以通过 PageInfo 对象获取到这些信息:

    PageInfo<User> pageInfo = userService.getUsers(1, 10);
    System.out.println(pageInfo.getTotal()); // 获取总记录数
    System.out.println(pageInfo.getPages()); // 获取总页数
    System.out.println(pageInfo.getList()); // 获取当前页的数据
  5. 自定义配置(可选)

    你可以通过 Spring Boot 的 application.propertiesapplication.yml 文件自定义 PageHelper 的相关配置,比如数据库方言、合理化配置、分页方式等。

    application.yml 中添加自定义配置:

    pagehelper:
    helper-dialect: mysql # 数据库方言
    reasonable: true # 启用合理化,避免页码超出范围
    support-methods-arguments: true # 支持分页参数作为方法参数
    params: count=countSql # 分页查询时统计总数的SQL

    或者在 application.properties 中:

    pagehelper.helperDialect=mysql
    pagehelper.reasonable=true
    pagehelper.supportMethodsArguments=true
    pagehelper.params=count=countSql

复杂度

  • 时间复杂度:分页查询的时间复杂度依赖于数据库查询操作。一般情况下,查询复杂度为 $O(n)$,加上分页条件,实际执行时可能会根据数据库的索引和优化机制有所不同。
  • 空间复杂度:空间复杂度取决于分页结果和数据的存储形式,一般为 $O(k)$,其中 k 是每页返回的数据量。

总结

通过 pagehelper-spring-boot-starter,在 Spring Boot 项目中可以轻松集成 PageHelper,自动完成分页查询的配置和操作,简化了开发者的代码量。同时还支持自定义配置,能够灵活应对各种分页需求。

实际运用

在我正在写的仿12306项目中很多地方都会用到pagehelper,所以一般会封装分页查询的入参和出参类,就以查询乘车人为例:

PageReq

封装PageReq作为分页查询入参类的父类,为分页查询提供pageNumpageSize

PageReq
public class PageReq {

    @NotNull(message = "【页码】不能为空")
private Integer start; @NotNull(message = "【每页条数】不能为空")
@Max(value = 100, message = "【每页条数】不能超过100")
private Integer count; public @NotNull(message = "【页码】不能为空") Integer getStart() {
return start;
} public void setStart(@NotNull(message = "【页码】不能为空") Integer start) {
this.start = start;
} public @NotNull(message = "【每页条数】不能为空") @Max(value = 100, message = "【每页条数】不能超过100") Integer getCount() {
return count;
} public void setCount(@NotNull(message = "【每页条数】不能为空") @Max(value = 100, message = "【每页条数】不能超过100") Integer count) {
this.count = count;
} @Override
public String toString() {
final StringBuffer sb = new StringBuffer("pageReq{");
sb.append("start=").append(start);
sb.append(", count=").append(count);
sb.append('}');
return sb.toString();
}
}

查询乘车人服务的入参类继承PageReq类;

PassengerQueryReq
public class PassengerQueryReq extends PageReq {

    private Long memberId;

    private String idCard;

    public Long getMemberId() {
return memberId;
} public void setMemberId(Long memberId) {
this.memberId = memberId;
} public String getIdCard() {
return idCard;
} public void setIdCard(String idCard) {
this.idCard = idCard;
} @Override
public String toString() {
final StringBuffer sb = new StringBuffer("PassengerQueryReq{");
sb.append("memberId=").append(memberId);
sb.append(", idCard='").append(idCard).append('\'');
sb.append('}');
return sb.toString();
}
}

在查询乘车人服务中使用PageReq提供的pageNumpageSize调用PageHelper

PassengerService
@Service
public class PassengerService { @Resource
private PassengerMapper passengerMapper; public List<PassengerQueryResp> queryList (PassengerQueryReq req) {
PassengerExample passengerExample = new PassengerExample();
PassengerExample.Criteria criteria = passengerExample.createCriteria();
if (ObjectUtil.isNotNull(req.getMemberId())) {
criteria.andMemberIdEqualTo(req.getMemberId());
}
PageHelper.startPage(req.getStart(), req.getCount());
List<Passenger> passengerList = passengerMapper.selectByExample(passengerExample);
return BeanUtil.copyToList(passengerList, PassengerQueryResp.class);
} public void update(PassengerSaveReq req) {
DateTime now = DateTime.now();
Passenger passenger = BeanUtil.copyProperties(req, Passenger.class);
passenger.setMemberId(LoginMemberContext.getId());
passenger.setModifiedTime(now); PassengerExample passengerExample = new PassengerExample();
passengerExample.createCriteria().
andMemberIdEqualTo(passenger.getMemberId()).
andIdCardEqualTo(passenger.getIdCard()); passengerMapper.updateByExampleSelective(passenger, passengerExample);
}
}

PageResp

封装PageResp作为response类,返回查询总数、分页总数和查询列表;

PageResp
public class PageResp<T> implements Serializable {

    private static final Long serialVersionUID = 1L;

    /**
* 查询结果总数
*/
private Long total; /**
* 查询结果列表
*/
private List<T> list; public List<T> getList() {
return list;
} public void setList(List<T> list) {
this.list = list;
} public Long getTotal() {
return total;
} public void setTotal(Long total) {
this.total = total;
} @Override
public String toString() {
final StringBuffer sb = new StringBuffer("PageResp{");
sb.append("total=").append(total);
sb.append(", list=").append(list);
sb.append('}');
return sb.toString();
}
}

查询乘车人服务中使用PageInfo获取分页查询的结果总数和分页数,返回PageResp

PassengerService
@Service
public class PassengerService { private static final Logger LOG = LoggerFactory.getLogger(PassengerService.class); @Resource
private PassengerMapper passengerMapper; public PageResp<PassengerQueryResp> queryList (PassengerQueryReq req) {
PassengerExample passengerExample = new PassengerExample();
PassengerExample.Criteria criteria = passengerExample.createCriteria();
if (ObjectUtil.isNotNull(req.getMemberId())) {
criteria.andMemberIdEqualTo(req.getMemberId());
} // mybatis PageHelper分页查询
LOG.info("查询页码:{}", req.getStart());
LOG.info("每页条数:{}", req.getCount());
PageHelper.startPage(req.getStart(), req.getCount());
List<Passenger> passengerList = passengerMapper.selectByExample(passengerExample);
// 把passengerList转为passengerQueryRespList
List<PassengerQueryResp> passengerQueryResp = BeanUtil.copyToList(passengerList, PassengerQueryResp.class); // pageHelper获取分页查询总条数,将分页查询结果(条数+list)封装到pageResp
PageInfo<Passenger> pageInfo = new PageInfo<>(passengerList);
LOG.info("总条数:{}", pageInfo.getTotal());
LOG.info("总页数:{}", pageInfo.getPages());
PageResp<PassengerQueryResp> pageResp = new PageResp<>();
pageResp.setList(passengerQueryResp);
pageResp.setTotal(pageInfo.getTotal());
return pageResp;
}
}

PageHeper的更多相关文章

  1. Mybaits-plus实战(二)

    1. Mybaits-plus实战(二) 1.1. mybatis-plus插件 1.1.1. 用法 先举个例子介绍用法,如下:直接作为Bean注入,一般来讲插件太多印象性能,所以大部分插件都只在测试 ...

  2. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_2-5.开源工具的优缺点选择和抽象方法的建议

    笔记 5.开源工具的优缺点选择和抽象方法的建议     简介:讲解开源工具的好处和弊端,如pageHeper分页拦截器,tk自动生成工具,抽象方法的利弊等 1.开源工具             好处: ...

  3. Mybatis-plus 思维导图,让 Mybatis-plus 不再难懂

    摘要: Mybatis-Plus(简称MP)是一个Mybatis的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发.提高效率而生. mybatis-plus与mybatis myba ...

  4. mybatis-plus思维导图,让mybatis-plus不再难懂

    mybatis-plus与mybatis mybatis Mybatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置 ...

随机推荐

  1. yb课堂之自定义异常和配置 《五》

    开发自定义异常和配置 自定义异常 继承RuntimeException 开发异常处理器ExceptionHandle YBException.java package net.ybclass.onli ...

  2. win10打不出中文的修复方法!

    说明 在Win10系统中,默认自带了中文输入法,使用起来非常的方便,但有时win10系统中自带的输入法会打不出中文的情况,该怎么办呢?遇到这样的问题,我们可以参考下本文中的方法来修复. 步骤: cmd ...

  3. 美团VS饿了么,到底谁更胜一筹?

    最近啊,收到一个粉丝的投稿,我发现他在美团和饿了么都去面试过. 这俩企业大家应该都经常用吧,咱点外卖的时候,我有时候就琢磨,到底他俩谁更厉害点. 今天咱们就瞅瞅,在面试这块儿谁更难一些. (目前都只有 ...

  4. 计算复杂性学习笔记(TCS笔记)

    感觉最近太摆了,每天很空虚,不愿意搞应试那一套,还是得学点东西.还是准备一边学tcs一边搞搞oi好打icpc,搞这个纯属兴趣,也是填个坑.最近进了一个初中生建的数学交流群,感觉群里初中生也很厉害,开始 ...

  5. pytest + allure2.x 踩坑-报告无数据

    我按照网上的教程,在用pytest生成完allure可以使用的json数据之后,然后再用allure生成报告,打开,发现我生成的报告中没有数据显示. 1.首先我用pytest生成数据是没有问题的 2. ...

  6. Superviso可视化监控进程

    如果您需要同时运行多个 ThinkPHP 命令,可以在 Supervisor 中为每个命令创建一个单独的程序段.以下是示例配置,其中包含两个 ThinkPHP 命令:command1.php 和 co ...

  7. 如何自动实现本地AD中禁用的用户从地址列表中隐藏掉?

    我的博客园:https://www.cnblogs.com/CQman/ 如何自动实现本地AD中禁用的用户从地址列表中隐藏掉? 需求信息: 用户本地AD用户通过ADConnect同步到O365,用户想 ...

  8. 【Vue】Re08 模块化

    一.JS的演变: 1.简单的页面控制,改变HTML标签和CSS样式 2.AJAX异步请求,控制前后数据传输问题 3.更强大的功能,几乎依赖JS实现 工程管理问题: 简单页面只需要在页面嵌入script ...

  9. 感慨!美国人的大学课程搞的确实蛮好的,不是那种刻板读书的感觉 —— 课程:SERVICE-ORIENTED COMPUTING AND SYSTEM INTEGRATION: SOFTWARE, IOT, BIG DATA, AND AI AS SERVICES

    无意间看到了一个美国人的课程,使用的教材:<SERVICE-ORIENTED COMPUTING AND SYSTEM INTEGRATION: SOFTWARE, IOT, BIG DATA, ...

  10. Trump 黑马 or 搅局者? 讲座视频分享

    沈逸-特朗普能走多远   https://www.bilibili.com/video/BV1r7411t7VS/?spm_id_from=333.788.videocard.2     国际关系 对 ...