预编译

本文将浅显地讲解什么是预编译


1. 定义

预编译是做些代码文本的替换工作。是整个编译过程的最先做的工作。

2. 为什么预编译的SQL能够有效地防止SQL注入攻击

在了解预编译SQL前,我们最先接触到的预编译应该是PrepareStatement了吧?
在刚接触JDBC编程的时候,我们使用的SQL执行器是Statement,随着学习的进行,渐渐地我们把Statement换成了PrepareStatement,理由是为了防止SQL注入和SQL执行效率更高,可是,原理是什么?

因为使用PrepareStatement,Java帮助我们进行了文本替换工作?

虽然按照这个说法勉强可以解释为什么能够防止SQL注入,可执行效率的提高体现在哪里?所以这个说法是有问题的。

3. 原理

select * from `user` where `id` = ?;

所谓的预编译,当我们把上面的那句SQL传给MySQL服务期的时候,服务期就已经帮我们编译了,编译成了一个SQL模板(可以类比函数),同时占位符?成了参数,当我们使用setInt()、setString()插入数据时,实际上只是往SQL模板里面传入参数,这个过程编译与执行是分开的,模板被放入了模板池,当需要时取出插入数据即可,不需要继续编译。

StatementPrepareStatement的区别在于,前者属于编译并执行,后者属于先编译后执行,前者给sql服务器传递了完整的sql语句,sql服务器就需要给整条语句进行编译,这时候如果进行了sql注入,sql服务器编织出得结果就会与我们的预期产生误差。

以上就是为什么预编译的SQL能够防止SQL注入,并且提高执行效率的理由。

当然了也可以类比成Mybatis#{}${},前者表示预编译(SQL预编译),后者表示占位符(仅仅做文本的替换)。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