首页 > 试题广场 >

关于PreparedStatement与Statement描

[单选题]
关于PreparedStatement与Statement描述错误的是()
  • 一般而言,PreparedStatement比Statement执行效率更高
  • PreparedStatement会预编译SQL语句
  • Statement每次都会解析/编译SQL,确立并优化数据获取路径
  • Statement执行扫描的结果集比PreparedStatement大
推荐
1:创建时的区别: 

    Statement statement = conn.createStatement();
    PreparedStatement preStatement = conn.prepareStatement(sql);
    执行的时候: 
    ResultSet rSet = statement.executeQuery(sql);
    ResultSet pSet = preStatement.executeQuery();

由上可以看出,PreparedStatement有预编译的过程,已经绑定sql,之后无论执行多少遍,都不会再去进行编译,

而 statement 不同,如果执行多变,则相应的就要编译多少遍sql,所以从这点看,preStatement 的效率会比 Statement要高一些


  1. import  java.sql.Connection;  
  2. import  java.sql.DriverManager;  
  3. import  java.sql.PreparedStatement;  
  4. import  java.sql.ResultSet;  
  5. import  java.sql.Statement;  
  6.   
  7. public   class  JDBCTest {  
  8.       
  9.     public   static   void  main(String[] args)  throws  Exception {  
  10.         //1 加载数据库驱动   
  11.         Class.forName("com.mysql.jdbc.Driver" );  
  12.           
  13.         //2 获取数据库连接   
  14.         String url = "jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8" ;  
  15.         String user = "root" ;  
  16.         String password = "root" ;  
  17.         Connection conn = DriverManager.getConnection(url, user, password);  
  18.           
  19.         //3 创建一个Statement   
  20.         String sql = "select id,loginName,email from user where id=" ;  
  21.         String tempSql;   
  22.         int  count =  1000 ;  
  23.         long  time = System.currentTimeMillis();  
  24.         for ( int  i= 0  ;i<count ;i++){  
  25.             Statement statement = conn.createStatement();  
  26.             tempSql=sql+(int ) (Math.random() *  100 );  
  27.             ResultSet rSet = statement.executeQuery(tempSql);  
  28.             statement.close();  
  29.         }  
  30.         System.out.println("statement cost:"  + (System.currentTimeMillis() - time));    
  31.           
  32.         String psql = "select id,loginName,email from user where id=?" ;  
  33.         time = System.currentTimeMillis();    
  34.         for  ( int  i =  0 ; i < count; i++) {    
  35.             int  id=( int ) (Math.random() *  100 );    
  36.             PreparedStatement preStatement = conn.prepareStatement(psql);  
  37.             preStatement.setLong(1 new  Long(id));    
  38.             ResultSet pSet = preStatement.executeQuery();  
  39.             preStatement.close();    
  40.         }    
  41.         System.out.println("preStatement cost:"  + (System.currentTimeMillis() - time));    
  42.         conn.close();  
  43.     }  
  44.       
  45. }  

上述代码反复执行,


statement cost:95           preStatement cost:90

statement cost:100         preStatement cost:89

statement cost:92           preStatement cost:86

当然,这个也会跟数据库的支持有关系,http://lucaslee.iteye.com/blog/49292  这篇帖子有说明

虽然没有更详细的测试 各种数据库, 但是就数据库发展 版本越高,数据库对 preStatement的支持会越来越好,

所以总体而言, 验证  preStatement 的效率 比 Statement 的效率高

2>安全性问题

这个就不多说了,preStatement是预编译的,所以可以有效的防止 SQL注入等问题

所以 preStatement 的安全性 比 Statement 高

3>代码的可读性 和 可维护性 
这点也不用多说了,你看老代码的时候  会深有体会

preStatement更胜一筹

