学习笔记
PreparedStatement:防 SQL 注入的正确姿势
2026-08-18 09:00
JDBCSQL 注入
从拼接 SQL 的风险讲起,说明 PreparedStatement 参数绑定如何阻断 SQL 注入并提升可维护性。
PreparedStatement:防 SQL 注入的正确姿势
来源:Java 应用开发 实验三(大二上学期)· 整理:婉萤
为什么不能拼 SQL
初学 JDBC 最常见的写法是把参数直接拼进 SQL 字符串:
String sql = "SELECT * FROM student WHERE name = '" + name + "'";
看起来没问题,但如果 name 是 ' OR '1'='1,这条 SQL 就变成了:
SELECT * FROM student WHERE name = '' OR '1'='1'
条件恒真,整张表被拖出来——这就是 SQL 注入。任何来自用户输入的内容,都不能直接拼进 SQL。
正确做法:PreparedStatement
String sql = "SELECT * FROM student WHERE name = ?";
PreparedStatement pstm = conn.prepareStatement(sql);
pstm.setString(1, name); // 参数绑定,类型安全
ResultSet rs = pstm.executeQuery();
? 占位符 + setXxx() 参数绑定,数据库把参数当数据而不是代码处理,注入路径从根上被切断。
实验内容
基于 student 表完成增删改查全流程,全部走参数化 SQL:
- 插入学生记录(setInt / setString 按类型绑定)
- 按 id / 姓名查询
- 修改学生信息(先查后改,回显原值)
- 删除记录(判断影响行数)
额外收益
- 预编译:同一条 SQL 结构复用执行计划,批量操作更快
- 类型安全:
setInt(1, id)在编译期就保证类型匹配 - 可读性:SQL 与数据分离,代码不再是一锅粥
这个习惯我一直带到了后来所有项目里——项目里的 SQL 全部参数绑定,零拼接。