网站界面设计修改要多少钱,厦门 微网站制作,网站建设与运营成本,成都品牌形象设计公司写在前面#xff1a;大家好#xff01;我是晴空๓。如果博客中有不足或者的错误的地方欢迎在评论区或者私信我指正#xff0c;感谢大家的不吝赐教。我的唯一博客更新地址是#xff1a;https://ac-fun.blog.csdn.net/。非常感谢大家的支持。一起加油#xff0c;冲鸭#x… 写在前面大家好我是晴空๓。如果博客中有不足或者的错误的地方欢迎在评论区或者私信我指正感谢大家的不吝赐教。我的唯一博客更新地址是https://ac-fun.blog.csdn.net/。非常感谢大家的支持。一起加油冲鸭 用知识改变命运用知识成就未来加油 (ง •̀o•́)ง (ง •̀o•́)ง 文章目录 为什么需要分页查询减少数据库压力减少网络传输数据量提高系统的稳定性提升用户体验 原始的实现方式计算偏移量在Mapper接口中定义查询方法编写SQL语句开发流程及完整代码Controller层Service实现类Mapper接口方法xml文件SQL 使用插件实现引入分页插件依赖Service实现类xml文件SQL与原始分页的不同 为什么需要分页查询 分页查询是一种常见的数据库查询技术用于将查询结果分成多个页面展示而不是一次性返回所有数据。使用分页查询主要是为了减少数据库压力、减少网络传输数据量、提高系统的稳定性、提高客户体验。
减少数据库压力 一次性查询全部数据例如百万条记录会占用大量的资源CPU、内存、I/O导致响应变慢甚至系统崩溃。分页后每次仅查询少量数据如每页100条可以显著降低负载。
减少网络传输数据量 分页查询每次只传输当前页的数据相比于全表查询会极大的减少网络传输的数据量降低网络带宽的占用。
提高系统的稳定性 后端服务处理分页查询时单次处理的数据量可控避免因一次性加载大数据导致内存耗尽出现 OOM 问题。对于前端也由于无需一次性渲染大量的数据而减少了内存崩溃的风险。
提升用户体验 分页查询由于单次查询的数据量少后端与前端可以快速的处理相关的数据。用户无需进行长时间的等待极大的提高了客户的体验。
原始的实现方式 如果不使用分页查询相关的插件需要我们自己计算分页查询的偏移量offset还需要手动查询结果集以及数据总条数并且在相关的 Mapper.xml 中定义分页查询的 SQL 语句。主要实现步骤如下
计算偏移量 手动分页查询需要我们通过在 SQL 语句中添加分页相关的语法来实现例如在 MySQL 中的语法
SELECT * FROM users LIMIT #{pageSize} offset #{offset};其中#{offset} 表示偏移量但是前端的分页查询请求中一般只有查询第几页 page 和每页的大小 pageSize。需要我们先计算一下偏移量是多少。 需要注意前端传的 page 是从 0 开始的还是从 1 开始的。
从 0 开始则 offset page * pageSize从 1 开始则 offset (page - 1) * pageSize
在Mapper接口中定义查询方法
/*** 分页查询结果集* param page* param offset* param name* param categoryId* param status* return*/
ListDishVO pageQuery(int page, int offset, String name, Integer categoryId, Integer status);/*** 查询总条数* return*/
int getTotalSize();编写SQL语句
mapper namespacecom.sky.mapper.DishMapperinsert idinsert useGeneratedKeystrue keyPropertyidinsert into dish (name, category_id, price, image, description, status, create_time, update_time, create_user, update_user)values (#{name}, #{categoryId}, #{price}, #{image}, #{description},#{status}, #{createTime}, #{updateTime}, #{createUser}, #{updateUser})/insertselect idpageQuery resultTypecom.sky.vo.DishVOselect d.*, c.name as categoryName from dish d left outer join category c on d.category_id c.idwhereif testname ! nulland d.name like concat(%, #{name}, %)/ifif testcategoryId ! nulland d.category_id #{categoryId}/ifif teststatus ! nulland d.status #{status}/if/whereorder by d.create_time desclimit #{page}offset #{offset}/selectselect idgetTotalSize resultTypejava.lang.Integerselect count(*) from dish;/select
/mapper开发流程及完整代码 在开发过程中 由外而内 进行开发效率会更高一些我们一般不需要先写 Mapper.xml 中的 SQL语句再定义Mapper接口中的方法然后再通过 Service类 中进行调用。 一般会从 Service类 开始写起然后再通过编辑器的快捷方式帮助我们生成相关的代码再一层一层的实现。
Controller层
GetMapping(/page)
ApiOperation(菜品分页查询)
public ResultPageResult pageQuery(DishPageQueryDTO dishPageQueryDTO) {log.info(菜品分页查询开始[{}], dishPageQueryDTO);return dishService.pageQuery(dishPageQueryDTO);
}Service实现类
Override
public ResultPageResult pageQuery(DishPageQueryDTO dishPageQueryDTO) {// 计算偏移量int offset (dishPageQueryDTO.getPage() - 1) * dishPageQueryDTO.getPageSize();// 查询当前页的数据ListDishVO dishVOList dishMapper.pageQuery(dishPageQueryDTO.getPageSize(), offset, dishPageQueryDTO.getName(),dishPageQueryDTO.getCategoryId(), dishPageQueryDTO.getStatus());// 查询数据库中的总条数int total dishMapper.getTotalSize();PageResult pageResult new PageResult();pageResult.setTotal(total);pageResult.setRecords(dishVOList);log.info(分页查询结果为[{}], pageResult);return Result.success(pageResult);
}Mapper接口方法
/*** 分页查询结果集* param page* param offset* param name* param categoryId* param status* return*/
ListDishVO pageQuery(int page, int offset, String name, Integer categoryId, Integer status);/*** 查询总条数* return*/
int getTotalSize();xml文件SQL
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.sky.mapper.DishMapperinsert idinsert useGeneratedKeystrue keyPropertyidinsert into dish (name, category_id, price, image, description, status, create_time, update_time, create_user, update_user)values (#{name}, #{categoryId}, #{price}, #{image}, #{description},#{status}, #{createTime}, #{updateTime}, #{createUser}, #{updateUser})/insertselect idpageQuery resultTypecom.sky.vo.DishVOselect d.*, c.name as categoryName from dish d left outer join category c on d.category_id c.idwhereif testname ! nulland d.name like concat(%, #{name}, %)/ifif testcategoryId ! nulland d.category_id #{categoryId}/ifif teststatus ! nulland d.status #{status}/if/whereorder by d.create_time desclimit #{page}offset #{offset}/selectselect idgetTotalSize resultTypejava.lang.Integerselect count(*) from dish;/select
/mapper
使用插件实现 使用分页插件可以极大的简化分页查询实现。虽然实现的主要原理还是通过原始实现方式中提到的逻辑但是通过分页插件我们就可以少写很多代码而且一般分页插件例如 PageHelper 会通过动态 SQL 的构建和优化能够有效避免传统分页方法的性能问题。 使用插件进行分页查询只需要修改一下上述原始实现方式的Service类 及 xml 文件中的 SQL 语句即可。
引入分页插件依赖
dependencygroupIdcom.github.pagehelper/groupIdartifactIdpagehelper-spring-boot-starter/artifactId
/dependencyService实现类
Override
public ResultPageResult pageQuery(DishPageQueryDTO dishPageQueryDTO) {PageHelper.startPage(dishPageQueryDTO.getPage(), dishPageQueryDTO.getPageSize());PageDishVO page dishMapper.pageHelperQuery(dishPageQueryDTO);PageResult pageResult new PageResult();pageResult.setTotal(page.getTotal());pageResult.setRecords(page.getResult());log.info(分页查询结果为[{}], pageResult);return Result.success(pageResult);}xml文件SQL
select idpageHelperQuery resultTypecom.sky.vo.DishVOselect d.*, c.name as categoryName from dish d left outer join category c on d.category_id c.idwhereif testname ! nulland d.name like concat(%, #{name}, %)/ifif testcategoryId ! nulland d.category_id #{categoryId}/ifif teststatus ! nulland d.status #{status}/if/whereorder by d.create_time desc
/select与原始分页的不同 使用分页插件进行分页不需要手动计算分页查询的偏移量在写SQL语句时也不需要显式地使用 LIMIT 和 OFFSET 来实现分页。而且分页插件也会直接将查询的结果集和总条数封装到 Page对象 中不需要我们手动的查询结果集和总条数。 mysql开启缓存、设置缓存大小、缓存过期机制PageHelper分页插件最新源码解读及使用苍穹外卖