为什么(正如java文档所说)我们不能从PreparedStatement或CallableStatement调用语句接口中的execute方法?

为什么(正如java文档所说)我们不能从PreparedStatement或CallableStatement调用语句接口中的execute方法?,java,jdbc,execute,Java,Jdbc,Execute,java文档中语句接口中的所有execute-type方法中都有一个注释 注意:不能对PreparedStatement或CallableStatement调用此方法 但为什么会这样呢?我的意思是PreparedStatement是语句的子接口,那么为什么我们不能这样做呢?事实上,我试过了,而且成功了 ConnectionSetup setCon = new ConnectionSetup(); // My own class for increasing readability

java文档中语句接口中的所有execute-type方法中都有一个注释

注意:不能对PreparedStatement或CallableStatement调用此方法

但为什么会这样呢?我的意思是
PreparedStatement
语句的子接口,那么为什么我们不能这样做呢?事实上,我试过了,而且成功了

    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();
    }
它工作得非常好,尽管我从
PreparedStatement
调用了execute方法(该方法以字符串作为输入并从接口
语句继承),但记录还是成功地输入到了数据库中。怎么回事


EDIT我只是想问,它是用java文档编写的,我们不能从
PreparedStatement
调用
execute(string)
,但因为它是
语句的子接口,为什么我们不能呢?

发生的事情是,在调用
execute时,基本上没有使用PreparedStatement本身(String)
方法,这意味着它没有使用PreparedStatement为您所做的预编译SQL内容。如果您在查询中有参数,并且您在PreparedStatement中设置了参数值,则
执行(String)
方法将忽略这些参数。

发生的事情是,在调用
执行(字符串)时,基本上没有使用PreparedStatement本身
方法,这意味着它没有使用PreparedStatement为您提供的预编译SQL内容。如果您在查询中有参数,并且您在PreparedStatement中设置了参数值,则执行(字符串)
方法将忽略这些参数。

尝试替换:

  ps.execute(query);
与:

因为您已经在PreparedStatement
con.prepareStatement(query)
中通过了
查询
,请尝试替换:

  ps.execute(query);
与:


因为您已经在PreparedStatement
con.prepareStatement(query)
中传递了
query
,它工作的事实意味着您正在使用的驱动程序实现(我猜MySQL连接器/J)不符合JDBC 4.1(或更高版本)JDBCAPI javadoc不仅适用于API用户,还描述了驱动程序供应商需要实现的行为

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

SQLException
-如果发生数据库访问错误,则对关闭语句调用此方法,对PreparedStatement或CallableStatement调用此方法

JDBC4.1(Java7)中添加了这个粗体部分,以澄清预期的行为

这有几个原因:

  • 调用一个
    execute…(String)
    方法会忽略准备好的语句,因此调用此方法可能是一个错误。引发异常表明您做错了什么
  • 在某些数据库系统上,在语句句柄上执行除已准备好的语句之外的语句字符串可能会使已准备好的语句无效,从而导致首次使用
    execute…(string)
    并随后尝试使用
    execute…()
    并希望它使用先前准备好的语句

  • 事后看来,
    Statement
    PreparedStatement
    CallableStatement
    形成继承层次结构可能是一个错误。为了向后兼容,这一点不能再改变。

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

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

    SQLException
    -如果发生数据库访问错误,则对关闭语句调用此方法,对PreparedStatement或CallableStatement调用此方法

    JDBC4.1(Java7)中添加了这个粗体部分,以澄清预期的行为

    这有几个原因:

  • 调用一个
    execute…(String)
    方法会忽略准备好的语句,因此调用此方法可能是一个错误。引发异常表明您做错了什么
  • 在某些数据库系统上,在语句句柄上执行除已准备好的语句之外的语句字符串可能会使已准备好的语句无效,从而导致首次使用
    execute…(string)
    并随后尝试使用
    execute…()
    并希望它使用先前准备好的语句

  • 事后看来,
    Statement
    PreparedStatement
    CallableStatement
    形成继承层次结构可能是一个错误。为了向后兼容,这一点无法再更改。

    如果我没记错的话,重载版本不会使用替换的placeho执行实际的prepared语句因此,如果您有类似以下内容,您的查询将不起作用:
    SELECT*FROM table WHERE blub=?;
    。因此您需要使用这个问题:重复的问题不会问您为什么不能使用重载版本,但答案会告诉您。关于您的编辑:JavaDoc中的这一部分并不意味着您无法调用它(编译器不会呻吟)。你不应该这样做,因为它没有做你想让它做的事情。@Tom这意味着执行查询就像我们在使用
    语句
    对象?@Tom实际上,apidoc说它应该抛出
    SQLException
    。在这种情况下,特定的驱动程序