数据库 JDBC:PreparedStatement
本文基于MySQL创建了一个shop数据库
再创建一个Product表插入一些数据,为后面JDBC的执行创建数据:
预处理语句介绍
SQL 预处理是一种特殊的 SQL 处理方式,它会预先根据 SQL 语句模板来生成对应的执行计划,而后只需携带 SQL 参数便能直接执行,提升了 SQL 执行的性能,是一种典型的空间换时间的算法优化。
由于28准则,绝大多数情况下,某需求某一条 SQL 语句可能会被反复调用执行,或者每次执行的时候只有个别的值不同(比如 select 的 where 子句值不同,update 的 set 子句值不同,insert 的 values 值不同)。如果每次都需要经过上面的词法语义解析、语句优化、制定执行计划等,则效率就会降低。所谓预编译语句就是将此类 SQL 语句中的值用占位符替代,视为将 SQL 语句模板化或者参数化,一般称Prepared Statements,是一种特殊的Statement,预编译语句的优势在于归纳为:一次编译、多次运行,省去了解析优化等过程;而且能防止 SQL 注入。
如果我们只是来查询或者更新数据的话,最好用PreparedStatement代替Statement,它具有如下优点:
可以提高语句的执行性能
安全性更好,可以防止SQL注入
提高代码的可读性和可维护性
SQL预处理语句
MySQL将PREPARE、EXECUTE、DEALLOCATE统称为PREPARE STATEMENT,也称之为预处理语句。语法:
假设,我们实现查询Product中purchase_price大于某个值的某个种类(product_type)商品信息
参数的占位符问题, MySQL 的占位符是
?
,而 PostgreSQL 的占位符则不同,它会根据参数的序列来依次定义,如第一个参数的占位符是$1
,第二个参数的占位符则是$2
。
JDBC执行Prepare
下面创建PreparedStatement,查询purchase_price大于某个值的某个种类(product_type)商品信息。
运行结果:
Prepare防止SQL注入
假设将PreparedStatement的第二个参数更改为厨房用品 OR 1 = 1,
则,此时的执行语句将会被转化为:
从而,导致查不到符合条件的数据。而假设是通过executeQuery
来执行的查询
SQL注入成功,可以查询到数据库中的信息:
Prepare 虽然在每个数据库中的语法差异很大,但是一般情况下我们都不会手写 SQL,而是使用 ORM 框架来做。
-- 慕课课程:SQL Prepare
参考资料
实战1:如何用 PREPARE 防止 SQL 注入http://www.imooc.com/wiki/sqlbase/sqlpractice1.html
MySQL的SQL预处理(Prepared)https://www.cnblogs.com/geaozhang/p/9891338.html
慕课课程:SQL Preparehttp://www.imooc.com/wiki/sqlbase/sqlprepare.html
版权声明: 本文为 InfoQ 作者【大规模数据处理学习者】的原创文章。
原文链接:【http://xie.infoq.cn/article/5b1ece04ca5dd91de10143618】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论