当前位置: 首页 > news >正文

java每日精进 5.15【分页实现】

一、前端分页实现

1.1 Vue 界面

前端使用 Element UI 的 Pagination 组件 实现分页,结合搜索功能,展示租户列表。代码位于 tenant/index.vue,以下是核心部分的分析和注释。

<template><!-- 搜索工作栏 --><el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"><el-form-item label="租户名" prop="name"><el-input v-model="queryParams.name" placeholder="请输入租户名" clearable @keyup.enter.native="handleQuery"/></el-form-item><el-form-item label="联系人" prop="contactName"><el-input v-model="queryParams.contactName" placeholder="请输入联系人" clearable @keyup.enter.native="handleQuery"/></el-form-item><el-form-item label="联系手机" prop="contactMobile"><el-input v-model="queryParams.contactMobile" placeholder="请输入联系手机" clearable @keyup.enter.native="handleQuery"/></el-form-item><el-form-item label="租户状态" prop="status"><el-select v-model="queryParams.status" placeholder="请选择租户状态" clearable><el-option v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)":key="dict.value" :label="dict.label" :value="dict.value"/></el-select></el-form-item><el-form-item><el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button><el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button></el-form-item></el-form><!-- 列表 --><el-table v-loading="loading" :data="list"><!-- 省略每一列... --></el-table><!-- 分页组件 --><pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" @pagination="getList"/>
</template>
  • 搜索工作栏
    • 使用 <el-form> 创建搜索表单,绑定 queryParams 对象,包含分页和搜索参数(如 name、contactName、contactMobile、status)。
    • 每个 <el-form-item> 对应一个搜索条件:
      • name、contactName、contactMobile 使用 <el-input>,支持模糊查询。
      • status 使用 <el-select>,从字典 DICT_TYPE.COMMON_STATUS 获取状态选项(如 0=正常,1=停用)。
    • 搜索按钮触发 handleQuery,重置按钮触发 resetQuery。
  • 列表展示
    • <el-table> 绑定 list 数据,显示租户列表,v-loading 控制加载状态。
  • 分页组件
    • <pagination> 是 Element UI 的分页组件,显示当 total > 0 时。
    • 属性:
      • :total:总记录数,从后端返回。
      • :page.sync:绑定当前页码 queryParams.pageNo,双向同步。
      • :limit.sync:绑定每页条数 queryParams.pageSize,双向同步。
      • @pagination:页码或条数变化时触发 getList,重新查询数据。

JavaScript 逻辑

