pagehelper分页查询列表怎么写
时间: 2025-07-19 10:36:21 浏览: 1
<think>我们正在讨论如何使用PageHelper实现分页查询列表。根据引用内容,我们可以总结出以下关键步骤:
1. 在查询前调用`PageHelper.startPage(pageNum, pageSize)`方法设置分页参数。
2. 紧接着执行查询,此时PageHelper会自动拦截并改写SQL,添加分页条件(如MySQL的LIMIT)。
3. 将查询结果包装成PageInfo对象,该对象包含分页信息(如总记录数、总页数等)和当前页的数据列表。
下面是一个详细的实现示例:
### 一、添加依赖(Maven项目)
```xml
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.6</version> <!-- 请使用最新稳定版本 -->
</dependency>
```
### 二、配置分页插件(application.yml)
```yaml
pagehelper:
helper-dialect: mysql # 根据实际数据库设置,如mysql, oracle等
reasonable: true # 分页合理化:当页码超出范围时自动调整到合理值
support-methods-arguments: true # 支持通过Mapper接口参数传递分页参数
```
### 三、代码实现
#### 1. Service层
```java
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class UserService {
@Resource
private UserMapper userMapper;
public PageInfo<User> listUsers(int pageNum, int pageSize) {
// 关键:在查询前设置分页参数
PageHelper.startPage(pageNum, pageSize);
// 执行查询(此时SQL已被自动分页)
List<User> userList = userMapper.selectAll();
// 用PageInfo包装结果(包含分页信息)
return new PageInfo<>(userList);
}
}
```
#### 2. Mapper层
```java
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserMapper {
// 注意:这里不需要在SQL中写LIMIT,PageHelper会自动处理
List<User> selectAll();
}
```
对应的XML映射文件(如果使用XML方式):
```xml
<select id="selectAll" resultType="User">
SELECT * FROM user
</select>
```
#### 3. Controller层
```java
import com.github.pagehelper.PageInfo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/users")
public PageInfo<User> getUsers(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size) {
return userService.listUsers(page, size);
}
}
```
### 四、结果说明
调用接口返回的JSON结构示例:
```json
{
"total": 100, // 总记录数
"list": [ // 当前页数据列表
{ "id": 1, "name": "张三" },
{ "id": 2, "name": "李四" }
],
"pageNum": 1, // 当前页码
"pageSize": 10, // 每页记录数
"size": 2, // 当前页实际记录数(当页不足pageSize时)
"pages": 10, // 总页数
"prePage": 0, // 上一页页码
"nextPage": 2, // 下一页页码
"isFirstPage": true, // 是否为第一页
"isLastPage": false, // 是否为最后一页
"hasPreviousPage": false, // 是否有上一页
"hasNextPage": true // 是否有下一页
}
```
### 五、注意事项
1. **调用顺序**
`PageHelper.startPage()`必须紧跟在查询方法之前,中间不能插入其他数据库操作[^1][^2]。
2. **线程安全**
分页参数使用`ThreadLocal`保存,因此确保分页操作在同一个线程内完成。
3. **复杂查询**
对于多表关联查询,PageHelper会自动优化COUNT查询(配置`count=countSql`时)[^3]。
4. **排序支持**
可以通过`PageHelper.orderBy("age DESC")`设置排序,但注意不要与SQL中的`ORDER BY`冲突。
### 六、常见问题
**Q:为什么返回的总记录数不正确?**
A:检查是否在复杂查询中触发了PageHelper的COUNT查询优化问题,可尝试在`startPage`后添加`PageHelper.setCount(true)`强制重新计数。
**Q:如何实现自定义排序?**
A:方案1:在SQL中直接写`ORDER BY`;方案2:使用`PageHelper.orderBy("字段名 ASC/DESC")`(需在`startPage`之后调用)。
---
### 相关问题
1. PageHelper 在分布式环境下如何保证分页参数的正确传递?
2. 如何优化 PageHelper 在百万级数据量下的分页性能?
3. PageHelper 与 MyBatis-Plus 的分页功能有何异同?
4. 分页查询时如何动态传递排序字段?
> 引用说明:
> [^1]: `PageHelper.startPage()`必须在查询前调用
> [^2]: 分页参数通过`ThreadLocal`传递
> [^3]: 配置`count=countSql`可优化COUNT查询效率</think>### PageHelper 分页查询列表实现指南
#### 一、核心实现步骤
1. **添加依赖**(Maven项目)
```xml
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.6</version>
</dependency>
```
2. **配置分页插件**(application.yml)
```yaml
pagehelper:
helper-dialect: mysql # 数据库类型
reasonable: true # 页码超限自动修正
support-methods-arguments: true # 支持接口参数分页
```
3. **Service层实现**
```java
public PageInfo<User> getUserList(int pageNum, int pageSize) {
// 1. 设置分页参数(必须紧贴查询语句)
PageHelper.startPage(pageNum, pageSize);
// 2. 执行查询(无需修改SQL)
List<User> userList = userMapper.selectUserList();
// 3. 包装分页结果
return new PageInfo<>(userList);
}
```
4. **Mapper接口**
```java
@Mapper
public interface UserMapper {
// 无需写LIMIT语句
List<User> selectUserList();
}
```
5. **Controller层**
```java
@GetMapping("/users")
public PageInfo<User> getUserList(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size) {
return userService.getUserList(page, size);
}
```
#### 二、关键原理说明
1. **SQL自动改写**
PageHelper通过拦截器自动改写SQL:
- 原始SQL:$ \text{SELECT * FROM user} $
- 改写后:$ \text{SELECT * FROM user LIMIT ?,?} $
2. **分页参数传递**
使用`ThreadLocal`存储分页参数,确保线程安全[^1][^2]
3. **分页合理化**
当`reasonable=true`时:
- 若 $ \text{pageNum} < 1 $ 自动设为 $ 1 $
- 若 $ \text{pageNum} > \text{maxPage} $ 设为最大页码[^1]
#### 三、返回数据结构示例
```json
{
"total": 100, // 总记录数
"list": [ // 当前页数据
{"id":1, "name":"张三"},
{"id":2, "name":"李四"}
],
"pageNum": 1, // 当前页码
"pageSize": 10, // 每页条数
"pages": 10, // 总页数
"isFirstPage": true // 是否首页
}
```
#### 四、注意事项
1. **调用顺序关键**
`PageHelper.startPage()`必须**紧贴**查询语句,中间不能有其他SQL操作[^1][^2]
2. **复杂查询优化**
多表关联查询时,配置`count=countSql`优化COUNT效率:
```yaml
pagehelper:
params: count=countSql
```
3. **排序支持**
添加动态排序:
```java
PageHelper.startPage(pageNum, pageSize, "create_time DESC");
```
#### 五、前端对接示例(Vue)
```javascript
axios.get(`/users?page=${currentPage}&size=${pageSize}`)
.then(res => {
this.list = res.data.list; // 当前页数据
this.total = res.data.total; // 总记录数
})
```
---
### 相关问题
1. PageHelper 在百万级数据量下如何优化分页性能?
2. 如何实现动态排序字段的分页查询?
3. PageHelper 与 MyBatis-Plus 的分页功能有何区别?
4. 分页查询时如何避免 N+1 查询问题?
> 引用说明:
> [^1]: `PageHelper.startPage()`必须在查询前调用
> [^2]: 分页参数通过`ThreadLocal`传递
> [^3]: 分页合理化机制和COUNT优化
阅读全文
相关推荐


















