Prepared Statements – 数据库层面解决SQL注入问题

Java Web开发更推荐PreparedStatement来进行动态拼装SQL语句,可以防止SQL注入和带来SQL执行效率提升,其实SQL预编译机制是数据库实现的,本文以MySQL为例

Prepared Statements语法

# 创建预编译语句psql1
PREPARE psql1 FROM 'SELECT * FROM employee WHERE id = ? AND name = ?';
# 创建用户自定义变量@a=3,@b="Bob"
SET @a = 3;
SET @b = "Bob";
# 按顺序代入占位符数值执行预编译语句
EXECUTE USING @a, @b;
# 回收预编译语句,之后将不能再EXECUTE该语句
DEALLOCATE PREPARE psql1;

Prepared Statement注意点

作用域:仅对当前Session有效,且仅在Session结束前有效

控制数量:调整max_prepared_stmt_count系统变量,防止创建太多语句占用过多内存

SQL预编译的好处

性能高:仅需一次编译,无需每次执行SQL时都进行词法分析和语法分析,之后的运行都仅传入参数

防注入:仅对传入参数前的SQL语句进行编译阶段的词法分析和语法分析,占位符传入的参数不参与编译阶段,因此不会被当作SQL的执行计划

Java Web项目中的使用

JDBC中的PreparedStatement、MyBatis中的#{param}占位符

开启SQL预编译和预编译缓存:设置数据源属性或作为JDBC URL参数

useServerPrepStmts=true
cachePrepStmts=true

参考资料

MySQL 8.0 Reference Manual / SQL Statements / Prepared Statements
MySQL Connector/J 8.0 Developer Guide / Connector/J Reference / Configuration Properties

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

©2018-2024 Howell版权所有 备案号:冀ICP备19000576号