Mybatis order by 動態傳參出現的一個小bug


大家好,我是老三,一個平平無奇的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日知錄,快樂繼續。


“簡單的事情重復做,重復的事情認真做,認真的事情有創造性地做。”——

我是三分惡,一個能文能武的全棧開發!

點贊關注不迷路,咱們下期見!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM