MyBatis模糊查詢報錯:ParserException: not supported.pos 問題解決
問題描述
在使用MyBatis執(zhí)行如下SQL時出現(xiàn)Druid解析異常:
<select id="selectListMzHairVoById" resultMap="MzPinHairMap">
select ... where pin_no like "%"#{id}"%"
</select>
報錯信息:
log merge sql error, dbType mysql, druid-1.2.9, sql : ... like '%'?'%' com.alibaba.druid.sql.parser.ParserException: not supported.pos 155...
問題根源
錯誤SQL解析邏輯
MyBatis會將 "%\"#{id}\"%" 解析為:
sql WHERE pin_no LIKE '%'?'%'
導(dǎo)致參數(shù)占位符被單引號包裹,MySQL無法識別這種語法結(jié)構(gòu)
深層原因分析
- 字符串拼接問題:直接使用
"%"#{id}"%"會導(dǎo)致預(yù)編譯參數(shù)位置錯誤 - SQL注入風(fēng)險:雖然使用
#{}是安全的,但錯誤的語法結(jié)構(gòu)可能繞過預(yù)編譯機制 - Druid嚴格校驗:阿里Druid連接池對SQL語法有嚴格校驗(比MySQL原生更嚴格)
三種解決方案
方案一:使用CONCAT函數(shù)(推薦)
<select id="selectListMzHairVoById" resultMap="MzPinHairMap">
SELECT ...
WHERE pin_no LIKE CONCAT('%', #{id}, '%')
</select>
優(yōu)勢:
- 符合SQL標準語法
- 100%預(yù)編譯安全
- 兼容所有數(shù)據(jù)庫連接池
方案二:bind標簽綁定參數(shù)
<select id="selectListMzHairVoById" resultMap="MzPinHairMap">
<bind name="pattern" value="'%' + id + '%'"/>
SELECT ... WHERE pin_no LIKE #{pattern}
</select>
適用場景:需要動態(tài)構(gòu)造復(fù)雜匹配模式時使用
方案三:Java端預(yù)拼接參數(shù)
Service層:
public List<MzPinHairVo> query(String id) {
String searchParam = "%" + id + "%";
return mapper.selectListMzHairVoById(searchParam);
}
Mapper.xml:
<select id="selectListMzHairVoById" resultMap="MzPinHairMap">
SELECT ...
WHERE pin_no LIKE #{id}
</select>
注意事項:需確保參數(shù)來源可信,防止SQL注入
方案對比
| 方案 | 安全性 | 可維護性 | 性能 | 跨數(shù)據(jù)庫兼容性 |
|---|---|---|---|---|
| CONCAT | ★★★ | ★★★ | ★★★ | ★★★ |
| bind標簽 | ★★★ | ★★☆ | ★★☆ | ★★★ |
| Java拼接 | ★★☆ | ★☆☆ | ★★★ | ★★★ |
到此這篇關(guān)于MyBatis模糊查詢報錯:ParserException: not supported.pos 問題解決的文章就介紹到這了,更多相關(guān)MyBatis模糊查詢報錯內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis動態(tài)調(diào)用表名和字段名的解決方法
今天在項目開發(fā)中有個業(yè)務(wù)是需要限制各個用戶對某些表里的字段查詢以及某些字段是否顯示,這種情況下,就需要構(gòu)建sql來動態(tài)傳入表名、字段名了,下面給大家介紹mybatis動態(tài)調(diào)用表名和字段名的解決方法,一起看看吧2016-10-10

