通過閱讀本文你可以更好的理解兩個知識點:
1.#{}與${}在實際項目中的使用,避免在項目中使用不當造成不可預知的Bug;
2.MySQL中in里面如果是字符串的話,為什么只取第一個對應的數據,eg: in (“5,6,7”);
------------------------------------------------------------------------------------------------------------
快過年了,項目決定年后上線,在修Bug階段,在Bug解決后開始當水手划水了,然后復習了下MyBatis的動態SQL的知識,無意中看到一個大佬寫的代碼,發現和我們平常寫的方式有點不同,覺得這樣寫會產生問題,於是乎開啟了思考。正常情況下,我們在用in的時候,參數都用List或者一個Vo對象(里面有一個List),然后用foreach的方式循環取值,但是這個大佬居然in里面是String類型的參數,這樣寫能查出值嗎?
通常的寫法:


注:stockInBands是vo對象中的一個List類型的屬性。
質疑大佬的寫法:

這個String類型的orgIds取值過程如下:

使用了StringUtils.join()的方法將List轉為逗號隔開的String類型,我開始了思考,這樣的話最后這個String不是變成了類似(“5,6,7”)這樣的格式嗎?MySQL中in(“5,6,7”)這樣的格式可以查出來嗎?然后我就開始在數據庫中寫SQL語句嘗試,發現了一個奇怪的現象,這樣的格式可以查出來,但是永遠只能查出第一條數據,在例子中就是id為5對應的數據,后面的6,7為啥查不出來?
表數據如下:

發現這五條SQL都能查出數據,但是前三條SQL能查出3條數據,而后兩條SQL都只能查詢出id為5對應的數據。


我開始百度查閱相關知識點,發現在MySQL中in里面如果是字符串的話,會自動使用類似CAST('5,6,7' AS INT)方法轉化成int類型,對於數字開頭的字符串來說,轉為數字的結果就是截取前面的數字部分(本例中第一個逗號前的數據),對於開頭部分不能截取出數字的字符串來說,轉換的結果自然就是0了,如下圖實例。

這個疑惑解決后,我想了下難道這個大佬寫的真有問題,只是他和測試沒發現問題嗎?我又仔細看了下代碼后發現這個大佬寫的SQL里面用的是$而不是#,難道用$就能查詢正常嗎?然后我開始復習#{}與${}的區別,發現果然如此,這個大佬因為用的是$,${} 解析之后是什么就是什么,他不會當做字符串處理。假設傳入參數是”Smith”會解析成:order by Smith或者in (Smith),所以並沒有出現我發現的那種只會查出第一個id為5對應數據的問題。原來只是因為自己知識淺薄,造成的誤解。
如過您想深入了解#{}與${}的相關知識,請查閱我博客中java基礎分類中的--#{}和${}的區別是什么? 一文,謝謝。
