Mybatis order by 动态传参出现的问题及解决方法

问题由来

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

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

很简单,查询语句后面加上: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>

上去吧,吴老二!

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

到此这篇关于Mybatis order by 动态传参出现的一个小bug的文章就介绍到这了,更多相关Mybatis order by 动态传参出现的一个小bug内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • mybatis框架order by作为参数传入时失效的解决

    mybatis order by作为参数传入失效 mxl中的语句如下 <select id="statToday" resultType="com.dahua.la.business.model.vo.StatSysResultVO"> select a, b, count(1) as total from table where a is not null and b is not null and operateTime >= #{startT

  • 解决mybatis中order by排序无效问题

    1.#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号.如:order by #{user_id},如果传入的值是111,那么解析成sql时的值为order by "111", 如果传入的值是id,则解析成的sql为order by "id". 2.$将传入的数据直接显示生成在sql中.如:order by ${user_id},如果传入的值是111,那么解析成sql时的值为order by 111, 如果传入的值是id,则解析成的sql为order b

  • Mybatis中使用万能的Map传参实现

    在编程中,有可能遇到我们的实体类或者数据库中表的字段或参数过多的情况,那这时候用Map传参是比较理想的选择. Map的特性是键值对应的,只要确定了一个键key,那么值value可以是任何的数据,这样就可以在map内存中存入任何数据. 下面例子演示在mybatis中结合Map实现基本的增删改查 数据库表(fruits)结构: 实体类: package com.pojo.pp1; import java.math.BigDecimal; /** * 简述: *创建实体 * @author:LiYan

  • Mybatis的几种传参方式详解

    前言 前几天恰好面试一个应届生,问了一个很简单的问题:你了解过Mybatis中有几种传参方式吗? 没想到其他问题回答的很好,唯独这个问题一知半解,勉强回答了其中两种方式. 于是这篇文章就来说一说Mybatis传参的几种常见方式,给正在面试或者准备面试的朋友巩固一下. 单个参数 单个参数的传参比较简单,可以是任意形式的,比如#{a}.#{b}或者#{param1},但是为了开发规范,尽量使用和入参时一样. Mapper如下: UserInfo selectByUserId(String userI

  • Mybatis中#{}和${}传参的区别及#和$的区别小结

    最近在用mybatis,之前用过ibatis,总体来说差不多,不过还是遇到了不少问题,再次记录下, 比如说用#{},和 ${}传参的区别, 使用#传入参数是,sql语句解析是会加上"",比如 select * from table where name = #{name} ,传入的name为小李,那么最后打印出来的就是 select * from table where name = '小李',就是会当成字符串来解析,这样相比于$的好处是比较明显对的吧,#{}传参能防止sql注入,如果

  • 详解mybatis #{}和${}的区别、传参、基本语法

    1 #{}和${}的区别.及注入问题 (1) 区别: 首先清楚一点,动态 SQL 是 mybatis 的强大特性之一,在 mapper 中定义的参数传到 xml 中之后,在查询之前 mybatis 会对其进行动态解析,#{} 和 ${} 在预编译中的处理是不一样的: 例如:select * from t_user where userName = #{name}; #{}预编译:用一个占位符 ? 代替参数:select * from t_user where userName = ? #{}预编

  • Mybatis order by 动态传参出现的问题及解决方法

    问题由来 一个简单的需求,要求把和当前用户相关的数据置顶展示. 这里,我用了一个简单的用户表来复现这个需求. 很简单,查询语句后面加上:order by t.login_name='wulaoer' desc 就行了. 如下所示,吴老二就到顶了. 那Mybatis脚本怎么写呢? 就这么写

  • 微信小程序 动态传参实例详解

    微信小程序 动态传参实例详解 在微信小程序的开发过程中经常会用到动态传参,比如根据某一页面传参的不同,加载不同的新的页面.接下来介绍下如何实现. 上一篇博客中介绍了如何用wx:for循环显示数组,一般情况下我们要实现的功能是点击不同的元素进入不同的页面,比如在另一个页面加载某个元素的详细信息. 跳转这里采用navigator跳转,在navigator跳转的链接上将参数加上去: index.wxml(根据点击页面的不同传递参数) <view class="item" wx:for=

  • vue2 router 动态传参,多个参数的实例

    这个是用vue-cli生成的项目下使用 比如有个路由跳转时需要带两个参数: <router-link to='/tr'>查看</router-link> 可以这样写: <router-link to='/tr/uid/pid'>查看</router-link> 然后去router.js 中 处理这个路由: import Vue from 'vue' import Router from 'vue-router' import tr from '@/compo

  • 解决vue-router中的query动态传参问题

    最近在写项目,在写项目的过程会总发现这样或者那样的问题,比如说vue-router中的query如何传递动态的参数,经过了一些波折才解决了问题,问题描述如下: 希望跳转的时候url是这样的:http://localhost:8080/editmovie?id=**** <li><router-link :to="{path:'editmovie', query: {id : 111}}" class="edit">修改</router-

  • 使用python执行shell脚本 并动态传参 及subprocess的使用详解

    最近工作需求中 有遇到这个情况 在web端获取配置文件内容 及 往shell 脚本中动态传入参数 执行shell脚本这个有多种方法 最后还是选择了subprocess这个python标准库 subprocess这个模块可以非常方便的启动一个子进程,并且控制其输入和输出 Class Popen(args,bufsize = 0,executable=None, stdin =None,stdout =None,stderr =None, preexec_fn = None,close_fds =

  • vue 中的动态传参和query传参操作

    Vue router 如何传参 params.query 是什么? params:/router1/:id,这里的 id 叫做 params.例如/router1/123, /router1/789 query:/router1?id=123,这里的 id 叫做 query.例如/router1?id=456 query 方式传参和接收参数 传参: this.$router.push({ path:'/xxx' query:{ id:id } }) this.$router.push 传参时,

  • Docker如何给Springboot项目动态传参的实现方法

    背景 最近有些初学Docker的朋友问到,想通过docker-compose.yml来动态给微服务传参,而不是每次都要在项目配置文件硬编码,然后构建服务镜像,最后打包发布经过一些列流程才能更新配置,那能不能直接通过docker-compose.yml里把一些配置项放到环境变量,然后springboot项目自动从环境变量获取参数呢? 场景 假设现在有一个Springboot项目,它里面有一个数据库的配置项,但是不同的数据库测试环境(DEV\SIT\UAT),数据库ip有多个,想使用同一个Sprin

  • springboot通过spel结合aop实现动态传参的案例

    目录 前言 SpEl表达式简介 实例: SpEl结合AOP动态传参 小结 项目地址 前言 基于SpingBoot框架中, 我们随处可以见的便是各种各样的功能注解, 注解的实现原理AOP之前有说过(翻看本系列的前面几章即可), 这里不过多赘述. 那么, 你有没有碰到这样一种场景: 需要动态的传参数进注解, 注意是动态的而不是写死在代码里的. 针对这种需求, 今天, 我们就来实现一个简单的案例. SpEl表达式简介 正式撸代码之前, 先了解下SpEl (Spring Expression Langu

  • PHP闭包函数传参及使用外部变量的方法

    本文实例讲述了PHP闭包函数传参及使用外部变量的方法.分享给大家供大家参考,具体如下: 在Laravel控制器写两个方法,一个是在内部创建一个闭包函数,一个是执行传过来的闭包函数,测试闭包的写法,use使用外部变量,及闭包函数的传参.如下: //测试闭包传参及use使用外部变量 public function testClosure($t1, $t2) { $closure = function ($param1, $param2) use ($t1, $t2) { echo $param1.$

  • 在axios中使用params传参的时候传入数组的方法

    如下: changeList为一个数组 此时请求的参数格式为下图 解决方案为 将数组json序列化 此时参数格式为 以上这篇在axios中使用params传参的时候传入数组的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

随机推荐