编辑于 2016-03-24 15:10:59 回复(7)
因为PreparedStatement有预编译的过程,所以第一次扫描的集合
PreparedStatement会大于等于 Statement
发表于 2015-10-07 22:39:11 回复(7)
因为preparedstatement是带有预编译的(也就是有占位符的),所谓占位符就是可能会是很多种条件,与statement相比,statement只是固定条件,就一个,所以preparedstatement的检索范围肯定大
发表于 2017-09-08 13:37:23 回复(0)
我就想知道D选项怎么理解,评论的热门都没有个说的,说一大堆基础谁不会啊
发表于 2017-08-12 17:52:15 回复(1)
D选项:
个人认为
Statement和PreparedStatement的差异体现在效率,安全性方面
若用的SQL一样,扫描出来的结果集是没有区别的
发表于 2017-08-15 11:13:37 回复(0)
前面都写了那么多废话,愣是没找出答案,麻烦那些不会不要装逼,我翻到最后才找到答案
发表于 2017-04-27 15:12:50 回复(1)
d是错的,因为statement和prestatement结果急是一样大的
发表于 2018-10-10 16:06:34 回复(0)
abc说的都很透彻,到d就含糊过去了……
发表于 2017-09-07 22:24:57 回复(0)
网上转的 1.Statement、PreparedStatement和CallableStatement都是接口(interface)。  2.Statement继承自Wrapper、PreparedStatement继承自Statement、CallableStatement继承自PreparedStatement。  3.  Statement接口提供了执行语句和获取结果的基本方法;  PreparedStatement接口添加了处理 IN 参数的方法;  CallableStatement接口添加了处理 OUT 参数的方法。  4.  a.Statement:  普通的不带参的查询SQL;支持批量更新,批量删除;  b.PreparedStatement:  可变参数的SQL,编译一次,执行多次,效率高;  安全性好,有效防止Sql注入等问题;  支持批量更新,批量删除;  c.CallableStatement:  继承自PreparedStatement,支持带参数的SQL操作;  支持调用存储过程,提供了对输出和输入/输出参数(INOUT)的支持;  Statement每次执行sql语句,数据库都要执行sql语句的编译 ,  最好用于仅执行一次查询并返回结果的情形,效率高于PreparedStatement。  PreparedStatement是预编译的,使用PreparedStatement有几个好处  1. 在执行可变参数的一条SQL时,PreparedStatement比Statement的效率高,因为DBMS预编译一条SQL当然会比多次编译一条SQL的效率要高。  2. 安全性好,有效防止Sql注入等问题。  3.  对于多次重复执行的语句,使用PreparedStament效率会更高一点,并且在这种情况下也比较适合使用batch;  4.  代码的可读性和可维护性。  注:  executeQuery:返回结果集(ResultSet)。  executeUpdate: 执行给定SQL语句,该语句可能为 INSERT、UPDATE 或 DELETE 语句,  或者不返回任何内容的SQL语句(如 SQL DDL 语句)。  execute: 可用于执行任何SQL语句,返回一个boolean值,  表明执行该SQL语句是否返回了ResultSet。如果执行后第一个结果是ResultSet,则返回true,否则返回false。 
发表于 2015-10-03 09:03:19 回复(1)
Statement与PreparedStatement的执行结果没有区别,但是在执行效率上Preparedstatement更高。
发表于 2018-02-27 18:16:43 回复(0)
1.PreparedStatement是预编译的,对于批量处理可以大大提高效率. 也叫JDBC存储过程
2.使用 Statement 对象。在对数据库只执行一次性存取的时侯,用 Statement 对象进行处理。PreparedStatement 对象的开销比Statement大,对于一次性操作并不会带来额外的好处。
3.statement每次执行sql语句,相关数据库都要执行sql语句的编译,preparedstatement是预编译得,   preparedstatement支持批处理
发表于 2017-04-26 10:52:18 回复(0)
结果集感觉是一样的,都是一样的语句嘛,不能得出不同的结论吧?
发表于 2015-09-16 16:46:25 回复(0)

1 PreparedStatement 接口继承 Statement PreparedStatement 实例包含已编译的 SQL 语句,所以其执行速度要快于 Statement 对象。

2 、作为 Statement 的子类, PreparedStatement 继承了 Statement 的所有功能。三种方法

      execute executeQuery executeUpdate 已被更改以使之不再需要参数

 

3 、在 JDBC 应用中 , 如果你已经是稍有水平开发者 , 你就应该始终以 PreparedStatement 代替

      Statement. 也就是说 , 在任何时候都不要使用 Statement.

基于以下的原因 :

. 代码的可读性和可维护性 .

虽然用 PreparedStatement 来代替 Statement 会使代码多出几行 , 但这样的代码无论从可读性还是可维护性上来说 . 都比直接用 Statement 的代码高很多档次 :

stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values ('"+var1+"','"+var2+"',"+var3+",'"+var4+"')");//stmt Statement 对象实例

 

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(); //prestmt PreparedStatement 对象实例

 

不用我多说 , 对于第一种方法 . 别说其他人去读你的代码 , 就是你自己过一段时间再去读 , 都会觉得伤心 .

 

PreparedStatement 尽最大可能提高性能 .

    语句在被 DB 的编译器编译后的执行代码被缓存下来 , 那么下次调用时只要是相同的预编译语句就不需要编译 , 只要将参数直接传入编译过的语句执行代码中 ( 相当于一个涵数 ) 就会得到执行 . 这并不是说只有一个 Connection 中多次执行的预编译语句被缓存 , 而是对于整个 DB , 只要预编译的语句语法和缓存中匹配 . 那么在任何时候就可以不需要再次编译而可以直接执行 . statement 的语句中 , 即使是相同一操作 , 而由于每次操作的数据不同所以使整个语句相匹配的机会极小 , 几乎不太可能匹配 . 比如 :

