大家好,我是老三,一个平平无奇的CRUD仔。

今天,我正在愉快地CRUD,突然发现出现一个Bug,我们来看看是怎么回事吧!

问题由来

一个简单的需求,要求把和当前用户相关的数据置顶展示。

这里,我用了一个简单的用户表来复现这个需求。

很简单,查询语句后面加上:order by t.login_name='wulaoer' desc 就行了。

如下所示,吴老二就到顶了。

那Mybatis脚本怎么写呢?

就这么写

    <select id="selectUserPageOrder" resultType="cn.fighter3.entity.User">
select * from user t
order by t.login_name=#{req.currentUser} desc
</select>

OK,需求完成,测试,摸……

嗯,出bug了……

问题现场

定晴一看控制台,报错了。

最关键的一行:

java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).

问题分析

问题很简单,随手一查,原因是:

  • #{}传过来的参数带单引号

#{}采用预编译机制,是占位符,#{}传入参数是以字符串传入,会将SQL中的#{}替换为?号,调用PreparedStatement的set方法来赋值。

这种方式,order by 最后的sql会多加单引号 ' 。

那怎么解决呢?

可以用 ${}${}是拼接符,直接字符串替换。

    <select id="selectUserPageOrder" resultType="cn.fighter3.entity.User">
select * from user t
order by t.login_name=${req.currentUser} desc
</select>

我不想用${}这种方式,因为有sql注入的风险,那该怎么办呢?

好吧,其实主要是这种方式也报错了。

java.sql.SQLSyntaxErrorException: Unknown column 'wulaoer' in 'order clause'

我们平时模糊查询怎么写呢?

——使用CONCAT()函数来拼接keyword。

以此类推,那我用一个函数来去掉'不就行了。

那用一个什么函数呢?

——REPLACE

所以写法就变成了这样:

    <select id="selectUserPageOrder" resultType="cn.fighter3.entity.User">
