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

前后端分页详解

一、后端Java分页实现

1. 使用MyBatis + XML(带分页插件)

依赖包:MyBatis + PageHelper

<!-- pom.xml -->
<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.4.6</version>
</dependency>

代码实现

// Controller
@GetMapping("/users")
public PageInfo<User> getUsers(@RequestParam int pageNum, @RequestParam int pageSize) {return userService.getUsers(pageNum, pageSize);
}// Service
public PageInfo<User> getUsers(int pageNum, int pageSize) {PageHelper.startPage(pageNum, pageSize);List<User> users = userMapper.selectAll();return new PageInfo<>(users);
}// Mapper XML(无需手写分页SQL,插件自动处理)
<select id="selectAll" resultType="User">SELECT * FROM users
</select>

2. 纯JDBC手写分页(无框架)

核心逻辑

public class PaginationService {public PageResult<User> getUsers(int pageNum, int pageSize) throws SQLException {int offset = (pageNum - 1) * pageSize;String sql = "SELECT * FROM users LIMIT ? OFFSET ?";String countSql = "SELECT COUNT(*) FROM users";try (Connection conn = DriverManager.getConnection(DB_URL);PreparedStatement ps = conn.prepareStatement(sql);PreparedStatement countPs = conn.prepareStatement(countSql)) {// 查询数据ps.setInt(1, pageSize);ps.setInt(2, offset);ResultSet rs = ps.executeQuery();List<User> users = new ArrayList<>();while (rs.next()) {// 解析User对象...}// 查询总数ResultSet countRs = countPs.executeQuery();int total = countRs.next() ? countRs.getInt(1) : 0;return new PageResult<>(users, total);}}
}

二、前端Vue分页实现

1. 使用Element UI分页组件

安装依赖

npm install element-ui

组件代码

<template><div><el-table :data="tableData"><!-- 表格列定义 --></el-table><el-pagination@current-change="handlePageChange"@size-change="handleSizeChange":current-page="currentPage":page-sizes="[10, 20, 50]":page-size="pageSize"layout="total, sizes, prev, pager, next":total="total"></el-pagination></div>
</template><script>
export default {data() {return {tableData: [],currentPage: 1,pageSize: 10,total: 0};},methods: {async fetchData() {const res = await axios.get('/api/users', {params: { pageNum: this.currentPage, pageSize: this.pageSize }});this.tableData = res.data.list;this.total = res.data.total;},handlePageChange(page) {this.currentPage = page;this.fetchData();},handleSizeChange(size) {this.pageSize = size;this.fetchData();}},mounted() {this.fetchData();}
};
</script>

2. 手动实现分页控件

自定义分页组件

<template><div class="pagination"><button @click="prevPage" :disabled="currentPage === 1">上一页</button><span v-for="page in pages" :key="page" @click="goToPage(page)":class="{ active: page === currentPage }">{{ page }}</span><button @click="nextPage" :disabled="currentPage === totalPages">下一页</button></div>
</template><script>
export default {props: ['currentPage', 'pageSize', 'total'],computed: {totalPages() {return Math.ceil(this.total / this.pageSize);},pages() {const range = [];for (let i = 1; i <= this.totalPages; i++) {range.push(i);}return range;}},methods: {goToPage(page) {this.$emit('page-change', page);},prevPage() {if (this.currentPage > 1) this.goToPage(this.currentPage - 1);},nextPage() {if (this.currentPage < this.totalPages) this.goToPage(this.currentPage + 1);}}
};
</script>

三、数据库分页SQL示例

  1. MySQL

    SELECT * FROM table LIMIT #{pageSize} OFFSET #{offset};
  2. Oracle

    SELECT * FROM (SELECT t.*, ROWNUM rn FROM (SELECT * FROM table ORDER BY id) t WHERE ROWNUM <= #{end}
    ) WHERE rn >= #{start}

四、完整流程说明

  1. 前后端交互协议

    • 请求参数:pageNum(当前页)、pageSize(每页条数)

    • 响应格式:{ list: [], total: 100 }

  2. 关键公式

    offset = (pageNum - 1) * pageSize;
    totalPages = ceil(total / pageSize);

五、总结

  • 使用组件/包:快速开发,适合标准场景(推荐PageHelper + Element UI)。

  • 手动实现:灵活定制,适合特殊需求或学习原理。

  • 性能注意:大数据量时建议使用索引优化分页查询(如MySQL覆盖索引)。

http://www.xdnf.cn/news/8604.html

相关文章:

  • Java的动态加载及类加载器实践
  • UI 设计|提高审美|Linear UI风格分享
  • RxJS 核心操作符详细用法示例
  • AI开发实习生面试总结(持续更新中...)
  • 精华贴分享|个股拥挤度分析研究分析
  • docker安装es连接kibana并安装分词器
  • Windows开机时间过长的原因
  • 射频芯片学习
  • 技术文档的炼金术:从信息碎片到知识体系的系统性构建
  • 《进化陷阱》--AI 生成文章 《连载 1》
  • RxJS 高阶映射操作符详解:map、mergeMap 和 switchMap
  • 大学之大:柏林自由大学2025.5.23
  • feign调用指定服务ip端口
  • winfrom 的 monthCalendar 指定日期字体加粗
  • 辐射发射RE测试
  • 解决用input选择文件不能选择同一个文件
  • Java多线程面试题
  • 白盒测试概念
  • 云原生架构下的企业数字化转型:理念、挑战与最佳实践
  • Honeywell CV-DINA-DI1624-2A 数字输入模块
  • K8s集群Python项目上云部署
  • vue2 全局指令(输入框自定义限制)
  • [crxjs]自己创建一个浏览器插件
  • 嵌入式学习Day27
  • [特殊字符] 构建高内聚低耦合的接口架构:从数据校验到后置通知的分层实践
  • 2025年高防IP与游戏盾深度对比:如何选择最佳防护方案?
  • C语言中地址的加法和减法
  • iOS 上线前的性能与稳定性检查流程实录:开发者的“最后一公里”(含 KeyMob 应用经验)
  • 速卖通OpenAPI商品详情接口开发实战
  • 生产企业ERP系统,项目级ERP系统源码,实现业务流程的全面管理