1. 参数化查询(PreparedStatement)的应用?
请说明参数化查询(PreparedStatement)的应用与原理?
- 参数化查询的机制
- 与 SQL 注入的对抗
- 编译与缓存
参数化查询(PreparedStatement)将 SQL 的"结构"与"参数"分离:SQL 语句在编译时被预编译为固定结构,参数通过占位符(?)传入,由数据库驱动将参数作为数据绑定,而不是拼接到 SQL 字符串中。这样用户输入永远不会被当作 SQL 语法执行,因此即使输入含单引号、注释符或关键字,也无法改变 SQL 结构,从根本上杜绝 SQL 注入。PreparedStatement 的另一优势是预编译语句可被数据库缓存复用,对重复执行的查询性能更好。应用场景包括所有用户输入参与的查询(按 ID、名称、条件搜索等),应统一使用参数化,禁止字符串拼接 SQL。参数化查询是 Web 应用与数据库安全的最基本、最有效的防线。
参数化查询解决的是"数据与代码"的混淆问题——把输入严格当作数据,从而让攻击者无法注入代码。它比 WAF 过滤更可靠,因为不依赖对攻击模式的识别,是防御 SQL 注入的第一原则。
String sql = "SELECT * FROM users WHERE id = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, userId); // 参数作为数据绑定,不参与 SQL 拼接
ResultSet rs = ps.executeQuery();