MybatisPlus使用排序查询时,将null值放到最后

1用户需求

查询结果,按照某些字段进行排序,将为null的值放到最后。按照更新时间排序,但是更新时间可能为null,因此将null的数据放到最后。

2解决方案

最简单的方式,当然是下面这种直接在SQL最后面 NULLS LAST ,但是问题是,我都用MybatisPlus,下面的这种SQL那肯定不会写了啊,要是用MybatisPlus还写下面这种单表SQL的查询的,我建议可以放弃MybatisPlus了

SELECT * FROM users ORDER BY OPERATE_DATE ASC NULLS LAST 

先说最终解决方案,用mybatis拦截器修改最终执行的sql语句

思路就是将queryWrapper构造的SQL语句中的ASC替换成ASC NULLS LAST即使用queryWrapper的orderBy时,mybatis-plus会生成这个SQL语句
SELECT * FROM users ORDER BY OPERATE_DATE ASC而我们要做的就是在mybatis-plus执行之前,将ASC变成 ASC NULLS LAST 

下面是我们进行排序的代码。目前来看,我们只能改这里,不过查找了一圈,都没有解决方案,因此放弃,用另外拦截器的方式实现。

if(!ObjectUtils.isEmpty(orderBy)) {if(orderBy instanceof Collection) {String[] array = ((Collection<?>) orderBy).toArray(new String[0]);queryWrapper.orderBy(true, isAsc, Arrays.asList(array));}else {queryWrapper.orderBy(true, isAsc, orderBy.toString());}
}

当然GPT一本正经的胡说八道,看着挺像回事的,可惜mybait-plus没有这个方法,所以看看就好。

orderByAscWithNullsLast()

在这里插入图片描述

3拦截器代码

这里开始,就是最后的代码实现了

3.1编写拦截器LastNullInterceptor

import java.lang.reflect.Field;
import java.sql.Connection;import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.mapping.StatementType;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.springframework.util.ReflectionUtils;import com.baomidou.mybatisplus.core.toolkit.PluginUtils;/*** @description:拦截查询SQL,处理查询SQL中的排序* @author:hutao* @mail:hutao_2017@aliyun.com* @date:2023年7月25日 下午12:17:50*/
@Intercepts(@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}))
public class LastNullInterceptor implements Interceptor {//,有兴趣,可以看看MybatisPlusInterceptor怎么实现的private static final String DESC = "DESC";private static final String ASC = "ASC";private static final String REPLACE_DESC = "DESC NULLS LAST";private static final String REPLACE_ASC = "ASC NULLS LAST";@Overridepublic Object intercept(Invocation invocation) throws Throwable {StatementHandler handler = PluginUtils.realTarget(invocation.getTarget());MetaObject metaObject = SystemMetaObject.forObject(handler);// 判断是不是SELECT操作,跳过存储过程MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");if (SqlCommandType.SELECT != mappedStatement.getSqlCommandType()|| StatementType.CALLABLE == mappedStatement.getStatementType()) {return invocation.proceed();}BoundSql boundSql = handler.getBoundSql();String sql = boundSql.getSql().toUpperCase();if(sql.contains("ORDER BY")) {sql = this.replaceLast(sql, DESC, REPLACE_DESC);sql = this.replaceLast(sql, ASC, REPLACE_ASC);Field sqlField = boundSql.getClass().getDeclaredField("sql");ReflectionUtils.makeAccessible(sqlField);ReflectionUtils.setField(sqlField, boundSql, sql);}return invocation.proceed();}/*** @description:替换最后一个字符串* @author:hutao* @mail:hutao1@epri.sgcc.com.cn* @date:2023年7月25日 下午2:22:21*/public String replaceLast(String str, String target, String replacement) {if (str == null || target == null || replacement == null) {return str;}int lastIndex = str.lastIndexOf(target);if (lastIndex < 0) {return str;}return str.substring(0, lastIndex) + replacement + str.substring(lastIndex + target.length());}
}

3.2注入拦截器

