PageHelper自定义Count查询及其优化

PageHelper自定义Count查询及其优化

文章目录

  • PageHelper自定义Count查询及其优化
    • 一:背景
      • 1.1、解决方法
    • 二:利用反射判断请求参数是否有模糊查询
      • 2.1、分页不执行count
      • 2.2、思路
      • 2.3、代码示例
    • 三:自定义COUNT查询SQL(只适用于单表)
      • 3.1、局限性
      • 3.2、使用方式
    • 四:各种模糊查询XML中示例

一:背景

PageHelper默认情况下会帮我们根据查询语句自动生成COUNT查询SQL,但是有些情况下,PageHelper自动生成COUNT查询SQL存在效率问题。比如,其中使用了GROUP BY语句,多表关联,生成的COUNT查询SQL查询效率很慢

1.1、解决方法

1.count()有优化空间的直接优化,Count执行条件慢无外乎索引是否命中,执行SQL是否多表关联

2.count()没办法优化的,只能从业务入手,取消关联的一些条件查询

3.不返回count总条数,只能一页一页往下翻

4.缓存总条数,实时性保证不保证

5.异步查询加载,前端后端一起优化

也就是点击一次请求查询两个接口,list接口肯定很快返回,可以直接进行列展示,供用户操作查看等;
count接口返回较慢,分页插件下面展示loading(提示正在加载),异步执行完成后告诉前端

6.彻底解决:引入ES或其他数据库

7.代码层面:投机取巧(二:利用反射判断请求参数是否有模糊查询)

每次请求分页接口,没有任何条件查询的时候,count会计算总条数,数据量大时非常耗时;但是模糊查询的话,速度还可以接受;是否有一种方法可以:如果只是有pageIndex和pageSize参数的时候,我用自定义的count;如果有其他模糊条件查询的时候,我选择pageHelper自带的count,执行原有复杂SQL语句,维持count准确性

二:利用反射判断请求参数是否有模糊查询

2.1、分页不执行count

PageHelper.startPage(req.getCurPage(), req.getPageSize(),false);
如果将此参数设置为false,pageHlper不执行count方法;

2.2、思路

1.只有分页参数--》不执行默认count方法,设置为false--》自定义count--》返回自定义count总条数2.有模糊查询分页参数--》执行默认count方法,设置为true--》pageHelper自带count--》count参数pageHelper会返回

2.3、代码示例

 // 定义一个私有静态列表来存储需要忽略的字段名称,填写当前类的字段private static final List<String> IGNORED_FIELDS = Arrays.asList("curPage", "pageSize");//用作分页count选择,如果原始分页,选择全表差,反之用条件查public boolean areAllFieldsEmptyExceptIgnored() {//获取父类的字段//Field[] declaredFields = this.getClass().getSuperclass().getDeclaredFields();//只获取了当前类的字段for (Field field : this.getClass().getDeclaredFields()) {// 忽略静态字段和transient字段if (java.lang.reflect.Modifier.isStatic(field.getModifiers()) ||java.lang.reflect.Modifier.isTransient(field.getModifiers())) {continue;}// 忽略配置列表中的字段if (IGNORED_FIELDS.contains(field.getName())) {continue;}// 确保私有字段也可以访问field.setAccessible(true);try {// 获取字段值Object value = field.get(this);//检查字段值是否为空// 检查字段值是否为空if (value instanceof String && ((String) value).isEmpty()) {//字段为空字符串,这是允许的,继续检查下一个字段continue;} else if (value instanceof String) {// 字段为非空字符串return false;} else if (value instanceof List && ((List<?>) value).isEmpty()) {// 字段为非空列表,这是允许的,继续检查下一个字段continue;}else if (value instanceof List) {//字段为非空集合return false;}  else if (value != null) {//字段为非空对象return false;}} catch (IllegalAccessException e) {// 处理可能的非法访问异常throw new RuntimeException("Error accessing field: " + field.getName(), e);}}//所有字段都是空的return true;}

