001: /*
002: * Copyright 2002-2005 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.jdbc.support.nativejdbc;
018:
019: import java.sql.CallableStatement;
020: import java.sql.Connection;
021: import java.sql.PreparedStatement;
022: import java.sql.ResultSet;
023: import java.sql.SQLException;
024: import java.sql.Statement;
025:
026: /**
027: * Interface for extracting native JDBC objects from wrapped objects coming from
028: * connection pools. This is necessary to be able to case to native implementations
029: * like OracleConnection or OracleResultSet in application code, for example to
030: * create Blobs or access other vendor-specific features.
031: *
032: * <p>Note: Setting a custom NativeJdbcExtractor is just necessary if you want to
033: * cast to database-specific implementations, like OracleConnection/OracleResultSet.
034: * Else, any wrapped JDBC object will be fine.
035: *
036: * <p>Note: To be able to support any pool's strategy of native ResultSet wrapping,
037: * it is advisable to get both the native Statement <i>and</i> the native ResultSet
038: * via this extractor. Some pools just allow to unwrap the Statement, some just to
039: * unwrap the ResultSet - the above strategy will cover both. It is typically
040: * <i>not</i> necessary to unwrap the Connection to retrieve a native ResultSet.
041: *
042: * <p>When working with a simple connection pool that wraps Connections but not
043: * Statements, a SimpleNativeJdbcExtractor is often sufficient. However, some
044: * pools (like Jakarta's Commons DBCP) wrap <i>all</i> JDBC objects that they
045: * return: Therefore, you need to use a specific NativeJdbcExtractor (like
046: * CommonsDbcpNativeJdbcExtractor) with them.
047: *
048: * <p>JdbcTemplate can properly apply a NativeJdbcExtractor if specified, correctly
049: * unwrapping all JDBC objects that it creates. Note that this is just necessary
050: * if you want to cast to native implementations in your data access code.
051: *
052: * <p>The Oracle-specific implementation of Spring's LobHandler interface needs
053: * a NativeJdbcExtractor to be able to work on the native OracleConnection.
054: * This is also necessary for other Oracle-specific features that you may want
055: * to leverage in your applications, such as InterMedia.
056: *
057: * @author Juergen Hoeller
058: * @since 25.08.2003
059: * @see SimpleNativeJdbcExtractor
060: * @see CommonsDbcpNativeJdbcExtractor
061: * @see org.springframework.jdbc.core.JdbcTemplate#setNativeJdbcExtractor
062: * @see org.springframework.jdbc.support.lob.OracleLobHandler#setNativeJdbcExtractor
063: */
064: public interface NativeJdbcExtractor {
065:
066: /**
067: * Return whether it is necessary to work on the native Connection to
068: * receive native Statements.
069: * <p>This should be true if the connection pool does not allow to extract
070: * the native JDBC objects from its Statement wrapper but supports a way
071: * to retrieve the native JDBC Connection. This way, applications can
072: * still receive native Statements and ResultSet via working on the
073: * native JDBC Connection.
074: */
075: boolean isNativeConnectionNecessaryForNativeStatements();
076:
077: /**
078: * Return whether it is necessary to work on the native Connection to
079: * receive native PreparedStatements.
080: * <p>This should be true if the connection pool does not allow to extract
081: * the native JDBC objects from its PreparedStatement wrappers but
082: * supports a way to retrieve the native JDBC Connection. This way,
083: * applications can still receive native Statements and ResultSet via
084: * working on the native JDBC Connection.
085: */
086: boolean isNativeConnectionNecessaryForNativePreparedStatements();
087:
088: /**
089: * Return whether it is necessary to work on the native Connection to
090: * receive native CallableStatements.
091: * <p>This should be true if the connection pool does not allow to extract
092: * the native JDBC objects from its CallableStatement wrappers but
093: * supports a way to retrieve the native JDBC Connection. This way,
094: * applications can still receive native Statements and ResultSet via
095: * working on the native JDBC Connection.
096: */
097: boolean isNativeConnectionNecessaryForNativeCallableStatements();
098:
099: /**
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)
123: throws SQLException;
124:
125: /**
126: * Retrieve the underlying native JDBC Statement for the given Statement.
127: * Supposed to return the given Statement if not capable of unwrapping.
128: * @param stmt the Statement handle, potentially wrapped by a connection pool
129: * @return the underlying native JDBC Statement, if possible;
130: * else, the original Connection
131: * @throws SQLException if thrown by JDBC methods
132: */
133: Statement getNativeStatement(Statement stmt) throws SQLException;
134:
135: /**
136: * Retrieve the underlying native JDBC PreparedStatement for the given statement.
137: * Supposed to return the given PreparedStatement if not capable of unwrapping.
138: * @param ps the PreparedStatement handle, potentially wrapped by a connection pool
139: * @return the underlying native JDBC PreparedStatement, if possible;
140: * else, the original Connection
141: * @throws SQLException if thrown by JDBC methods
142: */
143: PreparedStatement getNativePreparedStatement(PreparedStatement ps)
144: throws SQLException;
145:
146: /**
147: * Retrieve the underlying native JDBC CallableStatement for the given statement.
148: * Supposed to return the given CallableStatement if not capable of unwrapping.
149: * @param cs the CallableStatement handle, potentially wrapped by a connection pool
150: * @return the underlying native JDBC CallableStatement, if possible;
151: * else, the original Connection
152: * @throws SQLException if thrown by JDBC methods
153: */
154: CallableStatement getNativeCallableStatement(CallableStatement cs)
155: throws SQLException;
156:
157: /**
158: * Retrieve the underlying native JDBC ResultSet for the given statement.
159: * Supposed to return the given ResultSet if not capable of unwrapping.
160: * @param rs the ResultSet handle, potentially wrapped by a connection pool
161: * @return the underlying native JDBC ResultSet, if possible;
162: * else, the original Connection
163: * @throws SQLException if thrown by JDBC methods
164: */
165: ResultSet getNativeResultSet(ResultSet rs) throws SQLException;
166:
167: }
|