@SpringBootConfiguration
public class MybatisConfig {@Beanpublic LastNullInterceptor nullsLastInterceptor() {return new LastNullInterceptor();}
}

4结果展示

打印mybatis-plus的sql,我们可以发现,已经将ASC替换成 ASC NULLS LAST了
在这里插入图片描述

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

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

相关文章

502 Bad GateWay报错的解决方法

什么是502 bad gateway 报错 简单来说 502 是报错类型代码 bad gateway 错误的网关。是Web服务器作为网关或代理服务器时收到无效的响应。 用我们的口语说就是运行网站的服务器暂时挂了(不响应)。 产生错误的原因 1.连接超时 我们向服务器发送请求 由于服务器当前链接太多&am…

自然语言处理从入门到应用——LangChain:模型(Models)-[大型语言模型(LLMs):基础知识]

分类目录&#xff1a;《自然语言处理从入门到应用》总目录 大型语言模型&#xff08;LLMs&#xff09;是LangChain的核心组件。LangChain不提供大型语言模型&#xff0c;而是提供了一个标准接口&#xff0c;通过该接口我们可以与各种LLMs进行交互。LLM类是专为与LLM接口设计的类…

89、简述RabbitMQ的架构设计

简述RabbitMQ的架构设计 BrokerQueueExchangeRoutingKeyBinding信道架构设计图 Broker RabbitMQ的服务节点 Queue 队列&#xff0c;是RabbitMQ的内部对象&#xff0c;用于存储消息。RabbitMQ中消息只能存储在队列中。生产者投递消息到队列&#xff0c;消费者从队列中获取消息…

python:使用CNN神经网络实现CSV数据分类预测

作者:CSDN @ _养乐多_ 本文记录了一个使用Keras构建和训练卷积神经网络(CNN)的示例。这个CNN模型用于分类任务,并且训练样本数据集来自一个CSV文件。我们的目标是根据输入特征将样本分为不同的类别。 这个代码可以在遥感领域的多个方向进行应用,其中一些常见的应用方向包…

科技与人元宇宙论坛跨界对话

近来&#xff0c;“元宇宙”成为热门话题&#xff0c;越来越频繁地出现在人们的视野里。大家都在谈论它&#xff0c;但似 乎还没有一个被所有人认同的定义。元宇宙究竟是什么&#xff1f;未来它会对我们的工作和生活带来什么样 的改变&#xff1f;当谈论虚拟现实&#xff08;VR…

ES6基础知识五:你是怎么理解ES6新增Set、Map两种数据结构的?

如果要用一句来描述&#xff0c;我们可以说 Set是一种叫做集合的数据结构&#xff0c;Map是一种叫做字典的数据结构 什么是集合&#xff1f;什么又是字典&#xff1f; 集合 是由一堆无序的、相关联的&#xff0c;且不重复的内存结构【数学中称为元素】组成的组合 字典 是…

python-将矩阵转化成一列

在进行实际的案例开发过程中&#xff0c;我们经常用到矩阵、数组&#xff0c;而对于这两者学习变得至关重要。在学习矩阵及相关数组的操作过程中&#xff0c;不像matlab那么方便直接操作就可以了&#xff0c;而是需要进行导库才可以进行操作&#xff0c;python主要的学习数组和…

vue2生命周期图

生命周期全过程如下&#x1f447;详解 一:生命周期之创建阶段 1.创建一个Vue实例【new Vue()】 2.初始化Vue实例,第一次初始化,初始化Vue当中的事件和生命周期方法【Init Events Lifecycle】 ☆☆☆调用生命周期方法当中的beforCreate,调用这个方法的时候有一个特点,就是在调…

Matlab中实现对一幅图上的局部区域进行放大

大家好&#xff0c;我是带我去滑雪&#xff01; 局部放大图可以展示图像中的细节信息&#xff0c;使图像更加直观和精美&#xff0c;此次使用magnify工具实现对绘制的figure选择区域绘制&#xff0c;图像效果如下&#xff1a; 1、基本图像绘制 这里选择绘制一个散点图&#xff…

