为什么(如java文档所述)我们不能从PreparedStatement或CallableStatement调用Statement Interface中的execute方法?

时间:2016-02-20 11:47:06

标签: java jdbc execute

在java文档中的语句接口中的所有执行类型方法中都有一个注释

  

注意:无法在PreparedStatement或CallableStatement上调用此方法。

但为什么会如此呢?我的意思是PreparedStatementStatement的子界面,那么为什么我们不能这样做呢?事实上,我尝试过并且有效。

    ConnectionSetup setCon = new ConnectionSetup();
    // My own class for increasing readability.
    try{

        setCon.loadDriver("com.mysql.jdbc.Driver");//loadDriver calls Class.forName.
        con = setCon.setUpConnection("jdbc:mysql://localhost:3306/odi batsman", "root", "");//setUpConnection asks DriverManager for Connection Object.
        PreparedStatement ps = con.prepareStatement(query);
        ps.execute(query);
    }
    catch(ClassNotFoundException | SQLException e){

        e.printStackTrace();
    }

它工作得非常好,尽管我从Statement调用了execute方法(它接受一个字符串作为输入并从接口PreparedStatement继承),但该记录已在数据库中成功输入。最近怎么回事?

编辑我只是要求它是用java文档编写的,我们无法从execute(string)调用PreparedStatement,因为它是Statement的子接口,为什么我们不能?

3 个答案:

答案 0 :(得分:3)

它工作的事实意味着您正在使用的驱动程序实现(我猜MySQL Connector / J)不符合JDBC 4.1(或更高版本)规范。 JDBC API javadoc不仅适用于API的用户,还描述了驱动程序供应商需要实现的行为。

各种execute(String)executeQuery(String)等的API文档说:

  

SQLException - 如果发生数据库访问错误,则在已关闭的Statement上调用此方法,在PreparedStatement或CallableStatement上调用该方法

在JDBC 4.1(Java 7)中添加了这个粗体部分,以阐明预期的行为。

有几个原因:

  1. 调用其中一个execute...(String)方法会忽略准备好的语句,因此可能是您调用此方法的错误。提出异常表明你做错了什么。
  2. 在语句句柄上执行除预准备语句之外的语句字符串,可能在某些数据库系统上使预准备语句无效,导致第一次使用execute...(String)时出现意外行为,然后尝试使用{{1}执行并期望它使用早先准备好的声明。
  3. 事后看来,execute...()StatementPreparedStatement构成一个继承层次结构可能是一个错误。为了向后兼容,不能再更改它。

答案 1 :(得分:2)

当你调用execute(String)方法时,你基本上没有使用PreparedStatement本身,这意味着它没有使用PreparedStatement为你做的预编译SQL内容。如果您的查询中有参数,并且您已在PreparedStatement中设置参数值,execute(String)方法将忽略这些参数。

答案 2 :(得分:1)

尝试替换:

  ps.execute(query);

使用:

   ps.executeQuery();

因为您已经在PreparedStatement query中传递了con.prepareStatement(query)