使用preparedstatement做模糊查询应通过?占位符和setstring()传参,避免sql注入;需手动添加通配符,对%、_转义并指定escape;空值须判空处理,推荐用try-with-resources自动关闭资源。

用 PreparedStatement 做模糊查询,核心是**把用户输入作为参数传入,而不是拼接进 SQL 字符串**,这样能彻底避免 SQL 注入,同时正确处理特殊字符(比如下划线 _、百分号 %)。
用 ? 占位符 + setString() 传参,不拼 SQL
错误做法(危险!):
String keyword = request.getParameter("kw");
String sql = "SELECT * FROM user WHERE name LIKE '%" + keyword + "%'";
// keyword 输入 'admin' OR '1'='1' 就会查出所有数据
正确写法(安全):
String sql = "SELECT * FROM user WHERE name LIKE ?";
PreparedStatement ps = conn.prepareStatement(sql);
// 手动添加通配符,再传参
ps.setString(1, "%" + keyword + "%");
如果搜索内容本身含 % 或 _,要转义处理
默认情况下,% 和 _ 是 LIKE 的通配符。如果用户搜的就是字符串“100%”,直接加 % 会变成 “%100%%”,结果不准确,还可能误匹配。
解决方法:指定一个转义字符(比如 ),并在参数中对原始内容里的 %、_ 做转义:
- 先用
keyword.replace("\", "\\").replace("%", "\%").replace("_", "\_")处理原始输入 - SQL 中加上
ESCAPE '\' - 完整示例:
String escaped = keyword.replace("\", "\\").replace("%", "\%").replace("_", "\_");
String sql = "SELECT * FROM product WHERE title LIKE ? ESCAPE '\'";
ps.setString(1, "%" + escaped + "%");
更灵活:把通配符留在 SQL 里,参数只传关键词
适合前端明确区分“开头匹配”“全匹配”“包含匹配”的场景:
-
WHERE name LIKE ?+ps.setString(1, keyword)→ 精确匹配 -
WHERE name LIKE ?+ps.setString(1, keyword + "%")→ 开头匹配(如“张%”) -
WHERE name LIKE ?+ps.setString(1, "%" + keyword + "%")→ 包含匹配(最常用)
这样逻辑清晰,也方便复用同一段预编译 SQL。
别忘了关闭资源和处理空值
keyword 为空或 null 时,不要直接传给 setString,否则可能查出意外结果或报错:
- 加判空:
if (keyword == null || keyword.trim().isEmpty()) { keyword = ""; } - 使用 try-with-resources 自动关闭 PreparedStatement 和 ResultSet
try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, "%" + keyword + "%");
ResultSet rs = ps.executeQuery();
// 处理结果
}
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











