前言
分页功能是现代应用开发中不可或缺的一部分。通过 MyBatisPlus 和 Thymeleaf 的深度整合,可以实现一个高效、稳定的全栈分页解决方案。本文旨在介绍如何通过 Spring Boot 项目实现后端数据分页查询与前端页面渲染的对接。
一、MybatisPlus 搭建及表介绍
1、MybatisPlus 环境搭建
在 Maven 项目的 pom.xml 文件中引入 MyBatisPlus 依赖,同时集成 PostgreSQL 数据库驱动包和 Lombok 组件:
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!-- lombok 代码自动生成组件 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- PostgreSql 驱动包 -->
<dependency>
<groupId>net.postgis</groupId>
<artifactId>postgis-jdbc</artifactId>
<version>2.5.0</version>
</dependency>
2、示例表结构介绍
以城市停水信息数据为例,表结构如下:

对应的实例数据如下:

二、Java 后台分页实现
1、实体类实现
定义 Java 实体类,使用 MyBatisPlus 注解映射数据库表:
package org.yelang.pcwater.domain;
import java.io.Serializable;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@TableName(value = "biz_stop_water_info")
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
@ToString
public class StopWaterInfo implements Serializable {
private static final long serialVersionUID = -1582687729349525826L;
@TableId(value="pk_id")
private Long pkId;
@TableField(value = "affect_user")
private String affectUser;
@TableField(value = "affected_range")
private String affectedRange;
@TableField(value = "affect_region")
private String affectRegion;
@TableField(value = "created_on")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createdOn;
@TableField(value = "inform_emergency_plan")
private String informEmergencyPlan;
@TableField(value = "inform_id")
private Integer informId;
@TableField(value = "inform_remark")
private String informRemark;
@TableField(value = "main_lead_path")
private String mainLeadPath;
private String position;
private String reason;
@TableField(value = "service_phone")
private String servicePhone;
@TableField(value = "show_end_date")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@SerializedName("showenddate")
private Date showEndDate;
@TableField(value = "stop_end_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date stopEndTime;
@TableField(value = "stop_start_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date stopStartTime;
@TableField(value = "stop_time")
@SerializedName("stoptime")
private String stopTime;
@TableField(value = "stopwater_type")
private String stopwaterType;
@TableField(value = "supply_emergency_plan")
private String supplyEmergencyPlan;
@TableField(value = "supply_remark")
private String supplyRemark;
private String title;
private String type;
@TableField(value = "regin_name")
private String reginName;
@TableField(value = "sync_sno")
private Long syncSno;
}
2、业务层分页实现
在业务接口中定义分页方法,使用 IPage 对象返回结果:
/**
* -根据区域查询分页停水信息列表
* @param pageNum
* @param pageSize
* @param regionName
* @return
*/
IPage<StopWaterInfo> page(Integer pageNum, Integer pageSize,String regionName);
具体实现逻辑:
@Override
public IPage<StopWaterInfo> page(Integer pageNum, Integer pageSize, String regionName) {
QueryWrapper<StopWaterInfo> queryWrapper = new QueryWrapper<StopWaterInfo>();
queryWrapper.like("regin_name", regionName);
queryWrapper.orderByDesc("created_on");
Page<StopWaterInfo> page = new Page<StopWaterInfo>(pageNum, pageSize);
return this.baseMapper.selectPage(page, queryWrapper);
}
3、控制层实现
控制层接收前端参数,调用业务层方法并返回结果:
/**
* - 获取分页数据
* @param pageNum
* @param pageSize
* @param regionName
* @return
*/
@PostMapping("/list")
@ResponseBody
public AjaxResult list(@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "5") Integer pageSize,
@RequestParam(defaultValue = "") String regionName) {
IPage<StopWaterInfo> page = waterInfoService.page(pageNum, pageSize, regionName);
AjaxResult result = AjaxResult.success();
result.put("data", page);
return result;
}
三、Thymeleaf 分页集成
1、分页表格展示
在 HTML 中定义表格结构,并通过 AJAX 加载数据:
<div>
<table>
<thead>
<tr>
<th>创建时间</th>
<th>停水地点</th>
<th>原因</th>
</tr>
</thead>
<tbody>
<tr th:if="${#lists.isEmpty(waterEvents)}">
<td colspan="3">请点击查询按钮加载数据。</td>
</tr>
</tbody>
</table>
</div>
JavaScript 示例代码:
function renderTablePage(page) {
currentPage = page;
const tableBody = document.getElementById('table-body');
tableBody.innerHTML = '';
$.ajax({
type:"post",
url:ctx + "datasync/list",
dataType:"json",
cache:false,
processData:true,
data: {"pageNum":page,"pageSize":EVENTS_PER_PAGE,"regionName":""},
success:function(result){
const pageData = result.data.records;
const totalPages = result.data.pages;
if (pageData.length === 0) {
tableBody.innerHTML = `<tr><td colspan="5">未找到符合条件的停水事件。</td></tr>`;
} else {
pageData.forEach(event => {
const row = tableBody.insertRow();
row.innerHTML = `
<td>${event.createdOn}</td>
<td>${event.position}</td>
<td>${event.reason}</td>
`;
});
}
renderPagination(totalPages);
},
error:function(){
tableBody.innerHTML = `<tr><td colspan="5">未找到符合条件的停水事件。</td></tr>`;
}
});
}
2、分页条集成
在网页中插入分页元素标签:
<div>
<nav aria-label="Table Pagination">
<ul></ul>
</nav>
</div>
同步设置分页条逻辑(修复了原代码中的语法错误):
function renderPagination(totalPages) {
const paginationContainer = document.getElementById('table-pagination');
paginationContainer.innerHTML = '';
if (totalPages <= 1) return;
// 上一页按钮
paginationContainer.innerHTML += `<li${currentPage === 1 ? ' disabled' : ''}>`;
paginationContainer.innerHTML += `<a href="#" onclick="changePage(${totalPages},${currentPage - 1})" aria-label="Previous">前一页</a>`;
paginationContainer.innerHTML += `</li>`;
// 下一页按钮
paginationContainer.innerHTML += `<li${currentPage >= totalPages ? ' disabled' : ''}>`;
paginationContainer.innerHTML += `<a href="#" onclick="changePage(${totalPages},${currentPage + 1})" aria-label="Next">后一页</a>`;
paginationContainer.innerHTML += `</li>`;
}
3、成果展示
最终效果展示如下:

四、可能遇到的问题
1、分页不展示
如果页面显示所有数据且无分页条,可能是未正确配置分页插件。
2、问题解决
需要在后台配置好 MyBatisPlus 的分页插件:
package org.yelang.pcwater.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor i = new MybatisPlusInterceptor();
i.addInnerInterceptor(new PaginationInnerInterceptor(DbType.POSTGRE_SQL));
return i;
}
}
配置完成后再次运行程序,即可正常显示分页条。
五、总结
本文介绍了基于 Spring Boot、MyBatisPlus 和 Thymeleaf 的全栈分页实现方案。内容包括环境搭建、实体类定义、业务层分页逻辑编写、控制层 API 设计以及前端表格与分页条的集成。重点讲解了 MyBatisPlus 分页插件的配置方法,解决了分页不展示等常见问题。通过具体代码示例展示了从后端数据查询到前端页面渲染的完整流程。


