PageHelper是一个用于在数据库查询结果中进行分页的插件。它会在执行查询之前先进行查询总数,然后根据分页参数对查询结果进行切片,返回指定页码的数据。这样可以避免一次性加载全部数据,提高查询效率。
使用步骤:
1.在pom.xml文件中导入依赖包
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
2.注意,PageHelper插件默认使用的是MySQL数据库的分页方式,如果使用其他数据库,需要在配置文件中进行相应配置。
3.mapper层,mapper层写上查询该表数据返回List的方法
/**
* 查询用户数据列表
*
* @return 用户数据列表
*/
List<UserListItemVO> list();
4.repository层,repository层对mapper层进行数据操作,service层直接和repository层打交道。
repository接口方法:
/**
* 查询用户数据列表
*
* @param pageNum 页码
* @param pageSize 每页记录数
* @return 用户数据列表
*/
PageData<UserListItemVO> list(Integer pageNum, Integer pageSize);
编写测试类:
@Test
void list(){
Integer pageNum = 1;
Integer pageSize = 10;
PageHelper.startPage(pageNum,pageSize);
List<UserListItemVO> list = mapper.list();
System.out.println(list.getClass().getName());
}
PageHelper.startPage(pageNum, pageSize)来实现分页,在使用时先查询后分页,它会自动统计共多少条数据,并给SQL语句加上limit,参数为方法的参数。
通过该句后的第一个mapper查询就实现了分页,返回值类型是com.github.pagehelper.Page,该类继承自ArrayList类,Page提供了一些分页相关的方法,如获取当前页码、获取总页数、获取上一页页码等。而PageInfo则提供了更加丰富的分页相关方法,如获取所有页的页码列表、获取当前页的数据条数、判断是否有上一页等。因此通常使用pageInfo类处理分页后的数据,new一个pageInfo对象,将list数据传进去。
自定义PageData类
自定义PageData类可以自由地添加或删除分页相关信息,比如添加总页数、当前页码、每页显示条数等信息。这样可以更加灵活地处理分页数据,满足不同场景的需求,使分页数据的处理更加灵活、易于维护和易于传递,也使得service层不依赖导入的pageInfo类,也可实现分页。
1.定义PageData类:
(使用@Accessors(chain = true)注解后,Lombok会自动生成链式调用方式)
@Data
@Accessors(chain = true)
public class PageData<T> implements Serializable {
/**
* 每页记录数
*/
private Integer pageSize;
/**
* 记录总数
*/
private Long total;
/**
* 当前页码
*/
private Integer currentPage;
/**
* 最大页码
*/
private Integer maxPage;
/**
* 数据列表
*/
private List<T> list;
}
2.将方法的返回值类型修改为PageData<T>。
3.定义一个工具类将PageInfo<T>类型转换为PageData<T>。
public class PageInfoToPageDataConverter {
/**
* 将PageHelper框架中的PageInfo类型对象转换成自定义的PageData类型对象
*
* @param pageInfo PageInfo对象
* @param <T> PageInfo对象中的列表数据中的元素数据的类型
* @return 自定义的PageData类型的对象
*/
public synchronized static <T> PageData<T> convert(PageInfo<T> pageInfo) {
PageData<T> pageData = new PageData<>();
pageData.setPageSize(pageInfo.getPageSize())
.setTotal(pageInfo.getTotal())
.setCurrentPage(pageInfo.getPageNum())
.setMaxPage(pageInfo.getPages())
.setList(pageInfo.getList());
return pageData;
}
}
UserRepositoryImpl类:
@Override
public PageData<UserListItemVO> list(Integer pageNum, Integer pageSize) {
log.debug("开始执行【查询用户列表】的数据访问,页码:{},每页记录数:{}", pageNum,pageSize);
PageHelper.startPage(pageNum, pageSize);
List<UserListItemVO> list = userMapper.list();
PageInfo<UserListItemVO> pageInfo = new PageInfo<>(list);
PageData<UserListItemVO> pageData =PageInfoToPageDataConverter.convert(pageInfo);
return pageData;
}
service层:
@Override
public PageData<UserListItemVO> list(Integer pageNum, Integer pageSize) {
log.debug("开始处理【查询用户列表】的业务,页码:{},每页记录数:{}", pageNum, pageSize);
PageData<UserListItemVO> pageData = userRepository.list(pageNum, pageSize);
return pageData;
}
也可以在service中重新定义一个只有pageNum一个参数的方法(该方法使用默认的每页记录数),在配置文件中配置pageSize的值 ,并使用@Value
注解来获取配置文件中的属性值。
# 学茶商城的自定义配置
tea-store:
# 数据访问的相关配置
dao:
# 查询数据时,默认的每页记录数,建议值为10~30之间
default-query-page-size: 5
在service的实现类中通过@Value
注解获取值
@Value("${tea-store.dao.default-query-page-size}")
private Integer defaultQueryPageSize;
controller层:
@GetMapping("")
@PreAuthorize("hasAuthority('/account/user/read')")
@ApiOperation("查询用户列表")
@ApiOperationSupport(order = 420)
@ApiImplicitParams({
@ApiImplicitParam(name = "page", value = "页码", defaultValue = "1", dataType = "long")
})
public JsonResult list(Integer page) {
log.debug("开始处理【查询用户列表】的请求,页码:{}", page);
Integer pageNum = page == null ? 1 : page;
PageData<UserListItemVO> pageData = userService.list(pageNum);
return JsonResult.ok(pageData);
}
至此就实现了后端分页。