statement与preparestatement的区别
摘录之:http://luckykapok918.blog.163.com/blog/static/20586504320121027560264/
http://blog.csdn.net/sparadise1003/article/details/3514523
http://blog.csdn.net/gotohbu/article/details/4501811
1 从代码的可读性与可维护性
statement:
stmt.executeUpdate( "insert into tb_name (col1,col2,col2,col4) values ( ' "+var1+ " ', ' "+var2+ " ',
"+var3+ ", ' "+var4+ " ') ");
preparestatement:
perstmt = con.prepareStatement( "insert into tb_name (col1,col2,col2,col4) values (?,?,?,?) ");
perstmt.setString(1,var1);
perstmt.setString(2,var2);
perstmt.setString(3,var3);
perstmt.setString(4,var4);
perstmt.executeUpdate();
从这两个例子可以看出,preparestatement的可读性更好,书写也更方便,简洁。而且preparestatement的通用性更好,只要改变变量值,就可以执行另一次查询,而statement每执行一种查询,就要写一个新的查询字符串。
2 从数据库性能(特别是批处理)
preparestatement是预编译语句。每一种数据库都会尽最大努力对预编译语句提供最大的性能优化。因为预编译语句有可能会被重复调用,所以语句被DB编译器编译后的执行代码会被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中(相当于一个函数)就会得到执行。预编译语句是相对于DB而言的,与connection无关,即在CONNECT A中定义执行的preparestatement P,在connection B中也可以执行,不需要再重新编译了。在整个DB中,只要预编译语句的语法和缓存中匹配,那么在任何时候都可以不需要再次编译而直接执行。statement语句每执行一次,数据库编译器编译一次,即使是相同操作。
statement发送完整的Sql语句到数据库不是直接执行而是由数据库先编译,再运行。每次都需要编译。而PreparedStatement是先发送带参数的Sql语句,由数据库先编译,再发送一组组参数值。(同构时不需重复编译)
如果是同构的sql语句,PreparedStatement的效率要比statement高。而对于异构的sql则两者效率差不多,一般都用PreparedStatement代替Statement。
同构:两个Sql语句可编译部分是相同的,只有参数值不同。
异构:整个sql语句的格式是不同的
3 安全性
预编译语句会对传入的参数值进行检查,杜绝像SQL注入这样的攻击的发生。
在使用预编译语句,进行参数化查询的情况下,数据库系统不会将参数的内容视为SQL指令的一部分来处理,而是在数据库完成SQL指令的编译后,才套用参数运行,因此就算参数中含有破坏性的指令,也不会被数据库所运行。
另外,使用PrepareStatement还有一个好处,不用对传入的字符串进行转义,转义是为了防止SQL注入。