后端分页必须使用ipage而非list,因其能在sql层面注入limit/offset实现数据库物理分页;多表关联须定义vo接收联查字段并严格匹配别名,且list与count查询逻辑必须完全一致以保障分页正确性。

后端分页必须用 IPage 而不是 List
layui 的 table.render 默认会传 page 和 limit 两个参数,后端如果只返回 List,就等于把全量数据查出来再内存分页——数据一过千行,接口直接卡死或 OOM。
MyBatis-Plus 的 IPage 是唯一可靠解法:它会在 SQL 层面注入 LIMIT ? OFFSET ?(MySQL)或 ROWNUM(Oracle),让数据库承担分页压力。
- Service 方法签名必须是
IPage<map></map>或IPage<yourvo></yourvo>,不能是List<...></...> - Mapper 接口方法需带
@Param("page") Page<t> page</t>和@Param(Constants.WRAPPER) QueryWrapper<t> wrapper</t> - XML 中的 SQL 不要手动写
LIMIT #{page},#{limit}—— 这是旧 MyBatis 写法,和 MP 的自动分页冲突,会导致总数错、页码跳变
多表关联必须用 VO/DTO 接收,不能用实体类
比如你联查 user 和 dept 表,User 实体里没有 deptName 字段,但页面要显示部门名称。硬塞字段到实体里会污染领域模型,且 MP 自动映射会失败。
正确做法是定义一个平铺 VO:
public class UserWithDeptVo {
private Long userId;
private String userName;
private String deptName; // 来自 join 后的别名
}
然后在 XML 的 <select></select> 里明确写出字段别名,和 VO 属性一一对应:
SELECT u.user_id AS userId, u.user_name AS userName, d.dept_name AS deptName FROM sys_user u LEFT JOIN sys_dept d ON u.dept_id = d.dept_id
- VO 必须有无参构造 + getter/setter,MP 才能反射赋值
- 字段名必须严格匹配别名(注意大小写),MP 不做驼峰转换时尤其关键
- 不要用
*查询,否则 VO 多余字段可能被误赋 null,导致前端渲染异常
前端 table.render 的 where 参数必须透传到后端
layui 表格的条件查询不是靠 form 提交,而是靠 where 配置项把 JS 对象序列化后拼进 URL 或 POST body。如果你漏传或格式不对,后端收不到参数,多表关联的 WHERE 条件就失效。
典型写法:
table.render({
elem: '#demo',
url: '/user/list',
where: {
userName: $('#userName').val(),
deptName: $('#deptName').val()
},
// ...其他配置
});
-
where里的 key 名必须和后端 Controller 参数名一致(如@RequestParam String userName) - 如果用
QueryWrapper构建动态条件,注意字段前缀:比如u.user_name要写成wrapper.like("u.user_name", value),不能只写"user_name" - 日期范围、模糊搜索等复杂条件,建议统一收口到 DTO,避免 Controller 层堆砌 if 判断
count 查询必须和 list 查询逻辑完全一致
这是最容易出错的一环:layui 分页依赖后端返回的 count 值算总页数。如果 count SQL 没 join 同样的表、没加同样的 WHERE 条件,就会出现“最后一页空数据”或“页码显示错乱”。
例如 list 查询是:
SELECT u.*, d.dept_name FROM user u LEFT JOIN dept d ON u.dept_id = d.id WHERE u.status = 1
那 count 就必须是:
SELECT COUNT(*) FROM user u LEFT JOIN dept d ON u.dept_id = d.id WHERE u.status = 1
- 别用
SELECT COUNT(*) FROM user—— 它忽略了 dept 关联和 dept 相关的筛选条件 - MP 的
count()方法默认只对主表生效,多表场景下必须手写countSQL,或用QueryWrapper+selectCount并确保 wrapper 条件与 list 查询完全同步 - XML 中
countSQL 的<if></if>标签必须和 list SQL 保持镜像,哪怕只是复制粘贴也要逐行核对