mysql中的‘\G’ ‘\g’ ‘;’ navicat dbeaver

省流&#xff1a; 在navicat、dbeaver等客户端中使用时&#xff0c;“\G”、“\g”、“;”都可以不需要。 “\G”、“\g”、“;”都是用来做sql的结束符用。“\g”、“;”作用完全等价。“\G”是将字段横排显示转换成纵列显示。 横排显示&#xff1a; id |e…

前端:运用html+css+js模仿百度热搜电影榜鼠标移入特效

前端:运用htmlcssjs模仿百度热搜电影榜鼠标移入特效 1. 实现原理2. 界面布局3. js实现对鼠标移入和移出的监听4. 参考代码如下&#xff1a; 1. 实现原理 百度热搜上电影榜鼠标移入特效如上图所示。个人觉得上述特效实现原理为使用相对定位、绝对定位实现的(鼠标移入和没有移入…

自己实现SpringMVC 底层机制[二]

文章目录 自己实现SpringMVC 底层机制[二]实现任务阶段3- 从web.xml 动态获取myspringmvc.xml分图析示意代码实现 实现任务阶段4- 完成自定义Service 注解功能。分析示意图代码实现完成测试(启动Tomcat, 自动加载MyDispatcherServlet, 完成IOC 容器的注入)。 自己实现SpringMVC…

springboot集成logback按日志级别按天保存

演示结果 集成logback后项目启动控制台不会有日志输出 生成的日志文件路径windows上是默认D盘,linux上可自定义 代码实现 pom.xml <dependency><groupId>ch.qos.logback</groupId>

C# Modbus通信从入门到精通(21)——Modbus TCP协议原理

Modbus TCP是走网口的&#xff0c;也可以在同一时间内有多个从站访问主站&#xff0c;并且通过Modbus事务处理标识来区分同一时刻的不同Modbus事务&#xff0c;这是区别于Modbus ASCII和Modbus RTU的地方。 1、访问模式&#xff1a; Modbus客户端通常输入Modbus服务器的IP地址…

简单模拟Mybatis通过注解查询SQL

通过自定义注解&#xff0c;简单模拟Mybatis通过注解查询SQL。 首先&#xff0c;创建自定义注解MyDao和MySelect。 MyDao.java Target({ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) public interface MyDao {String[] value() default {}; }MySelect.java Targ…

AI面试官:LINQ和Lambda表达式(一)

AI面试官&#xff1a;LINQ和Lambda表达式&#xff08;一&#xff09; 当面试官面对C#中关于LINQ和Lambda表达式的面试题时&#xff0c;通常会涉及这两个主题的基本概念、用法、实际应用以及与其他相关技术的对比等。以下是一些可能的面试题目&#xff0c;附带简要解答和相关案…

HTML <option> 标签

实例 创建带有 4 个选项的选择列表: <select><option value ="volvo">Volvo</option><option value ="saab">Saab</option><option value="opel">Opel</option><option value="audi"…

Server - 调用 K8S 集群 GPU 环境运行算法脚本

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://blog.csdn.net/caroline_wendy/article/details/131899662 Kubeflow 是基于 Kubernetes 的机器学习工具包&#xff0c;提供了一套技术栈&#xff0c;包含了很多组件&#xff0c;用于支持…

使用RestTemplate访问内部服务时返回的json字符串未做转换处理之后再次返回json字符到前台导致json字符串无法解析的解决办法

1. 以下是使用RestTemplate调用接口的方法 RequestMapping("/getQrList") //获取qrlable列表String getQrList(Qr qr) {//返回的数据本身就是 ResponBody也就是json&#xff0c;当前方法再次返回json&#xff0c;就会导致导出时无法解析数据&#xff08;table是能…

SQL SERVER安装

其中服务器名称输入./自己本机电脑名称. nchar类型一个单位可以放一个汉字-------长度短的补空格一个字节8位一个汉字两个字节 char类型两个单位可以放一个汉字 nvarchar类型是可变长度-----------长度短不会补空格 varchar类型是可变长度两个单位可以放一个汉字---------…