← 返回笔记

学习笔记

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 全部参数绑定,零拼接。