Java中?占位符需配合PreparedStatement使用,按序、按类型、按逻辑绑定值;多条件查询用WHERE 1=1动态拼接,IN列表须动态生成对应数量?,模糊匹配通配符应置于参数值中,类型绑定须严格匹配。

Java 中的 ? 占位符是预编译 SQL 的核心安全机制,不能直接拼接字符串,必须配合 PreparedStatement 使用。在复杂查询(如多条件、动态 WHERE、IN 列表、模糊匹配等)中,关键不是“怎么写 ?”,而是“怎么按顺序、按类型、按逻辑绑定值”。用错顺序或漏绑参数会导致运行时异常或逻辑错误。
多条件动态查询:先构建 SQL 模板,再按需设值
复杂查询常含可选条件(如用户只填了姓名、没填部门),不能靠 if 拼接完整 SQL 字符串,而应统一用 WHERE 1=1 + 动态 AND ?:
- SQL 模板示例:
"SELECT * FROM emp WHERE 1=1 AND name LIKE ? AND dept_id = ? AND status = ?" - 只填了姓名?那就只对第一个
?调用setString(1, "%张%"),后两个参数仍需设值(如设为null或默认值),否则SQLException报“参数数量不匹配” - 更健壮的做法:用
StringBuilder构建最终 SQL 字符串,同时维护一个List<Object>存放待设参数,最后遍历列表调用setXxx
IN 查询:? 不能代表多个值,需动态生成占位符
WHERE id IN (?, ?, ?) 中每个 ? 对应一个独立参数,不能用单个 ? 代替整个列表:
- 错误写法:
"WHERE id IN (?)"+setInt(1, Arrays.asList(1,2,3))→ 运行时报错或查不到数据 - 正确做法:根据实际 ID 数量动态拼出对应个数的
?,例如 3 个 ID 就用"WHERE id IN (?,?,?)",再依次调用setInt(1,1); setInt(2,2); setInt(3,3) - 建议封装工具方法:传入
List<Integer>,自动生成(?,?,?)字符串并返回参数数组
模糊查询:通配符必须加在参数值里,不能写在 SQL 中
像 LIKE '%张%' 这样的写法看似自然,但若把 % 写死在 SQL 里,就无法复用模板做精确匹配;正确方式是把通配符作为参数值的一部分:
立即学习“Java免费学习笔记(深入)”;
- SQL 模板保持简洁:
"WHERE name LIKE ?" - 设值时手动包裹:
ps.setString(1, "%" + keyword + "%") - 如果既要支持模糊又要支持精确,可准备两套 SQL 模板,或在 Java 层判断后决定是否加
%
类型匹配要严格,尤其数字、布尔、null 和日期
? 本身无类型,绑定时必须用对应方法,否则可能隐式转换失败或结果异常:
- 整数用
setInt(),浮点数用setDouble(),不要全用setString() - 布尔值用
setBoolean()(数据库字段是TINYINT(1)或BOOLEAN时才可靠) - 传
null时,必须用setNull(index, Types.INTEGER)并指定 JDBC 类型,不能用setString(i, null) - 日期优先用
setTimestamp()或setDate(),避免字符串解析歧义


















