跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
Java大前端java

MyBatisPlus 与 Thymeleaf 全栈分页整合实战

MyBatisPlus 结合 Thymeleaf 实现全栈分页功能,涵盖环境搭建、实体类定义、Service 层分页逻辑及 Controller 接口设计。前端通过 Ajax 请求获取后端分页数据并动态渲染表格与分页条。重点解决分页插件未配置导致无分页条的问题,提供完整的 Spring Boot 配置示例。适合 Java 全栈开发者参考。

赛博行者发布于 2026/3/29更新于 2026/4/263 浏览
MyBatisPlus 与 Thymeleaf 全栈分页整合实战

MyBatisPlus 与 Thymeleaf 全栈分页整合实战

分页功能在现代 Web 开发中至关重要,它不仅能优化用户体验,还能有效降低服务器负载。本文将通过实际案例,演示如何结合 MyBatisPlus 后端框架与 Thymeleaf 前端模板引擎,实现一套完整的全栈分页方案。

环境搭建与表结构

依赖配置

在 Spring Boot 项目中引入 MyBatisPlus、Lombok 以及 PostgreSQL 驱动是基础。以下 pom.xml 片段展示了核心依赖:

<!-- 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>

数据表设计

以城市停水信息为例,我们需要一张包含时间、地点、原因等字段的表来承载分页数据。表结构及示例数据如下所示:

文章配图

对应的实例数据预览:

文章配图

Java 后台分页实现

实体类定义

实体类需要映射数据库表结构,利用 Lombok 简化 Getter/Setter 方法。注意字段注解需与数据库列名对应。

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;
    
    // ... 其他字段省略 ...
}

业务层逻辑

分页的核心在于 Service 层。MyBatisPlus 提供了 Page 对象来处理分页参数,配合 QueryWrapper 构建查询条件。

首先定义接口方法:

IPage<StopWaterInfo> page(Integer pageNum, Integer pageSize, String regionName);

具体实现时,构造 Page 对象并传入 Mapper:

@Override
public IPage<StopWaterInfo> page(Integer pageNum, Integer pageSize, String regionName) {
    QueryWrapper<StopWaterInfo> queryWrapper = new QueryWrapper<>();
    queryWrapper.like("regin_name", regionName);
    queryWrapper.orderByDesc("created_on");
    Page<StopWaterInfo> page = new Page<>(pageNum, pageSize);
    return this.baseMapper.selectPage(page, queryWrapper);
}

这里我们直接传递当前页码和每页条数,MP 会自动处理 SQL 中的 LIMIT 和 OFFSET 逻辑。

控制层交互

Controller 负责接收前端请求参数,调用 Service 后返回统一结果格式。

@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 前端集成

表格渲染

前端通过 AJAX 获取后端 JSON 数据,动态填充 HTML 表格。以下是加载数据的函数逻辑:

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>`;
        }
    });
}

分页条组件

分页条的生成同样基于后端返回的总页数。为了保持简洁,这里仅展示上一页和下一页按钮。

HTML 结构:

<div>
    <nav aria-label="Table Pagination">
        <ul id="table-pagination"></ul>
    </nav>
</div>

JS 渲染逻辑(修复了原代码中的标签错误):

function renderPagination(totalPages) {
    const paginationContainer = document.getElementById('table-pagination');
    paginationContainer.innerHTML = '';
    if (totalPages <= 1) return;
    
    // 上一页
    paginationContainer.innerHTML += `
        <li ${currentPage === 1 ? 'disabled' : ''}>
            <a href="#" onclick="changePage(${totalPages},${currentPage - 1})" aria-label="Previous">前一页</a>
        </li>
    `;
    
    // 下一页
    paginationContainer.innerHTML += `
        <li ${currentPage === totalPages ? 'disabled' : ''}>
            <a href="#" onclick="changePage(${totalPages},${currentPage + 1})" aria-label="Next">后一页</a>
        </li>
    `;
}

最终效果如下:

文章配图

常见问题排查

分页不展示

如果在页面底部看不到分页条,且所有数据一次性加载完毕,通常是分页插件未生效。

解决方案

检查是否配置了 MybatisPlusInterceptor。如果没有配置,MyBatisPlus 不会拦截 SQL 进行分页处理。正确的配置如下:

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;
    }
}

配置完成后重启服务,分页条即可正常显示。

总结

通过上述步骤,我们完成了从数据库表设计到前后端分页联调的全过程。MyBatisPlus 的分页能力非常强大,只需简单配置即可支持复杂查询场景;而 Thymeleaf 结合原生 JS 则能灵活控制前端展示。在实际开发中,注意分页参数的校验和异常处理,能让系统更加健壮。

目录

  1. MyBatisPlus 与 Thymeleaf 全栈分页整合实战
  2. 环境搭建与表结构
  3. 依赖配置
  4. 数据表设计
  5. Java 后台分页实现
  6. 实体类定义
  7. 业务层逻辑
  8. 控制层交互
  9. Thymeleaf 前端集成
  10. 表格渲染
  11. 分页条组件
  12. 常见问题排查
  13. 分页不展示
  14. 解决方案
  15. 总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • 💰 8折买阿里云服务器限时8折购买
  • 🦞 5分钟部署阿里云小龙虾了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • RTX 4090 本地部署腾讯混元与阿里通义万相视频模型
  • 计算机视觉基础与实战应用解析
  • 基于 DeepSeek 与 Cursor 构建智能代码审查工具实战
  • Vue 踩坑:el-checkbox-group 编辑页状态同步失效修复
  • C++ 计算未排序数组排序后相邻元素的最大差值
  • Qt Creator 配置 GitHub Copilot 插件实战指南
  • Vitis 安装实战:从零搭建 FPGA 开发环境
  • 2026 年主流 AI 生成 PPT 工具实测与横向对比
  • Claude Code 跨平台安装与配置指南(Win/Linux/Mac)
  • Java Web 开发环境搭建:IDEA 与 Tomcat 安装部署指南
  • Spring AI Agent Skills 接入实战与原理剖析
  • CCF-GESP 2025 年 9 月 C++ 三级真题深度解析
  • AIGC 微电影《编钟》制作全流程复盘
  • QClaw:本地化 AI 个人助手平台完全指南
  • 基于 Transformer 的时序数据建模与实现详解
  • Mac mini M4 本地部署 OpenClaw 与 Ollama 接入飞书机器人
  • Spring Web MVC 核心概念与实战详解
  • GitHub 启用双因素身份验证 2FA 配置教程 TOTP.app 动态验证码生成
  • EasyConnect Mac 版安装使用指南
  • Trae IDE 实战:从零开发 AI Chatbot 应用

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online