Implementing Pagination in Java Web Applications with Spring MVC and MyBatis
This article demonstrates how to implement pagination and search pagination in a Java web project using Spring MVC, MyBatis, and standard pagination utilities, covering the creation of a Page utility class, MyBatis mapper configurations, DAO interfaces, service methods, controller handling, and JSP view integration.
The article explains a complete pagination solution for Java web projects, focusing on Spring MVC combined with MyBatis, and provides a reusable Page utility class to calculate page numbers, sizes, and navigation flags.
import java.io.Serializable;
/**
* Pagination utility class
*/
public class Page implements Serializable {
private static final long serialVersionUID = -3198048449643774660L;
private int pageNow = 1; // current page
private int pageSize = 4; // records per page
private int totalCount; // total records
private int totalPageCount; // total pages
@SuppressWarnings("unused")
private int startPos; // start position (0‑based)
@SuppressWarnings("unused")
private boolean hasFirst;
@SuppressWarnings("unused")
private boolean hasPre;
@SuppressWarnings("unused")
private boolean hasNext;
@SuppressWarnings("unused")
private boolean hasLast;
/** constructor */
public Page(int totalCount, int pageNow) {
this.totalCount = totalCount;
this.pageNow = pageNow;
}
public int getTotalPageCount() {
totalPageCount = getTotalCount() / getPageSize();
return (totalCount % pageSize == 0) ? totalPageCount : totalPageCount + 1;
}
public int getStartPos() {
return (pageNow - 1) * pageSize;
}
public boolean isHasFirst() {
return (pageNow == 1) ? false : true;
}
public boolean isHasPre() {
return isHasFirst() ? true : false;
}
public boolean isHasNext() {
return isHasLast() ? true : false;
}
public boolean isHasLast() {
return (pageNow == getTotalCount()) ? false : true;
}
// getters and setters omitted for brevity
}The corresponding MyBatis mapper XML defines two <select> statements: one for retrieving a page of products and another for counting the total number of records.
<!-- Pagination SQL -->
<select id="selectProductsByPage" resultMap="返回值类型">
select *
from 表名
WHERE user_id = #{userId,jdbcType=INTEGER}
limit #{startPos},#{pageSize}
</select>
<!-- Count SQL -->
<select id="getProductsCount" resultType="long">
SELECT COUNT(*) FROM 表名 WHERE user_id = #{userId,jdbcType=INTEGER}
</select>DAO interfaces use MyBatis annotations to bind the parameters required by the mapper.
/** select products by page */
public List<Products> selectProductsByPage(@Param("startPos") Integer startPos,
@Param("pageSize") Integer pageSize,
@Param("userId") Integer userId);
/** get product count */
public long getProductsCount(@Param("userId") Integer userId);In the service layer a method showProductsByPage receives the HTTP request, extracts the current page number, builds a Page object, calls the DAO, and puts the result list and pagination object into the model.
String pageNow = request.getParameter("pageNow");
Page page = null;
int totalCount = (int) productDao.getProductsCount(loginUserId);
if (pageNow != null) {
page = new Page(totalCount, Integer.parseInt(pageNow));
} else {
page = new Page(totalCount, 1);
}
List<ProductWithBLOBs> products = productDao.selectProductsByPage(page.getStartPos(), page.getPageSize(), loginUserId);
model.addAttribute("products", products);
model.addAttribute("page", page);The controller initializes the product list page, checks the user session, and delegates to the service method.
@RequestMapping(value = "映射路径", method = RequestMethod.GET)
public String showMyProduct(HttpServletRequest request, Model model) {
User loginUser = (User) request.getSession().getAttribute("loginUser");
if (loginUser == null || "".equals(loginUser)) {
return "redirect:/";
}
int loginUserId = loginUser.getUserId();
productService.showProductsByPage(request, model, loginUserId);
return "跳转到的JSP路径";
}The JSP view renders pagination controls using JSTL <c:choose> and <c:when> tags, providing links for first, previous, next, and last pages based on the Page object's properties.
<!-- Pagination start -->
<div align="center">
<font size="2">共 ${page.totalPageCount} 页 第 ${page.pageNow} 页</font>
<a href="myProductPage?pageNow=1">首页</a>
<c:choose>
<c:when test="${page.pageNow - 1 > 0}">
<a href="myProductPage?pageNow=${page.pageNow - 1}">上一页</a>
</c:when>
<c:when test="${page.pageNow - 1 <= 0}">
<a href="myProductPage?pageNow=1">上一页</a>
</c:when>
</c:choose>
<!-- similar logic for next and last page -->
</div>
<!-- Pagination end -->For search‑based pagination the same flow is reused; the controller stores the search condition in the session, reuses the Page utility, and renders the same JSP fragment, avoiding code duplication.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