这段反射说明:如果只有分页参数,会返回true;如果有模糊查询参数,会返回false;需要忽略的字段,支持自己设置

        boolean status = req.areAllFieldsEmptyExceptIgnored();PageHelper.startPage(req.getCurPage(), req.getPageSize(),!status);List<GoodsSpu> resultList =goodsSpuMapper.goodsSpuList(daoReq);PageInfo<GoodsSpu> pageInfo = new PageInfo<>(resultList);if (status) {//count全查pageInfo.setTotal(goodsSpuMapper.goodsSpuListCount(daoReq));}else{//count条件查,走默认分页的count}
<select id="goodsSpuList" parameterType="com.kkd.goods.model.in.GoodsSpuListDaoReq" resultType="com.kkd.goods.entity.GoodsSpu">select DISTINCT r.id dis_id,r.* from(select gsp.* from gd_goods_spu gspLEFT JOIN gd_goods_sku gsk on gsp.spu=gsk.spuLEFT JOIN gd_goods_sku_upc gsu on gsp.spu=gsu.spuLEFT JOIN gd_goods_shop_category_relation gscr on gsp.spu=gscr.spuwheregsp.is_delete=0and gsp.org_id=#{orgId}<if test="name != null and name != '' ">and gsp.`name`like concat('%',#{name},'%')</if><if test="spuList != null and spuList.size > 0">AND  gsp.spu IN<foreach item="id" index="index" collection="spuList" open="(" separator="," close=")">#{id}</foreach></if><if test="skuList != null and skuList.size > 0">AND  gsk.sku IN<foreach item="id" index="index" collection="skuList" open="(" separator="," close=")">#{id}</foreach></if><if test="upcList != null and upcList.size > 0">AND  gsu.upc IN<foreach item="id" index="index" collection="upcList" open="(" separator="," close=")">#{id}</foreach></if><if test="categoryCodes != null and categoryCodes.size > 0">AND  gsp.category_code IN<foreach item="id" index="index" collection="categoryCodes" open="(" separator="," close=")">#{id}</foreach></if><if test="shopCategoryIds != null and shopCategoryIds.size > 0">AND  gscr.shop_category_id IN<foreach item="id" index="index" collection="shopCategoryIds" open="(" separator="," close=")">#{id}</foreach></if><if test="ePlatformCategoryId != null">and gsp.e_platform_category_id=#{ePlatformCategoryId}</if><if test="isNormal != null">and gsp.normal=#{isNormal}</if><if test="imageEmpty != null  and imageEmpty == 1 ">and gsp.images is null</if><if test="isMaster != null ">and gsp.`master` = #{isMaster}</if><if test="masterSpu != null and masterSpu !='' ">and gsp.`master_spu` = #{masterSpu}</if>ORDER BY gsp.update_time desc) r
</select>
<select id="goodsSpuListCount" resultType="java.lang.Long" parameterType="com.kkd.goods.model.in.GoodsSpuListDaoReq">select count(*) from gd_goods_spu gspwheregsp.is_delete=0and gsp.org_id=#{orgId}
</select>

三:自定义COUNT查询SQL(只适用于单表)

3.1、局限性

1.对于单表查询:分页执行的sql执行效率都慢,count执行的时候首先考虑命中索引,如果拆分出来效率能得到提升再用
2.对于多表查询:如果查询条件仅仅只是主表中的条件,此方法适用如果查询条件需要从表中的条件,自定义的这个count就不满足
3.缓存count,业务上总数实时性要求不高,或者总数变化不快的情况下可以使用
<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.0.4</version>
</dependency>

image-20241209165918906

3.2、使用方式

原有的代码不需要动,只需要在Mybatis的xml文件里添加一个count查询
这里注意以下三点即可:

  1. id和对应的查询语句保持一致,并且以 _COUNT 结尾
  2. 入参和对应的查询语句保持一致
  3. 出参为 resultType=“Long”
<select id="goodsSpuList_COUNT" parameterType="com.kkd.goods.model.in.GoodsSpuListDaoReq" resultType="java.lang.Long">select count(*)from gd_goods_spu gspwhere gsp.is_delete = 0and gsp.org_id = #{orgId}
</select>

四:各种模糊查询XML中示例

    <select id="goodsSpuList" parameterType="com.kkd.goods.model.in.GoodsSpuListDaoReq" resultType="com.kkd.goods.entity.GoodsSpu">select DISTINCT r.id dis_id,r.* from(select gsp.* from gd_goods_spu gspLEFT JOIN gd_goods_sku gsk on gsp.spu=gsk.spuLEFT JOIN gd_goods_sku_upc gsu on gsp.spu=gsu.spuLEFT JOIN gd_goods_shop_category_relation gscr on gsp.spu=gscr.spuwheregsp.is_delete=0and gsp.org_id=#{orgId}<if test="name != null and name != '' ">and gsp.`name`like concat('%',#{name},'%')</if><if test="spuList != null and spuList.size > 0">AND  gsp.spu IN<foreach item="id" index="index" collection="spuList" open="(" separator="," close=")">#{id}</foreach></if><if test="skuList != null and skuList.size > 0">AND  gsk.sku IN<foreach item="id" index="index" collection="skuList" open="(" separator="," close=")">#{id}</foreach></if><if test="upcList != null and upcList.size > 0">AND  gsu.upc IN<foreach item="id" index="index" collection="upcList" open="(" separator="," close=")">#{id}</foreach></if><if test="categoryCodes != null and categoryCodes.size > 0">AND  gsp.category_code IN<foreach item="id" index="index" collection="categoryCodes" open="(" separator="," close=")">#{id}</foreach></if><if test="shopCategoryIds != null and shopCategoryIds.size > 0">AND  gscr.shop_category_id IN<foreach item="id" index="index" collection="shopCategoryIds" open="(" separator="," close=")">#{id}</foreach></if><if test="ePlatformCategoryId != null">and gsp.e_platform_category_id=#{ePlatformCategoryId}</if><if test="isNormal != null">and gsp.normal=#{isNormal}</if><if test="imageEmpty != null  and imageEmpty == 1 ">and gsp.images is null</if><if test="isMaster != null ">and gsp.`master` = #{isMaster}</if><if test="masterSpu != null and masterSpu !='' ">and gsp.`master_spu` = #{masterSpu}</if>ORDER BY gsp.update_time desc) r</select>

参考:Pagehelper自定义count查询

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/63820.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TPAMI 2023:When Object Detection Meets Knowledge Distillation: A Survey

摘要 目标检测&#xff08;Object Detection&#xff0c;OD&#xff09;是计算机视觉中的一项关键任务&#xff0c;多年来涌现出了众多算法和模型。尽管当前 OD 模型的性能有所提升&#xff0c;但它们也变得更加复杂&#xff0c;由于参数规模庞大&#xff0c;在工业应用中并不…

ZED相机应用

下载SDK wget https://stereolabs.sfo2.cdn.digitaloceanspaces.com/zedsdk/3.6/ZED_SDK_Ubuntu18_cuda11.5_v3.6.5.run 安装 ./ZED_SDK_Ubuntu18_cuda11.5_v3.6.5.run skip_python 测试 cd /usr/local/zed/tools ls ZED_Calibration ZED_Depth_Viewer ZED_Diagnostic ZED_E…

农业园区气象站

农业园区气象站是一种专为农业生产和科研设计的气象监测设备&#xff0c;它集成了多种传感器和技术&#xff0c;用于实时、准确地监测和记录农业园区内的气象数据。以下是农业园区气象站的主要功能和用处&#xff1a; 一、主要功能 实时监测&#xff1a;农业园区气象站能够实时…

Unity3D项目为什么要使用FairyGUI

前言 Unity3D项目选择使用FairyGUI的原因是多方面的&#xff0c;主要涵盖性能优化、设计模式、编辑器支持、跨平台兼容性以及丰富的功能特性。以下是对这些方面的详细解析以及相关的代码实现。 对惹&#xff0c;这里有一个游戏开发交流小组&#xff0c;希望大家可以点击进来一…

编译问题 fatal error: rpc/rpc.h: No such file or directory

在编译一些第三方软件的时候&#xff0c;会经常遇到一些文件识别不到的问题&#xff0c;这里整理下做个归总。 目前可能的原因有&#xff08;排序分先后&#xff09;&#xff1a; 文件不存在&#xff1b;文件存在但路径识别不了&#xff1b;…… 这次以常见的编译lmbench测试…

设计模式的艺术读书笔记

设计模式的艺术 面向对象设计原则概述单一职责原则开闭原则里氏代换原则依赖倒转原则接口隔离原则合成复用原则迪米特法则 创建的艺术创建型模式单例模式饿汉式单例与懒汉式单例的讨论通过静态内部类实现的更好办法 简单工厂模式工厂方法模式重载的工厂方法工厂方法的隐藏工厂方…

Spring Boot中使用YAML配置文件

1. YAML 文件结构和语法 缩进与层次 YAML使用缩进来表示层级关系。每个层级的元素必须比它的父级多一个空格或Tab&#xff08;推荐使用空格&#xff09;。例如&#xff1a; server:port: 8080address: localhost 列表与映射 列表用 - 开头&#xff0c;映射则用 key: value…

python模拟练习第一期

问题一 如果一个数 p 是个质数&#xff0c;同时又是整数 a的约数&#xff0c;则 p 称为 a的一个质因数。 请问 2024 有多少个质因数&#xff1f; 步骤 1: 分解 2024 首先&#xff0c;2024 是偶数&#xff0c;说明可以被 2 整除。我们从 2 开始进行除法分解&#xff1a; 202…

element-plus的el-tree的双向绑定

el-tree改造了下 可选可取消 有默认值 不包含父级id&#xff08;也可打开注释 包含父级id&#xff09; 默认展开 点击节点也可触发选择 节点内容自定义 <template><div class"absolute"><el-scrollbar class"pall"><div class"…

【iOS】OC高级编程 iOS多线程与内存管理阅读笔记——自动引用计数(三)

目录 ARC规则 概要 所有权修饰符 __strong修饰符 __weak修饰符 __unsafe_unretained修饰符 __autoreleasing修饰符 ARC规则 概要 “引用计数式内存管理”的本质部分在ARC中并没有改变&#xff0c;ARC只是自动地帮助我们处理“引用计数”的相关部分。 在编译单位上可以…

MySQL-DQL之数据多表操作

文章目录 一. 多表操作1. 表与表之间的关系2. 外键约束3. 创建外键约束表(一对多操作) 二. 多表查询1. 多表查询① 交叉连接查询(基本不会使用-得到的是两个表的乘积) [了解]&#xff08;不要记住&#xff09;② 交集运算&#xff1a;内连接查询(join)③ 差集运算&#xff1a;外…

《经验分享 · 软考系统分析师》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

宝塔面板Linux版本常用命令

宝塔面板&#xff08;BT Panel&#xff09;是一款简单易用的服务器管理工具&#xff0c;广泛应用于Linux服务器的管理。尽管宝塔提供了图形化界面&#xff0c;但在某些情况下&#xff0c;使用命令行操作更加高效。以下是宝塔面板Linux版本常用的命令&#xff0c;包括安装、管理…

ElasticSearch - 理解doc Values与Inverted Index倒排索引

文章目录 概述倒排索引&#xff1a;从图书馆的索引卡片谈起倒排索引的工作原理 docValues&#xff1a;从数据库的列式存储说起docValues的工作原理 docValues与倒排索引的对比两者的联系&#xff1a;组合使用&#xff0c;优化搜索与分析 小结 概述 在使用 Elasticsearch 进行大…

2.【每日算法】

1. NC140 排序 题目连接 快排 #include <vector> class Solution { public:/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可** 将给定数组排序* param arr int整型vector 待排序的数组* return int整型vector*/v…

Acer宏碁Swift3笔记本S40-20,SF314-56G原厂Win10系统工厂模式安装包,带Recovery恢复还原

适用电脑型号&#xff1a;S40-20、SF314-56、SF314-56G(原装OEM预装系统) 链接&#xff1a;https://pan.baidu.com/s/1q77Br-hcmn9iJraGVVKQ7Q?pwdrw1r 提取码&#xff1a;rw1r Acer宏碁原装出厂windows10系统自带所有驱动、Office办公软件、出厂主题壁纸、系统属性专属联…

人工智能|自然语言处理——机器翻译评价指标Bleu和Rouge

在机器翻译任务中&#xff0c;BLEU 和 ROUGE 是两个常用的评价指标&#xff0c;BLEU 根据精确率(Precision)衡量翻译的质量&#xff0c;而 ROUGE 根据召回率(Recall)衡量翻译的质量 BLEU&#xff08;Bilingual Evaluation Understudy&#xff09;&#xff1a; BLEU是一种用于评…

Python跳动的爱心

系列文章 序号直达链接表白系列1Python制作一个无法拒绝的表白界面2Python满屏飘字表白代码3Python无限弹窗满屏表白代码4Python李峋同款可写字版跳动的爱心5Python流星雨代码6Python漂浮爱心代码7Python爱心光波代码8Python普通的玫瑰花代码9Python炫酷的玫瑰花代码10Python多…

极验决策引擎如何凭借独特优势,弯道超车传统风控?

前言 市场上的规则决策引擎产品众多&#xff0c;但大多局限于IP、设备、账号等层面&#xff0c;提供的是现成的风控标签和规则。然而&#xff0c;真正的风控&#xff0c;需要的不仅仅是标签和规则。 极验的业务规则决策引擎与众不同&#xff0c;这款决策引擎以界面流程编排为…

windows如何使用ssh连接kali

声明&#xff1a; 昨天晚上看了小羽老师的直播课&#xff0c;心血来潮自己也想搞一下这个ssh&#xff0c;中途安装遇到了不少问题&#xff0c;电脑也是重启了好多次&#xff0c;遇到bug就重启也是解决bug的一种方法. 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&…