动态 SQL(最常见于 MyBatis、Spring JDBC、或者后台自己拼 SQL)确实很灵活,但也非常容易踩坑。下面按常见坑点 + 原因 + 建议来总结,偏实战向。
直接拼接用户输入:
String sql = "select * from user where name = '" + name + "'";
用户输入 ' or '1'='1 就能改变语义。
#{} 而不是 ${}${}(MyBatis 重灾区)order by ${column}
看起来“动态”,其实是字符串替换,不是参数。
if (!allowedColumns.contains(column)) {
throw new IllegalArgumentException();
}
select * from user
where
<if test="name != null">
and name = #{name}
</if>
如果前面没有条件,就会变成:
where and name = ?
<where> 标签1=1<where>
<if test="name != null">
and name = #{name}
</if>
</where>
where id in (#{ids})
传 "1,2,3" 会失败。
<foreach>where id in
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
<if test="list != null and list.size > 0">
忘了判断 size,直接拼 in () → SQL 报错。
where phone = #{phone}
phone 是 varchar,但传了数字。
一个 SQL 里十几个 <if>,逻辑比代码还复杂。
只测了“有参数”,没测:
动态 SQL 的核心坑:注入、语法、索引、可维护性。
原则:能参数化就参数化,能简单就别动态,动态必须可控。
如果你用的是 MyBatis / MyBatis-Plus / JPA / 原生 JDBC,我可以针对具体技术给更细的“避坑模板”。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。