PrepareStatment 与 Statement 比较

来源:互联网 发布:安全设置阻止java运行 编辑:程序博客网 时间:2024/05/01 22:47

JAVA的JDBC有多种方法可以对数据库进行查询,但使用比较多的还是conn.prepareStatement()和conn.createStatement()两种方式打开数据库游标进行查询,具体方法就不多说了,主要说说两种方式的区别。

个人感觉在开发中还是应尽量使用prepareStatement方式进行数据库查询,原因有以下几点:

1.       prepareStatement绑定参数方式 比createStatement直接写sql更加安全。

例: 系统中有一功能对客户信息按姓名进行检索,界面中有用户姓名输入框,如果用户在输入框中输入’ WHERE NAME = LIHE’检索

这时假设使用createStatement方式查询你的程序可能像下面这样:

String querySql = “SELECT * FROM CUSTOMERINFO WHERE NAME = ‘” + 姓名输入框的值 + “’”;

stmt = conn.createStatement();

stmt.execute(querySql);

querySql现在的值是SELECT * FROM CUSTOMERINFO WHERE NAME = ‘’ WHERE NAME = LIHE’’, 红字表示用户输入的内容,这时的查询肯定会报SQL语法错误,如果程序中未对输入框的特殊字符进行过滤则系统将会报错,这可能就是传说中的SQL攻击…

而使用prepareStatement 利用? 传参方式,java会自动将参数中的特殊字符进行转义,从而避免了以上的SQL攻击问题。

2.       prepareStatement绑定参数方式 比createStatement更加高效。

还是利用以上的例子, 假设使用createStatement方式查询程序可能像下面这样:

String querySql = “SELECT * FROM CUSTOMERINFO WHERE NAME = ‘” + 姓名输入框的值 + “’”;

stmt = conn.createStatement();

stmt.execute(querySql);

如果用户第一次输入AAA查询SQL为:

SELECT * FROM CUSTOMERINFO WHERE NAME = ‘AAA’, 如果此语句是第一次运行则Oracle发现这句SQL未在SHAREPOOL(共享池)中就会对这句SQL进行硬解析。而第二次用户输入BBB则查询SQL为: SELECT * FROM CUSTOMERINFO WHERE NAME = ‘BBB’, 如果此语句也是第一次运行, Oracle会从SHAREPOOL中查找此这句SQL以期望重用解析方案但发现没有找到,则会对上面这句SQL进行硬解析,因为Oracle会把SELECT * FROM CUSTOMERINFO WHERE NAME = ‘AAA’和SELECT * FROM CUSTOMERINFO WHERE NAME = ‘BBB’看成两句完全不同的SQL尽管两句只差了一个查询条件, 要知道Oracle的硬解析是很耗费资源的,它包括: 分析、限定(名称解析)、安全检查、优化等等。

而使用prepareStatement 利用? 传参方式就会利用Oracle绑定参数特性,解析时会忽略绑定参数,查询经过一次编译后,查询方案存储在Oracle的SHAREPOOL(共享池)中,可以用来检索和重用。在性能和伸缩性方面,这两者的差异是巨大的,甚至是惊人的。
转自:http://qingfengjushi.blog.hexun.com/26206763_d.html

原创粉丝点击