本文目录导读:

我来给你分享一个通用的Java分页模块设计方案,包含完整的代码实现:
通用分页请求对象
/**
* 通用分页请求参数
*/
public class PageRequest {
// 当前页码,从1开始
private Integer pageNum = 1;
// 每页显示条数
private Integer pageSize = 10;
// 排序字段
private String orderBy;
// 排序方式:asc/desc
private String orderType = "asc";
// 构造函数
public PageRequest() {}
public PageRequest(Integer pageNum, Integer pageSize) {
this.pageNum = pageNum;
this.pageSize = pageSize;
}
// 计算数据库偏移量
public Integer getOffset() {
return (pageNum - 1) * pageSize;
}
// getters and setters
public Integer getPageNum() {
return pageNum;
}
public void setPageNum(Integer pageNum) {
if (pageNum == null || pageNum < 1) {
this.pageNum = 1;
} else {
this.pageNum = pageNum;
}
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
if (pageSize == null || pageSize < 1) {
this.pageSize = 10;
} else {
this.pageSize = Math.min(pageSize, 100); // 限制最大100条
}
}
public String getOrderBy() {
return orderBy;
}
public void setOrderBy(String orderBy) {
this.orderBy = orderBy;
}
public String getOrderType() {
return orderType;
}
public void setOrderType(String orderType) {
if ("asc".equalsIgnoreCase(orderType) || "desc".equalsIgnoreCase(orderType)) {
this.orderType = orderType.toLowerCase();
}
}
}
通用分页响应对象
import java.util.Collections;
import java.util.List;
/**
* 通用分页响应结果
*/
public class PageResult<T> {
// 当前页码
private Integer pageNum;
// 每页条数
private Integer pageSize;
// 总条数
private Long total;
// 总页数
private Integer pages;
// 数据列表
private List<T> list;
// 是否有上一页
private Boolean hasPrevious;
// 是否有下一页
private Boolean hasNext;
public PageResult() {
this.list = Collections.emptyList();
}
/**
* 构建分页结果
*/
public static <T> PageResult<T> build(List<T> list, Long total, PageRequest pageRequest) {
PageResult<T> result = new PageResult<>();
result.setList(list == null ? Collections.emptyList() : list);
result.setTotal(total == null ? 0L : total);
result.setPageNum(pageRequest.getPageNum());
result.setPageSize(pageRequest.getPageSize());
// 计算总页数
if (result.getTotal() == 0) {
result.setPages(0);
} else {
result.setPages((int) Math.ceil((double) result.getTotal() / result.getPageSize()));
}
// 计算是否有上一页/下一页
result.setHasPrevious(result.getPageNum() > 1);
result.setHasNext(result.getPageNum() < result.getPages());
return result;
}
// getters and setters
public Integer getPageNum() {
return pageNum;
}
public void setPageNum(Integer pageNum) {
this.pageNum = pageNum;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Long getTotal() {
return total;
}
public void setTotal(Long total) {
this.total = total;
}
public Integer getPages() {
return pages;
}
public void setPages(Integer pages) {
this.pages = pages;
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
public Boolean getHasPrevious() {
return hasPrevious;
}
public void setHasPrevious(Boolean hasPrevious) {
this.hasPrevious = hasPrevious;
}
public Boolean getHasNext() {
return hasNext;
}
public void setHasNext(Boolean hasNext) {
this.hasNext = hasNext;
}
}
分页工具类
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* 分页工具类
*/
public class PageUtils {
/**
* 手动分页(内存分页)
*/
public static <T> PageResult<T> manualPage(List<T> dataList, PageRequest pageRequest) {
if (dataList == null || dataList.isEmpty()) {
return PageResult.build(Collections.emptyList(), 0L, pageRequest);
}
long total = dataList.size();
int fromIndex = pageRequest.getOffset();
int toIndex = Math.min(fromIndex + pageRequest.getPageSize(), dataList.size());
List<T> pageList;
if (fromIndex >= dataList.size()) {
pageList = Collections.emptyList();
} else {
pageList = dataList.subList(fromIndex, toIndex);
}
return PageResult.build(pageList, total, pageRequest);
}
/**
* 转换分页结果中的数据类型
*/
public static <T, R> PageResult<R> convert(PageResult<T> source, Function<T, R> converter) {
PageResult<R> result = new PageResult<>();
result.setPageNum(source.getPageNum());
result.setPageSize(source.getPageSize());
result.setTotal(source.getTotal());
result.setPages(source.getPages());
result.setHasPrevious(source.getHasPrevious());
result.setHasNext(source.getHasNext());
if (source.getList() != null) {
result.setList(source.getList().stream()
.map(converter)
.collect(Collectors.toList()));
}
return result;
}
}
MyBatis Plus 分页实现
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Service;
/**
* MyBatis Plus 分页示例
*/
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
/**
* 使用MyBatis Plus分页插件
*/
public PageResult<UserVO> pageUsers(PageRequest pageRequest) {
// 创建MyBatis Plus分页对象
Page<User> page = new Page<>(pageRequest.getPageNum(), pageRequest.getPageSize());
// 执行分页查询(自动添加limit)
IPage<User> userPage = userMapper.selectPage(page, null);
// 转换为通用分页结果
List<UserVO> userVOS = userPage.getRecords().stream()
.map(this::convertToVO)
.collect(Collectors.toList());
return PageResult.build(userVOS, userPage.getTotal(), pageRequest);
}
/**
* 带条件的分页查询
*/
public PageResult<UserVO> searchUsers(String keyword, PageRequest pageRequest) {
Page<User> page = new Page<>(pageRequest.getPageNum(), pageRequest.getPageSize());
// 使用Lambda条件构造器
LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery()
.like(StringUtils.isNotBlank(keyword), User::getUsername, keyword)
.orderByDesc(User::getCreateTime);
IPage<User> userPage = userMapper.selectPage(page, wrapper);
List<UserVO> userVOS = userPage.getRecords().stream()
.map(this::convertToVO)
.collect(Collectors.toList());
return PageResult.build(userVOS, userPage.getTotal(), pageRequest);
}
}
原生JDBC/MyBatis分页实现
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
/**
* 原生SQL分页查询
*/
@Mapper
public interface ProductMapper {
/**
* 查询总数
*/
@Select("SELECT COUNT(*) FROM product WHERE status = #{status}")
Long countByStatus(@Param("status") Integer status);
/**
* 分页查询
*/
@Select("SELECT * FROM product WHERE status = #{status} " +
"ORDER BY create_time DESC " +
"LIMIT #{offset}, #{pageSize}")
List<Product> pageByStatus(@Param("status") Integer status,
@Param("offset") Integer offset,
@Param("pageSize") Integer pageSize);
}
@Service
public class ProductService {
@Autowired
private ProductMapper productMapper;
/**
* 手动分页实现
*/
public PageResult<Product> pageProducts(Integer status, PageRequest pageRequest) {
// 查询总数
Long total = productMapper.countByStatus(status);
// 查询分页数据
List<Product> list;
if (total > 0) {
list = productMapper.pageByStatus(status,
pageRequest.getOffset(),
pageRequest.getPageSize());
} else {
list = Collections.emptyList();
}
return PageResult.build(list, total, pageRequest);
}
}
Spring Data JPA分页实现
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/**
* JPA Repository
*/
public interface OrderRepository extends JpaRepository<Order, Long>,
JpaSpecificationExecutor<Order> {
}
@Service
public class OrderService {
@Autowired
private OrderRepository orderRepository;
/**
* JPA分页查询
*/
public PageResult<Order> pageOrders(PageRequest pageRequest) {
// 创建JPA分页对象
Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
Pageable pageable = PageRequest.of(
pageRequest.getPageNum() - 1, // JPA页码从0开始
pageRequest.getPageSize(),
sort
);
// 执行分页查询
Page<Order> orderPage = orderRepository.findAll(pageable);
// 转换为通用分页结果
return PageResult.build(
orderPage.getContent(),
orderPage.getTotalElements(),
pageRequest
);
}
/**
* 带条件的分页查询
*/
public PageResult<Order> searchOrders(String orderNo, PageRequest pageRequest) {
Pageable pageable = PageRequest.of(
pageRequest.getPageNum() - 1,
pageRequest.getPageSize()
);
// 使用Specification构建条件
Specification<Order> spec = (root, query, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
if (StringUtils.isNotBlank(orderNo)) {
predicates.add(criteriaBuilder.like(root.get("orderNo"), "%" + orderNo + "%"));
}
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
};
Page<Order> orderPage = orderRepository.findAll(spec, pageable);
return PageResult.build(
orderPage.getContent(),
orderPage.getTotalElements(),
pageRequest
);
}
}
使用示例
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
/**
* 分页查询用户列表
*/
@GetMapping("/page")
public Result<PageResult<UserVO>> pageUsers(PageRequest pageRequest) {
PageResult<UserVO> result = userService.pageUsers(pageRequest);
return Result.success(result);
}
/**
* 搜索用户分页
*/
@GetMapping("/search")
public Result<PageResult<UserVO>> searchUsers(
@RequestParam(required = false) String keyword,
PageRequest pageRequest) {
PageResult<UserVO> result = userService.searchUsers(keyword, pageRequest);
return Result.success(result);
}
}
// 通用响应对象
class Result<T> {
private Integer code;
private String message;
private T data;
public static <T> Result<T> success(T data) {
Result<T> result = new Result<>();
result.setCode(200);
result.setMessage("success");
result.setData(data);
return result;
}
// getters and setters...
}
分页查询最佳实践
前端请求示例
// axios请求
axios.get('/api/users/page', {
params: {
pageNum: 1,
pageSize: 10,
orderBy: 'createTime',
orderType: 'desc'
}
}).then(response => {
console.log(response.data);
});
注意事项
- 防止SQL注入:排序字段需要做白名单校验
- 分页大小限制:设置最大分页大小,防止内存溢出
- 缓存优化:对不经常变化的数据做缓存
- 索引优化:分页查询字段要建立合适的索引
- 大数据量处理:使用游标分页或键集分页代替传统分页
这个通用的分页模块可以适配不同的ORM框架,提供一致的分页功能,你可以根据具体需求选择使用手动分页、MyBatis Plus、JPA等不同实现方式。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播