Prepared Statement作为SQL参数时,如何传入SQL LIKE语句?
如何在Prepared Statement中给LIKE语句传参数
嘿,这个问题其实挺常见的,核心就是要在不破坏PreparedStatement防注入特性的前提下,把通配符和参数结合起来。我给你分享两种最常用的靠谱做法:
方法1:在代码层给参数添加通配符
这种方式最直观,也跨数据库通用。你只需要在SQL里直接写LIKE ?,然后在代码里把通配符(%或_)加到参数值的前后/左右即可。比如用JDBC的例子:
// 假设要搜索包含"jacob"的用户名 String searchKeyword = "jacob"; String sql = "SELECT id, username FROM users WHERE username LIKE ?"; try (PreparedStatement pstmt = conn.prepareStatement(sql)) { // 给参数加上前后通配符,实现全模糊匹配 pstmt.setString(1, "%" + searchKeyword + "%"); // 如果只想前缀匹配:pstmt.setString(1, searchKeyword + "%"); // 如果只想后缀匹配:pstmt.setString(1, "%" + searchKeyword); ResultSet rs = pstmt.executeQuery(); // 处理结果集... } catch (SQLException e) { // 异常处理... }
这种做法的好处是逻辑清晰,通配符的位置可以灵活调整,而且完全保留了PreparedStatement的安全特性,不会有SQL注入风险。
方法2:在SQL语句中拼接通配符
如果你更倾向于把匹配逻辑放在SQL层面,可以用数据库的字符串拼接函数来把通配符和占位符结合。不同数据库的拼接语法略有不同:
MySQL/MariaDB 示例
用CONCAT()函数:
SELECT id, username FROM users WHERE username LIKE CONCAT('%', ?, '%')
代码里直接传原始参数就行:
pstmt.setString(1, searchKeyword);
PostgreSQL 示例
用||拼接运算符:
SELECT id, username FROM users WHERE username LIKE '%' || ? || '%'
SQL Server 示例
用+拼接运算符:
SELECT id, username FROM users WHERE username LIKE '%' + ? + '%'
这种方式的优势是如果多个业务场景用相同的匹配规则,只需要修改SQL语句,不用改业务代码。但要注意不同数据库的语法差异,跨数据库部署时需要适配。
绝对要避免的错误做法
- 不要直接写
LIKE '%?%':这会让数据库把?当成字符串的一部分,PreparedStatement不会解析这个占位符,结果就是你搜不到任何正确的内容。 - 绝对不要把参数直接拼到SQL字符串里(比如
"LIKE '%" + searchKeyword + "%'"):这完全抛弃了PreparedStatement的防注入能力,恶意用户很容易通过构造参数攻击你的数据库。
额外补充:处理参数中的通配符
如果你的搜索参数本身包含%或_(比如用户想搜“jacob%smith”),而你希望把这些字符当成普通文本匹配,就需要转义它们。以MySQL为例,可以用ESCAPE子句:
SELECT id, username FROM users WHERE username LIKE CONCAT('%', ?, '%') ESCAPE '\\'
然后在代码里把参数中的%转成\%,_转成\_即可:
String escapedKeyword = searchKeyword.replace("%", "\\%").replace("_", "\\_"); pstmt.setString(1, escapedKeyword);
内容的提问来源于stack exchange,提问作者Jacob McCall
相关产品推荐
相关产品推荐

