今天遇到這樣一個問題下面是我服務器日誌中打印的SQL
SELECT COUNT(not_notice.id)
FROM not_notice not_notice
WHERE 1 = 1
AND not_notice.state IN (?)
AND not_notice.pk_uc_company = ?
打印傳入的參數是這樣的Parameters: 1,3,4(String), 1(Integer)
實際數據庫執行查詢語句是是90條 可是在接收到數據是67條 。SQL沒有問題啊
我的Mybatis XML是這樣寫的
SELECT
COUNT(not_notice.id)
FROM
not_notice not_notice
WHERE
1 = 1
<if test="noticeQuery.sendtime != null">
<![CDATA[ AND not_notice.sendtime >= #{noticeQuery.sendtime}]]>
</if>
AND not_notice.state IN
(#{noticeQuery.states})
<if test="noticeQuery.content != null and noticeQuery.content != ''">
AND (not_notice.title LIKE CONCAT('%',#{noticeQuery.content},'%')
OR not_notice.text LIKE CONCAT('%',#{noticeQuery.content},'%'))
</if>
<if test="noticeQuery.starttime != null and noticeQuery.sendtime != null">
<![CDATA[ AND not_notice.sendtime >= #{noticeQuery.starttime} AND not_notice.sendtime <= #{noticeQuery.endtime}]]>
</if>
AND not_notice.pk_uc_company = #{noticeQuery.companyId}
然後就一直盯着看 突然想到 #在mybatis會把參數在引號(' '),但是我想 ‘1,3,4’ 這樣的條件傳入應該查詢不到呀 後來測試 竟然能查詢到下面是執行的SQL
SELECT * FROM not_notice not_notice WHERE 1 = 1 AND not_notice.state IN ('1,3,4') AND not_notice.pk_uc_company = 1
查詢到的確實是67條 也就是滿足第一個 1 這個條件 在逗號前終止了
後來我把 #{noticeQuery.sates}這個改爲了¥{noticeQuery.state}的方式原樣傳入 結果就正常了。
說一下Mybatis # $的區別
#在Mybatis 中有預編譯的功能,也就是我們在JavaWeb中先把要執行的SQL 進行格式校驗 也就是調用了PreparedStatement這個接口 有預編譯功能 可以防止SQL注入攻擊,在實際的工作中大都使用這樣表達式。
$是原生轉入SQL的參數中,不進行預編譯,採用此方式傳入的參數不可以暴露到服務接口參數中,防止SQL注入攻擊。