<script>
import { getTenantPage } from "@/api/system/tenant";export default {name: "Tenant",components: {},data() {return {loading: true, // 控制表格加载状态showSearch: true, // 控制搜索栏显示total: 0, // 总记录数list: [], // 租户列表数据queryParams: { // 查询参数pageNo: 1, // 页码,默认为 1pageSize: 10, // 每页条数,默认为 10name: null, // 租户名contactName: null, // 联系人contactMobile: null, // 联系手机status: undefined // 租户状态}}},created() {this.getList(); // 页面初始化时查询数据},methods: {/** 查询列表 */getList() {this.loading = true; // 显示加载状态let params = {...this.queryParams}; // 复制查询参数,避免直接修改getTenantPage(params).then(response => {this.list = response.data.list; // 更新列表数据this.total = response.data.total; // 更新总记录数this.loading = false; // 关闭加载状态});},/** 搜索按钮操作 */handleQuery() {this.queryParams.pageNo = 1; // 重置为第一页this.getList(); // 执行查询},/** 重置按钮操作 */resetQuery() {this.resetForm("queryForm"); // 重置表单this.handleQuery(); // 重新查询}}
}
</script>
  • 数据初始化
    • queryParams 包含分页参数(pageNo、pageSize)和搜索条件。
    • total 和 list 用于存储后端返回的分页数据。
  • 查询逻辑
    • getList:调用 getTenantPage API,传递 queryParams,更新 list 和 total。
    • handleQuery:点击搜索按钮,重置 pageNo 为 1,调用 getList。
    • resetQuery:重置表单,重置后重新查询。
  • 加载状态:loading 控制表格的加载动画,提升用户体验。

1.2 API 请求

前端通过 system/tenant.js 定义 API 请求,调用后端分页接口。

import request from '@/utils/request'// 获得租户分页
export function getTenantPage(query) {return request({url: '/system/tenant/page',method: 'get',params: query})
}
  • 功能:发送 GET 请求到 /system/tenant/page,携带 query 参数(包括 pageNo、pageSize 和搜索条件)。
  • 实现
    • request 是基于 Axios 的封装,处理 HTTP 请求。
    • params: query 将 queryParams 作为查询参数附加到 URL(如 /system/tenant/page?pageNo=1&pageSize=10&name=芋道)。
  • 响应:期待后端返回 CommonResult<PageResult<TenantRespVO>>,包含 list(租户列表)和 total(总记录数)。

二、后端分页实现

2.1 Controller 接口

后端使用 MyBatis Plus 的分页功能,结合二次封装的 PageResult 类实现分页。TenantController 定义了分页接口。

@Tag(name = "管理后台 - 租户")
@RestController
@RequestMapping("/system/tenant")
public class TenantController {@Resourceprivate TenantService tenantService;@GetMapping("/page")@Operation(summary = "获得租户分页")@PreAuthorize("@ss.hasPermission('system:tenant:query')") // 权限校验public CommonResult<PageResult<TenantRespVO>> getTenantPage(@Valid TenantPageReqVO pageVO) {PageResult<TenantDO> pageResult = tenantService.getTenantPage(pageVO); // 调用 Servicereturn success(TenantConvert.INSTANCE.convertPage(pageResult)); // 转换并返回}
}
  • 功能:处理 /system/tenant/page GET 请求,返回租户分页数据。
  • 参数
    • @Valid TenantPageReqVO pageVO:分页和搜索参数,经过校验。
  • 逻辑
    • 调用 tenantService.getTenantPage 获取 PageResult<TenantDO>。
    • 使用 TenantConvert 将 TenantDO 转换为 TenantRespVO。
    • 封装为 CommonResult 返回。
  • 权限:@PreAuthorize 确保用户有 system:tenant:query 权限。
分页参数 PageParam

分页请求继承 PageParam 类,定义页码和每页条数。

@Schema(description = "分页参数")
@Data
public class PageParam implements Serializable {private static final Integer PAGE_NO = 1; // 默认页码private static final Integer PAGE_SIZE = 10; // 默认每页条数@Schema(description = "页码,从 1 开始", required = true, example = "1")@NotNull(message = "页码不能为空")@Min(value = 1, message = "页码最小值为 1")private Integer pageNo = PAGE_NO;@Schema(description = "每页条数,最大值为 100", required = true, example = "10")@NotNull(message = "每页条数不能为空")@Min(value = 1, message = "每页条数最小值为 1")@Max(value = 100, message = "每页条数最大值为 100")private Integer pageSize = PAGE_SIZE;
}
  • 解析
    • pageNo:页码,默认 1,校验非空且 ≥ 1。
    • pageSize:每页条数,默认 10,校验非空,范围 1-100。
    • 使用 @Schema 提供 OpenAPI 文档描述。
搜索条件 TenantPageReqVO

TenantPageReqVO 继承 PageParam,添加搜索条件。

@Schema(description = "管理后台 - 租户分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class TenantPageReqVO extends PageParam {@Schema(description = "租户名", example = "芋道")private String name;@Schema(description = "联系人", example = "芋艿")private String contactName;@Schema(description = "联系手机", example = "15601691300")private String contactMobile;@Schema(description = "租户状态(0正常 1停用)", example = "1")private Integer status;@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")@Schema(description = "创建时间")private LocalDateTime[] createTime;
}
  • 解析
    • 继承 pageNo 和 pageSize。
    • 搜索字段:name、contactName、contactMobile 支持模糊查询,status 支持精确匹配,createTime 支持时间范围查询。
    • @DateTimeFormat 解析时间字符串(如 2025-05-14 09:47:00)。
分页结果 PageResult

分页结果使用 PageResult 类封装。

@Schema(description = "分页结果")
@Data
public final class PageResult<T> implements Serializable {@Schema(description = "数据", required = true)private List<T> list; // 数据列表@Schema(description = "总量", required = true)private Long total; // 总记录数
}

解析

  • list:当前页的数据列表,泛型支持任意类型(如 TenantRespVO)。
  • total:总记录数,用于前端分页组件计算总页数。

2.2 Mapper 查询

后端使用 MyBatis Plus 的分页功能,TenantMapper 定义分页查询。

@Mapper
public interface TenantMapper extends BaseMapperX<TenantDO> {default PageResult<TenantDO> selectPage(TenantPageReqVO reqVO) {return selectPage(reqVO, new LambdaQueryWrapperX<TenantDO>().likeIfPresent(TenantDO::getName, reqVO.getName()) // 模糊查询租户名.likeIfPresent(TenantDO::getContactName, reqVO.getContactName()) // 模糊查询联系人.likeIfPresent(TenantDO::getContactMobile, reqVO.getContactMobile()) // 模糊查询联系手机.eqIfPresent(TenantDO::getStatus, reqVO.getStatus()) // 精确匹配状态.betweenIfPresent(TenantDO::getCreateTime, reqVO.getCreateTime()) // 时间范围查询.orderByDesc(TenantDO::getId)); // 按 ID 倒序}
}
  • 功能:执行分页查询,根据 TenantPageReqVO 的条件构建动态 SQL。
  • 逻辑
    • 使用 LambdaQueryWrapperX(MyBatis Plus 增强封装)动态拼接查询条件。
    • likeIfPresent:当字段非空时添加模糊查询(如 name LIKE '%芋道%')。
    • eqIfPresent:当字段非空时添加精确匹配。
    • betweenIfPresent:当 createTime 非空时添加时间范围查询。
    • orderByDesc:按 id 倒序排序。
  • 返回:PageResult<TenantDO>,包含当前页数据和总记录数。
MyBatis Plus 分页封装

BaseMapperX 封装了 MyBatis Plus 的分页逻辑。

default PageResult<T> selectPage(PageParam pageParam, @Param("ew") Wrapper<T> queryWrapper) {return selectPage(pageParam, null, queryWrapper);
}default PageResult<T> selectPage(PageParam pageParam, Collection<SortingField> sortingFields, @Param("ew") Wrapper<T> queryWrapper) {// 特殊:不分页,直接查询全部if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageSize())) {List<T> list = selectList(queryWrapper);return new PageResult<>(list, (long) list.size());}// MyBatis Plus 查询IPage<T> mpPage = MyBatisUtils.buildPage(pageParam, sortingFields);selectPage(mpPage, queryWrapper);// 转换返回return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
}

解析

  • PageParam:提供 pageNo 和 pageSize。
  • IPage:MyBatis Plus 的分页对象,设置页码和条数。
  • MyBatisUtils.buildPage:将 PageParam 转换为 IPage。
  • 特殊情况:当 pageSize 为 PAGE_SIZE_NONE 时,查询所有数据。
  • 转换:将 IPage 的 records 和 total 转为 PageResult。

相关文章:

  • 自学嵌入式 day 18 - 数据结构 1
  • Seata源码—3.全局事务注解扫描器的初始化一
  • Ansys Zemax | 在 MATLAB 或 Python 中使用 ZOS-API 进行光线追迹的批次处理
  • Web》》url 参数 # 、 ? 、@
  • element ui 级联列表Cascader懒加载数据回显的优雅解决方案
  • LocalDateTime类型的时间在前端页面不显示或者修改数据时因为LocalDateTime导致无法修改,解决方案
  • 会计要素+借贷分录+会计科目+账户,几个银行会计的重要概念
  • 【J2】乘法逆元
  • 将b[索引]中元素按照a中元素的值进行排序
  • C++核心编程--1 内存分区模型
  • python打卡day26
  • 如何在线免费压缩PDF文档?
  • 【MySQL】多表连接查询
  • 各个历史版本mysql/tomcat/Redis/Jdk/Apache/gitlab下载地址
  • 2024年9月电子学会等级考试五级第三题——整数分解
  • 【蓝桥杯省赛真题49】python偶数 第十五届蓝桥杯青少组Python编程省赛真题解析
  • zynq嵌入式linux启动默认设置
  • 钉钉数据与金蝶云星空的无缝集成解决方案
  • 嵌入式开发学习日志(数据结构--双链表)Day21
  • C++ QT图片查看器
  • 国家统计局:2024年城镇单位就业人员工资平稳增长
  • 梅花奖在上海|话剧《主角》:艺术与人生的交错
  • 银行积分大幅贬值遭质疑,涉及工行、中行、农行等
  • 350种咖啡主题图书集结上海,20家参展书店买书送咖啡
  • 艺术稀缺性和价值坚守如何构筑品牌差异化壁垒?从“心邸”看CINDY CHAO的破局之道
  • “家国万里时光故事会” 举行,多家庭共话家风与家国情怀