Implementing Pagination in a Java Web Application with Spring MVC and MyBatis
This article demonstrates how to implement page-based data retrieval in a Java web application using Spring MVC, MyBatis, and a custom Page utility class, covering the creation of the pagination class, mapper XML, DAO interfaces, service logic, controller handling, and JSP pagination controls.
This guide shows a complete end‑to‑end solution for adding pagination to a Java web project that uses Spring MVC, MyBatis and a simple utility class named Page. The solution includes the pagination class, MyBatis mapper XML, DAO interface, service layer, controller method and JSP view code.
import java.io.Serializable;
/**
* Pagination utility class
*/
public class Page implements Serializable {
private static final long serialVersionUID = -3198048449643774660L;
private int pageNow = 1; // current page number
private int pageSize = 4; // records per page
private int totalCount; // total record count
private int totalPageCount; // total pages
private int startPos; // start position (0‑based)
private boolean hasFirst;
private boolean hasPre;
private boolean hasNext;
private boolean hasLast;
/**
* Construct with total record count and current page
*/
public Page(int totalCount, int pageNow) {
this.totalCount = totalCount;
this.pageNow = pageNow;
}
/** Get total page count */
public int getTotalPageCount() {
totalPageCount = getTotalCount() / getPageSize();
return (totalCount % pageSize == 0) ? totalPageCount : totalPageCount + 1;
}
public void setTotalPageCount(int totalPageCount) { this.totalPageCount = totalPageCount; }
public int getPageNow() { return pageNow; }
public void setPageNow(int pageNow) { this.pageNow = pageNow; }
public int getPageSize() { return pageSize; }
public void setPageSize(int pageSize) { this.pageSize = pageSize; }
public int getTotalCount() { return totalCount; }
public void setTotalCount(int totalCount) { this.totalCount = totalCount; }
/** Get start position for SQL LIMIT */
public int getStartPos() { return (pageNow - 1) * pageSize; }
public void setStartPos(int startPos) { this.startPos = startPos; }
public boolean isHasFirst() { return pageNow == 1 ? false : true; }
public void setHasFirst(boolean hasFirst) { this.hasFirst = hasFirst; }
public boolean isHasPre() { return isHasFirst() ? true : false; }
public void setHasPre(boolean hasPre) { this.hasPre = hasPre; }
public boolean isHasNext() { return isHasLast() ? true : false; }
public void setHasNext(boolean hasNext) { this.hasNext = hasNext; }
public boolean isHasLast() { return (pageNow == getTotalCount()) ? false : true; }
public void setHasLast(boolean hasLast) { this.hasLast = hasLast; }
}MyBatis mapper XML defines two statements: one for fetching a page of products and another for counting total records.
<!-- Pagination SQL -->
<select id="selectProductsByPage" resultMap="返回值类型">
select *
from 表名
WHERE user_id = #{userId,jdbcType=INTEGER}
limit #{startPos},#{pageSize}
</select>
<!-- Count total records -->
<select id="getProductsCount" resultType="long">
SELECT COUNT(*) FROM 表名 WHERE user_id = #{userId,jdbcType=INTEGER}
</select>The DAO interface declares methods that correspond to the mapper IDs, using @Param to bind the three parameters required for pagination.
/** Retrieve a page of products */
public List<Products> selectProductsByPage(@Param(value="startPos") Integer startPos,
@Param(value="pageSize") Integer pageSize,
@Param(value="userId") Integer userId);
/** Get total product count for a user */
public long getProductsCount(@Param(value="userId") Integer userId);In the service layer an interface method is defined to drive the pagination logic, and its implementation calls the DAO, builds a Page object and puts the results into the model.
/** Show products with pagination */
void showProductsByPage(HttpServletRequest request, Model model, int loginUserId);Implementation example (excerpt):
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 method obtains the logged‑in user from the session, validates it, and delegates to the service method. It finally returns the logical view name of the JSP page.
@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();
this.productService.showProductsByPage(request, model, loginUserId);
return "跳转到的JSP路径";
}The JSP fragment renders the pagination bar using JSTL c:choose / c:when tags and builds links for first, previous, next and last pages.
<!-- 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 -->Together these pieces provide a reusable pagination mechanism that can be adapted for simple list views or search‑filtered results in a Spring MVC + MyBatis Java web application.
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.
Java Captain
Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.
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.
