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