【问题标题】:Using OraclePreparedStatement with DBCP Connection将 OraclePreparedStatement 与 DBCP 连接一起使用
【发布时间】:2011-09-20 12:16:37
【问题描述】:

我正在尝试使用 dbcp 框架为我的 oracle 服务器创建一个连接池。 我使用这个tutorial 进行连接。 问题是用这个连接创建一个 OraclePreparedStatement:

Connection oracleCon;
OraclePreparedStatement o_stmt;
String sql = "INSERT INTO T002_metadata (T002_datacitexml,T002_version, T002_active)       VALUES (?,?,?) RETURNING T002_id INTO ?";


oracleCon = ConnectionManager.ds.getConnection();

o_stmt = ((OraclePreparedStatement) oracleCon.prepareStatement(sql));

执行后,抛出异常。

org.apache.commons.dbcp.DelegatingPreparedStatement cannot be cast to oracle.jdbc.OraclePreparedStatement

有没有可能强制转换语句?

【问题讨论】:

标签: java oracle casting prepared-statement


【解决方案1】:

不是甲骨文课程,不。这就是 JDBC 的用途。这是一个 API。仅使用 java.sql.PreparedStatement。通过尝试向下转换,您违反了多态性并破坏了这样的事情,其中​​一个库正在包装真正的连接和语句,以便为您提供一些额外的服务。

【讨论】:

    【解决方案2】:

    我今天遇到了同样的问题,并按照here 的建议通过更改 Tomcat 配置解决了它。 我通过像这样更改类型和工厂属性来更改context.xml 文件:

    ....
    <Resource name="jdbc/dsName"
           auth="Container"
              type="oracle.jdbc.pool.OracleDataSource"
              factory="oracle.jdbc.pool.OracleDataSourceFactory"
           user="username"
           password="password"
           driverClassName="oracle.jdbc.driver.OracleDriver"
           url="jdbcurl"/>
    ....
    

    web.xml 文件中的资源定义也必须更改

    ....
     <resource-ref>
        <description>Oracle datasource</description>
        <res-ref-name>jdbc/test</res-ref-name>
        <!-- <res-type>javax.sql.DataSource</res-type>-->
        <res-type>oracle.jdbc.pool.OracleDataSource</res-type>
        <res-auth>Container</res-auth>
      </resource-ref>
    ....
    

    我的代码无需更改。

    【讨论】:

      【解决方案3】:

      如果您使用的是 Oracle,您可以将连接转换为 OracleConnection,然后再转换 您对 OraclePreparedStatement 的准备好的语句。 jdbc 所做的是将 Oracle 对象向上转换为标准 sql 对象,但它们仍然是 Oracle sql 对象。

      【讨论】:

        【解决方案4】:

        我使用实用方法

        public static OraclePreparedStatement getOraclePreparedStatement(PreparedStatement stmt) {
                if (stmt instanceof OraclePreparedStatement) {
                    return (OraclePreparedStatement) stmt;
                }
                if (stmt instanceof DelegatingPreparedStatement) {
                    DelegatingPreparedStatement stmt1 = (DelegatingPreparedStatement) stmt;
        
                    return (OraclePreparedStatement) stmt1.getInnermostDelegate();
                }
                System.out.println(stmt);
                throw new RuntimeException("unknown statement");
            }
        

        本质上它允许单独使用相同的代码(例如在测试中)或在 tomcat 中。我使用它而不是强制转换,所以代码不会变长。

        try (OraclePreparedStatement stmt = getOraclePreparedStatement(con.prepareStatement(SQL_INSERT_TREATMENT))) {
            ...
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-04-29
          • 1970-01-01
          • 2013-01-02
          • 2017-11-18
          • 2015-11-17
          • 1970-01-01
          • 1970-01-01
          • 2021-09-08
          相关资源
          最近更新 更多