简述statement 和preparestatment的区别以

2020-08-15  本文已影响0人  早点起床晒太阳

前言

statement 和 PreparedStatement 均为接口,可以用他们来执行sql,但是他们还是有细微的差别。

1、执行sql的样式不同

Statement

Statement执行的是静态的sql对象

PreparedStatement

PreparedStatement既可以执行静态的sql对象,可以往里面出入参数。(这块注意: 参数类型不能错 比如int值就传入int) 样例如下,不多解释

        Connection connection = DriverManager.getConnection(CONNECTION_URL,"hadoop","");
        statement = connection.prepareStatement("select * from ceshi.test limit ?");
        statement.setInt(1,10);
        resultSet = statement.executeQuery();

2、PreparedStatement预编译的功能

PreparedStatement执行sql是现在预编译,然后执行executeQuery(),如上面代码所示

但是Statement这里执行的sql确实先拿到Statement ,然后去执行具体的sql语句。比如

        Connection connection = DriverManager.getConnection(CONNECTION_URL,"hadoop","");
        statement = connection.createStatement();
        resultSet = statement.executeQuery("select * from ceshi.test limit 10");

所以这块PreparedStatement可以防止Statement出现的预编译的问题。

3、注意 (重复使用preparestatment和statement的场景)

说到上面这些点,感觉还是PreparedStatement好用,那么是不是任何场景都使用PreparedStatement 就可以了呢?

如今有这么一个需求,我们来执行一个sql来得到一个resultSet。获取数据后,我们在执行另外一个sql获取另外一个resultSet,我们应该怎么做?

statement = connection.prepareStatement("xxx");
resultSet = statement.executeQuery()
statement.executeQuery("xxx")

如果使用这个的话,这样写可以么? 打开PreparedStatement关于executeQuery 的源码,我们看到如下

 <strong>Note:</strong>This method cannot be called on a
 <code>PreparedStatement</code> or <code>CallableStatement</code>.

说明这个方法不能被executeQuery调用,不然容易抛出异常(但是说实话,我自己测试了也能用,但是确实也是隐患。)

这个时候我们就可以使用Statement来进行操作了,比如

statement = connection.createStatement();
resultSet = statement.executeQuery("select * from ceshi.test limit 10");
while(resultSet.next()) {
    System.out.println(resultSet.getString(1));
}
resultSet1 = statement.executeQuery("select * from ceshi.test limit 10");
疑问

这里其实当时有个疑问,就是statement能同时执行多个resultSet么,会不会引起重复

我在statement源码说明的最上面找到了答案,说明如下

By default, only one <code>ResultSet</code> object per <code>Statement</code>
object can be open at the same time. Therefore, if the reading of one
<code>ResultSet</code> object is interleaved
with the reading of another, each must have been generated by
different <code>Statement</code> objects. All execution methods in the
<code>Statement</code> interface implicitly close a current
<code>ResultSet</code> object of the statement if an open one exists.

大意就是,如果同时读取两个resultSet做交互,使用一个Statement是不行的。但是如果是顺序执行的话,是可以的,因为比如当前的resultSet打开的时候,会隐式关闭之前的resultSet

上一篇下一篇

猜你喜欢

热点阅读