insert into tb_name (col1,col2) values ('11','22');

insert into tb_name (col1,col2) values ('11','23');

即使是相同操作但因为数据内容不一样 , 所以整个个语句本身不能匹配 , 没有缓存语句的意义 . 事实是没有数据库会对普通语句编译后的执行代码缓存 .

 

当然并不是所以预编译语句都一定会被缓存 , 数据库本身会用一种策略 , 比如使用频度等因素来决定什么时候不再缓存已有的预编译结果 . 以保存有更多的空间存储新的预编译语句 .

 

. 最重要的一点是极大地提高了安全性 .

 

即使到目前为止 , 仍有一些人连基本的恶义 SQL 语法都不知道 .

String sql = "select * from tb_name where name= '"+varname+"' and passwd='"+varpasswd+"'";

如果我们把 [' or '1' = '1] 作为 varpasswd 传入进来 . 用户名随意 , 看看会成为什么 ?

 

select * from tb_name = ' 随意 ' and passwd = '' or '1' = '1';

因为 '1'='1' 肯定成立 , 所以可以任何通过验证 . 更有甚者 :

[';drop table tb_name;] 作为 varpasswd 传入进来 , :

select * from tb_name = ' 随意 ' and passwd = '';drop table tb_name; 有些数据库是不会让你成功的 , 但也有很多数据库就可以使这些语句得到执行 .

 

而如果你使用预编译语句 . 你传入的任何内容就不会和原来的语句发生任何匹配的关系 . 只要全使用预编译语句 , 你就用不着对传入的数据做任何过虑 . 而如果使用普通的 statement, 有可能要对 drop,; 等做费尽心机的判断和过虑 .

发表于 2015-12-21 09:12:22 回复(3)
现在的框架封装得太好了,很少有直接用JDBC直接编程了
发表于 2016-07-08 16:26:05 回复(0)
难道我用prestatement和statement执行相同的sql语句还出现的结果不一样嘛,好像pre只是有一个预编译防止sql注入,所以我觉得结果集应该是一样的
发表于 2019-08-14 23:25:57 回复(0)
一样的SQL语句,得到的结果集肯定相同啦。只是编译运行的效率不同罢了。
发表于 2019-07-31 01:10:34 回复(0)
两者都是创建对象然后通过对象调用 executeQuery() 方法执行 sql 语句 1.PreparedStatement效率更高 在数据库支持预编译的情况下预先将SQL语句编译, 当多次执行这条SQL语句时,可以直接执行编译好的SQL语句 2.PreparedStatement更加安全 PreparedStatement将sql变量抽离出sql语句,执行更加安全 例: select * from user where username = 'user' and userpwd = '' or '1' = '1'; select * from user where username= '"+varname+"' and userpwd='"+varpasswd+"'";
发表于 2019-05-02 11:53:13 回复(0)
preStatement的效率要比Statement要高一些,这是没有办法的事情
发表于 2019-01-15 18:28:52 回复(0)
prepare 准备好了先编译了
发表于 2018-12-13 20:03:57 回复(0)
1 、 PreparedStatement 接口继承 Statement , PreparedStatement 实例包含已编译的 SQL 语句,所以其执行速度要快于 Statement 对象。 2 、作为 Statement 的子类, PreparedStatement 继承了 Statement 的所有功能。三种方法 execute 、 executeQuery 和 executeUpdate 已被更改以使之不再需要参数 3 、在 JDBC 应用中 , 如果你已经是稍有水平开发者 , 你就应该始终以 PreparedStatement 代替 Statement. 也就是说 , 在任何时候都不要使用 Statement. 基于以下的原因 : 一 . 代码的可读性和可维护性 . 虽然用 PreparedStatement 来代替 Statement 会使代码多出几行 , 但这样的代码无论从可读性还是可维护性上来说 . 都比直接用 Statement 的代码高很多档次 : stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values ('"+var1+"','"+var2+"',"+var3+",'"+var4+"')");//stmt 是 Statement 对象实例 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(); //prestmt 是 PreparedStatement 对象实例 不用我多说 , 对于第一种方法 . 别说其他人去读你的代码 , 就是你自己过一段时间再去读 , 都会觉得伤心 . PreparedStatement 尽最大可能提高性能 . 语句在被 DB 的编译器编译后的执行代码被缓存下来
发表于 2018-11-15 08:14:07 回复(0)