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. flutter 一直卡在Running Gradle task 'assembleDebug'...运行不起来

    大概率只有一个原因:gradle下载不完整! 要想办法让他下载完整! 解决方法: 方法一:修改远程maven仓库地址(2024.7.9下列地址可用) repositories{ maven{ url' ...

  2. 安卓app产品:应用分析工具

    这是我独立开发的一款工具类安卓app(名称:应用分析工具),其主要功能是:(Solo 社区投稿) 1.基础信息查看 - 可查看app的包名.签名.权限.版本信息.AndroidManifest.xml ...

  3. KubeCube 用户管理与身份认证

    前言 KubeCube (https://kubecube.io) 是由网易数帆近期开源的一个轻量化的企业级容器平台,为企业提供 kubernetes 资源可视化管理以及统一的多集群多租户管理功能.K ...

  4. Mysql中where条件自动类型转换的坑

    我有张表,其主键id字段为varchar(5),内容是5位随机不重复字符串表的内容大概是这样的 id name s8bk2 admin 9f0ps username 在一个方法中我查询了这张表,代码大 ...

  5. MySQL ibdata1文件太大的解决办法

    在MySQL数据库中,如果不指定innodb_file_per_table=1参数单独保存每个表的数据,MySQL的数据都会存放在ibdata1文件里,时间久了这个文件就会变的非常大. 下面是参考网上 ...

  6. oeasy教您玩转 linux 010213 中文 fcitx

     我们来回顾一下 上一部分我们都讲了什么? 管道 ls | cowsay 管道的符号是| 管道的作用是连接 原来应该输出到屏幕的内容 通过管道流到了另一个命令做为参数 这次是否可以让cow说出一些中文 ...

  7. [oeasy]python0007-Guido的简历

    ​ 执行 esc 退回到正常模式 ​ 编辑 esc退出插入模式 准备底行命令模式运行当前py文件 保存执行 ​:w|!python3 %​ 保存并用 python3 解释当前程序(%) ​ 编辑 可以 ...

  8. c语言的编译与调试

    1. GCC/G++ gcc和g++是GNU Compiler Collection中的编译器,分别用于编译C和C++程序.它们的编译过程主要包括四个步骤:预处理(Pre-Processing).编译 ...

  9. 关于异步编程中的bind(this)

    异步编程中的.bind(this)方法解决了异步执行后this指针指向全局函数的问题,主要可以通过以下两个场景加以说明:(本文所用例子基于React场景:为简便起见,仅在第一个例子中展示完整HTML代 ...

  10. springMvc使用自定义View生成Excel表格

    1:通过自定义的View视图可以让请求直接到一个Excel表去. 2:自定义的视图必须继承  AbstractXlsView /AbstractXlsxView / AbstractXlsxStrea ...