PageHelper 实现分页查询

PageHelper

PageHelper 是一个用于简化 Java 分页查询的工具库,广泛应用于 MyBatis 和 Spring Data JPA 等框架中。它提供了简单易用的 API 来处理分页和排序操作。
PageHelper 通过拦截器的方式,在查询执行前自动计算分页参数,并在查询结果中返回分页信息。它支持多种数据库,并且可以与其他 ORM 框架配合使用。

PageHelper 的基本用法

添加依赖

1
2
3
4
5
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.0</version>
</dependency>

在 Spring Boot 中配置 PageHelper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// service/EmployeeService.java
public PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO) {
//PageHelper 开始分页查询 类似 select * from employee limit 0,10
//动态从threadLocal中获取当前页码和每页条数 进行动态sql
PageHelper.startPage(employeePageQueryDTO.getPage(), employeePageQueryDTO.getPageSize());

Page<Employee> page = employeeMapper.pageQuery(employeePageQueryDTO);

long total = page.getTotal();
List<Employee> records = page.getResult();

return new PageResult(total, records);
}

// p.s: here PageResult is a custom class to encapsulate the result
// result/PageResult.java
// @Data
// @AllArgsConstructor
// @NoArgsConstructor
// public class PageResult implements Serializable {

// private long total; //总记录数

// private List records; //当前页数据集合

// }
1
2
3
4
5
6
7
8
9
10
// EmployeeMapper.xml
<select id="pageQuery" resultType="com.sky.entity.Employee">
select * from employee
<where>
<if test="name != null and name != ''">
and name like concat('%', #{name}, '%')
</if>
</where>
order by create_time desc
</select>

PageHelper 能够进行动态sql 语句的拼接,将查询条件封装到 PageHelper 中,自动进行分页查询。

以上为实现了分页查询的代码示例

分页查询进一步

发现返回的 createTime 和 updateTime 没有按照年月日时分秒的格式返回

两种处理方法:

  • 使用 @JsonFormat 注解
1
2
3
4
5
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
  • 使用 WebMvcConfigurer 统一进行序列化和反序列化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* 扩展Spring MVC框架的消息转换器
* @param converters
*/
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
log.info("扩展Spring MVC框架的消息转换器...");
// 创建一个消息转换器对象
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
// 需要为消息转换器设置一个对象映射器
converter.setObjectMapper(new JacksonObjectMapper());
// 将自己的消息转换器加入到mvc框架的转换器集合中
// 注意:要将自己的消息转换器放在最前面
converters.add(0, converter);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
* 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
* 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
* 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
*/
public class JacksonObjectMapper extends ObjectMapper {

public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
//public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";

public JacksonObjectMapper() {
super();
//收到未知属性时不报异常
this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);

//反序列化时,属性不存在的兼容处理
this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

SimpleModule simpleModule = new SimpleModule()
.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));

//注册功能模块 例如,可以添加自定义序列化器和反序列化器
this.registerModule(simpleModule);
}
}

使用消息转换器和对象映射器的方式可以统一处理时间格式化问题,避免在每个实体类中都添加 @JsonFormat 注解。
这样可以提高代码的可维护性和可读性。
同时,使用 WebMvcConfigurer 还可以对其他请求和响应进行统一处理,例如添加全局异常处理、跨域配置等。