问题描述
在使用mybatis执行如下sql时出现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 '%'?'%'
导致参数占位符被单引号包裹,mysql无法识别这种语法结构
深层原因分析
- 字符串拼接问题:直接使用
"%"#{id}"%"会导致预编译参数位置错误 - sql注入风险:虽然使用
#{}是安全的,但错误的语法结构可能绕过预编译机制 - druid严格校验:阿里druid连接池对sql语法有严格校验(比mysql原生更严格)
三种解决方案
方案一:使用concat函数(推荐)
<select id="selectlistmzhairvobyid" resultmap="mzpinhairmap">
select ...
where pin_no like concat('%', #{id}, '%')
</select>
优势:
- 符合sql标准语法
- 100%预编译安全
- 兼容所有数据库连接池
方案二:bind标签绑定参数
<select id="selectlistmzhairvobyid" resultmap="mzpinhairmap">
<bind name="pattern" value="'%' + id + '%'"/>
select ... where pin_no like #{pattern}
</select>
适用场景:需要动态构造复杂匹配模式时使用
方案三:java端预拼接参数
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>
注意事项:需确保参数来源可信,防止sql注入
方案对比
| 方案 | 安全性 | 可维护性 | 性能 | 跨数据库兼容性 |
|---|---|---|---|---|
| concat | ★★★ | ★★★ | ★★★ | ★★★ |
| bind标签 | ★★★ | ★★☆ | ★★☆ | ★★★ |
| java拼接 | ★★☆ | ★☆☆ | ★★★ | ★★★ |
到此这篇关于mybatis模糊查询报错:parserexception: not supported.pos 问题解决的文章就介绍到这了,更多相关mybatis模糊查询报错内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论