1 /* 2 * Copyright 2002-2005 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.springframework.jdbc.support.nativejdbc; 18 19 import java.sql.CallableStatement; 20 import java.sql.Connection; 21 import java.sql.PreparedStatement; 22 import java.sql.ResultSet; 23 import java.sql.SQLException; 24 import java.sql.Statement; 25 26 /** 27 * Interface for extracting native JDBC objects from wrapped objects coming from 28 * connection pools. This is necessary to be able to case to native implementations 29 * like OracleConnection or OracleResultSet in application code, for example to 30 * create Blobs or access other vendor-specific features. 31 * 32 * <p>Note: Setting a custom NativeJdbcExtractor is just necessary if you want to 33 * cast to database-specific implementations, like OracleConnection/OracleResultSet. 34 * Else, any wrapped JDBC object will be fine. 35 * 36 * <p>Note: To be able to support any pool's strategy of native ResultSet wrapping, 37 * it is advisable to get both the native Statement <i>and</i> the native ResultSet 38 * via this extractor. Some pools just allow to unwrap the Statement, some just to 39 * unwrap the ResultSet - the above strategy will cover both. It is typically 40 * <i>not</i> necessary to unwrap the Connection to retrieve a native ResultSet. 41 * 42 * <p>When working with a simple connection pool that wraps Connections but not 43 * Statements, a SimpleNativeJdbcExtractor is often sufficient. However, some 44 * pools (like Jakarta's Commons DBCP) wrap <i>all</i> JDBC objects that they 45 * return: Therefore, you need to use a specific NativeJdbcExtractor (like 46 * CommonsDbcpNativeJdbcExtractor) with them. 47 * 48 * <p>JdbcTemplate can properly apply a NativeJdbcExtractor if specified, correctly 49 * unwrapping all JDBC objects that it creates. Note that this is just necessary 50 * if you want to cast to native implementations in your data access code. 51 * 52 * <p>The Oracle-specific implementation of Spring's LobHandler interface needs 53 * a NativeJdbcExtractor to be able to work on the native OracleConnection. 54 * This is also necessary for other Oracle-specific features that you may want 55 * to leverage in your applications, such as InterMedia. 56 * 57 * @author Juergen Hoeller 58 * @since 25.08.2003 59 * @see SimpleNativeJdbcExtractor 60 * @see CommonsDbcpNativeJdbcExtractor 61 * @see org.springframework.jdbc.core.JdbcTemplate#setNativeJdbcExtractor 62 * @see org.springframework.jdbc.support.lob.OracleLobHandler#setNativeJdbcExtractor 63 */ 64 public interface NativeJdbcExtractor { 65 66 /** 67 * Return whether it is necessary to work on the native Connection to 68 * receive native Statements. 69 * <p>This should be true if the connection pool does not allow to extract 70 * the native JDBC objects from its Statement wrapper but supports a way 71 * to retrieve the native JDBC Connection. This way, applications can 72 * still receive native Statements and ResultSet via working on the 73 * native JDBC Connection. 74 */ 75 boolean isNativeConnectionNecessaryForNativeStatements(); 76 77 /** 78 * Return whether it is necessary to work on the native Connection to 79 * receive native PreparedStatements. 80 * <p>This should be true if the connection pool does not allow to extract 81 * the native JDBC objects from its PreparedStatement wrappers but 82 * supports a way to retrieve the native JDBC Connection. This way, 83 * applications can still receive native Statements and ResultSet via 84 * working on the native JDBC Connection. 85 */ 86 boolean isNativeConnectionNecessaryForNativePreparedStatements(); 87 88 /** 89 * Return whether it is necessary to work on the native Connection to 90 * receive native CallableStatements. 91 * <p>This should be true if the connection pool does not allow to extract 92 * the native JDBC objects from its CallableStatement wrappers but 93 * supports a way to retrieve the native JDBC Connection. This way, 94 * applications can still receive native Statements and ResultSet via 95 * working on the native JDBC Connection. 96 */ 97 boolean isNativeConnectionNecessaryForNativeCallableStatements(); 98 99 /** 100 * Retrieve the underlying native JDBC Connection for the given Connection. 101 * Supposed to return the given Connection if not capable of unwrapping. 102 * @param con the Connection handle, potentially wrapped by a connection pool 103 * @return the underlying native JDBC Connection, if possible; 104 * else, the original Connection 105 * @throws SQLException if thrown by JDBC methods 106 */ 107 Connection getNativeConnection(Connection con) throws SQLException; 108 109 /** 110 * Retrieve the underlying native JDBC Connection for the given Statement. 111 * Supposed to return the <code>Statement.getConnection()</code> if not 112 * capable of unwrapping. 113 * <p>Having this extra method allows for more efficient unwrapping if data 114 * access code already has a Statement. <code>Statement.getConnection()</code> 115 * often returns the native JDBC Connection even if the Statement itself 116 * is wrapped by a pool. 117 * @param stmt the Statement handle, potentially wrapped by a connection pool 118 * @return the underlying native JDBC Connection, if possible; 119 * else, the original Connection 120 * @throws SQLException if thrown by JDBC methods 121 */ 122 Connection getNativeConnectionFromStatement(Statement stmt) throws SQLException; 123 124 /** 125 * Retrieve the underlying native JDBC Statement for the given Statement. 126 * Supposed to return the given Statement if not capable of unwrapping. 127 * @param stmt the Statement handle, potentially wrapped by a connection pool 128 * @return the underlying native JDBC Statement, if possible; 129 * else, the original Connection 130 * @throws SQLException if thrown by JDBC methods 131 */ 132 Statement getNativeStatement(Statement stmt) throws SQLException; 133 134 /** 135 * Retrieve the underlying native JDBC PreparedStatement for the given statement. 136 * Supposed to return the given PreparedStatement if not capable of unwrapping. 137 * @param ps the PreparedStatement handle, potentially wrapped by a connection pool 138 * @return the underlying native JDBC PreparedStatement, if possible; 139 * else, the original Connection 140 * @throws SQLException if thrown by JDBC methods 141 */ 142 PreparedStatement getNativePreparedStatement(PreparedStatement ps) throws SQLException; 143 144 /** 145 * Retrieve the underlying native JDBC CallableStatement for the given statement. 146 * Supposed to return the given CallableStatement if not capable of unwrapping. 147 * @param cs the CallableStatement handle, potentially wrapped by a connection pool 148 * @return the underlying native JDBC CallableStatement, if possible; 149 * else, the original Connection 150 * @throws SQLException if thrown by JDBC methods 151 */ 152 CallableStatement getNativeCallableStatement(CallableStatement cs) throws SQLException; 153 154 /** 155 * Retrieve the underlying native JDBC ResultSet for the given statement. 156 * Supposed to return the given ResultSet if not capable of unwrapping. 157 * @param rs the ResultSet handle, potentially wrapped by a connection pool 158 * @return the underlying native JDBC ResultSet, if possible; 159 * else, the original Connection 160 * @throws SQLException if thrown by JDBC methods 161 */ 162 ResultSet getNativeResultSet(ResultSet rs) throws SQLException; 163 164 } 165