Spring Boot分页Bug:空数据表时错误显示多页(应为1页)
Spring Boot分页异常问题:无数据时错误显示多页
问题现象
- 当数据表存在9条有效数据、每页显示5条时,分页正常(共2页);
- 当数据表无有效记录时,错误显示多页,实际应仅显示1页。
相关代码
ProductDAO.java
package com.springboot3.sb3hxh.DAO; import com.springboot3.sb3hxh.Entity.*; import java.util.*; public interface ProductDAO { List<ProductEntity> indexPagination(int page, int size); int totalProducts(); }
ProductService.java
package com.springboot3.sb3hxh.Service; import com.springboot3.sb3hxh.DAO.*; import com.springboot3.sb3hxh.Entity.*; import jakarta.persistence.*; import jakarta.transaction.*; import org.springframework.stereotype.*; import java.time.*; import java.util.*; @Service public class ProductService implements ProductDAO { @PersistenceContext private EntityManager entityManager; public ProductService(EntityManager theEntityManager) { this.entityManager = theEntityManager; } @Override public List<ProductEntity> indexPagination(int page, int size) { TypedQuery<ProductEntity> query = entityManager.createQuery("SELECT p FROM ProductEntity p " + "WHERE p.deleted_at IS NULL " + "ORDER BY p.id ASC", ProductEntity.class); query.setFirstResult(page * size); query.setMaxResults(size); return query.getResultList(); } @Override public int totalProducts() { TypedQuery<Long> query = entityManager.createQuery("SELECT COUNT(p) FROM ProductEntity p", Long.class); return query.getSingleResult().intValue(); } }
ProductController.java
package com.springboot3.sb3hxh.Controller; import com.springboot3.sb3hxh.Entity.*; import com.springboot3.sb3hxh.Service.*; import jakarta.validation.*; import org.springframework.stereotype.*; import org.springframework.ui.*; import org.springframework.validation.*; import org.springframework.web.bind.annotation.*; import java.util.*; @Controller @RequestMapping("/products") public class ProductController { private ProductService productService; public ProductController(ProductService theProductService){ productService = theProductService; } @GetMapping("/list") public String listProducts(Model model, @RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "5") int size){ List<ProductEntity> productEntity = productService.indexPagination(page -1, size); int totalItems = productService.totalProducts(); int totalPages = (int) Math.ceil((double) totalItems / size); model.addAttribute("currentPage", page); model.addAttribute("totalPages", totalPages); model.addAttribute("products", productEntity); return "/product/list-products"; } }
list-products.html
<div class="pagination justify-content-center"> <ul class="pagination"> <li class="page-item" th:each="i: ${#numbers.sequence(1, totalPages)}" th:class="${currentPage == i} ? 'active' : ''"> <a class="page-link" th:href="@{'/products/list?page=' + ${i}}">[[${i}]]</a> </li> </ul> </div>
问题原因
- 统计与查询条件不一致:分页查询过滤了
deleted_at IS NULL的有效数据,但totalProducts()方法统计的是所有ProductEntity(包括已删除数据)。若存在已删除数据,无有效记录时totalItems仍不为0,导致计算出错误的总页数。 - 无数据时总页数计算错误:当totalItems为0时,
Math.ceil(0/size)结果为0,Thymeleaf的#numbers.sequence(1, 0)会生成反向序列,导致显示异常页码。
解决方案
1. 修正统计方法的过滤条件
修改ProductService中的totalProducts()方法,与分页查询保持一致的过滤条件:
@Override public int totalProducts() { TypedQuery<Long> query = entityManager.createQuery("SELECT COUNT(p) FROM ProductEntity p WHERE p.deleted_at IS NULL", Long.class); return query.getSingleResult().intValue(); }
2. 处理无数据时的总页数逻辑
在ProductController中修改总页数计算逻辑,确保无数据时总页数为1:
int totalPages = totalItems == 0 ? 1 : (int) Math.ceil((double) totalItems / size);
3. 优化当前页合法性校验
添加当前页超出总页数时的重定向处理,避免显示空数据:
@GetMapping("/list") public String listProducts(Model model, @RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "5") int size){ int totalItems = productService.totalProducts(); int totalPages = totalItems == 0 ? 1 : (int) Math.ceil((double) totalItems / size); // 处理当前页超出总页数的情况 if (page > totalPages) { page = totalPages; return "redirect:/products/list?page=" + page + "&size=" + size; } List<ProductEntity> productEntity = productService.indexPagination(page -1, size); model.addAttribute("currentPage", page); model.addAttribute("totalPages", totalPages); model.addAttribute("products", productEntity); return "/product/list-products"; }
内容的提问来源于stack exchange,提问作者user23450337
相关产品推荐
相关产品推荐