select * from user t
order by t.login_name=REPLACE(#{req.currentUser},'\'','') desc
</select>

问题解决

OK,最终问题解决。

    <select id="selectUserPageOrder" resultType="cn.fighter3.entity.User">
select * from user t
order by t.login_name=REPLACE(#{req.currentUser},'\'','') desc
</select>

上去吧,吴老二!


问题比较简单,处理起来也是三下五除二,但是分析的过程还有点意思,所以发出来给大家瞧瞧。

PS:有读者朋友催更SringCloud Alibaba实战系列,抱歉,最近加班、刷题,只能暂时停更。不过大家不要担心没得学,我的朋友Jam哥已经更了三十几篇高质量教程,百度搜Java日知录,快乐继续。

“简单的事情重复做,重复的事情认真做,认真的事情有创造性地做。”——

我是三分恶,一个能文能武的全栈开发!

点赞关注不迷路,咱们下期见!

Mybatis order by 动态传参出现的一个小bug的更多相关文章

  1. MyBatis dao层 方法传参

    MyBatis dao层 方法传参有三种方法. 1. 以下标的方法获取参数. <update id="insertSuccessKilled">       INSER ...

  2. js函数动态传参

    js函数体内可以通过arguments对象来接收传递进来的参数,利用这一对象属性可以动态传参. function box() { return arguments[0]+' | '+arguments ...

  3. uploadify的用法与动态传参 提供demo下载

    ---恢复内容开始--- 官网:http://www.uploadify.com/   一款不错的上传插件.官方文档http://www.uploadify.com/documentation/ 用法 ...

  4. Postman 串行传参和动态传参详解

    Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件 用Postman做接口测试的时候,要把多条用例一起执行,就需要把用例连接起来,一次性执行 目录 串行传参 动态传参 使用 ...

  5. python之路--动态传参,作用域,函数嵌套

    一 . 动态传参(重点)  * ,  ** * 与 ** * 在形参位置. * 表示不定参数, 接收的是位置参数 接收到的位置参数的动态传参: 都是元组 def eat(*food): # 在形参这里 ...

  6. python----函数的动态传参

    函数的动态传参 *args 将所有的实参的位置参数聚合到一个元组,并将这个元组赋值给args 有些时候,对于函数,传入的实参数量可能是不固定的,也就是动态的,这个时候我们就需要用到函数的动态传参.下面 ...

  7. 在Java中动态传参调用Python脚本

    最近,又接触到一个奇葩的接口,基于老板不断催促赶时间的情况下,在重写java接口和复用已有的python脚本的两条路中选择了后者,但是其实后者并没有好很多,因为我是一个对python的认识仅限于其名称 ...

  8. python函数的动态传参.作用域与命名空间

    一.动态传参1.*表示动态传参. 可以接受所有的位置参数传参的时候自动的把实参打包成元组 交给形参 def chi(*food): print(food) chi() # 动态传参可以不传参数 chi ...

  9. python记录_day10 动态传参 命名空间 作用域

    一.动态传参 动态传参用到 *args 和 **kwargs ,*号表示接收位置参数,args是参数名:**表示接收关键字参数,kwargs是参数名 def chi(*food): print(foo ...

随机推荐

  1. NVIDIA Nsight Systems CUDA 跟踪

    NVIDIA Nsight Systems CUDA 跟踪 CUDA跟踪 NVIDIA Nsight Systems能够捕获有关在概要过程中执行CUDA的信息. 可以在报告的时间轴上收集和呈现以下信息 ...

  2. 解决redis集群版本不一致导致RDB同步失败的问题

    某天,运维反馈某两个机房的出口流量和入口流量过大,并且持续了好一段时间. 再仔细排查后发现是 redis 集群的几台服流量问题,于是开始查日志. 在日志中发现出现大量的 Can't handle RD ...

  3. Pandas高级教程之:Dataframe的合并

    目录 简介 使用concat 使用append 使用merge 使用join 覆盖数据 简介 Pandas提供了很多合并Series和Dataframe的强大的功能,通过这些功能可以方便的进行数据分析 ...

  4. 【逆向&编程实战】Metasploit中的安卓载荷凭什么吊打SpyNote成为安卓端最强远控

    文章作者:MG1937 QQ:3496925334 CNBLOG:ALDYS4 未经许可,禁止转载 前言 说起SpyNote大家自然不陌生,这款恶意远控软件被利用在各种攻击场景中 甚至是最近也捕获到了 ...

  5. YoyoGo v1.7.2 发布, 支持 Nacos & Apollo 配置中心

    YoyoGo (Go语言框架)一个简单.轻量.快速.基于依赖注入的微服务框架( web .grpc ),支持Nacos/Consoul/Etcd/Eureka/k8s /Apollo等 . https ...

  6. Java后端精选技术:SpringBoot配置读取

    在早前的博客中曾经写过 Spring 程序通过 Bean 映射实现配置信息的读取. 在SpringBoot 框架中读取配置的方式变得非常多样,这导致读者在搜寻资料时反而容易迷糊. 到底,SpringB ...

  7. 孟老板 ListAdapter封装, 告别Adapter代码 (四)

    BaseAdapter系列 ListAdapter封装, 告别Adapter代码 (一) ListAdapter封装, 告别Adapter代码 (二) ListAdapter封装, 告别Adapter ...

  8. [Linux]经典面试题 - 系统管理 - 备份策略

    [Linux]经典面试题 - 系统管理 - 备份策略 目录 [Linux]经典面试题 - 系统管理 - 备份策略 一.备份目录 1.1 系统目录 1.2 服务目录 二.备份策略 2.1 完整备份 2. ...

  9. 百炼3752:走迷宫--栈实现dfs

    3752:走迷宫 总时间限制:  1000ms 内存限制:  65536kB 描述 一个迷宫由R行C列格子组成,有的格子里有障碍物,不能走:有的格子是空地,可以走.给定一个迷宫,求从左上角走到右下角最 ...

  10. Linux-NFS存储

    1.什么是NFS NFS是Network File System 的缩写,中文意思是网络文件共享系统,它的主要功能是通过网络(一般是局域网)让不同的主机系统之间可以共享文件或目录. 2.NFS存储服务 ...