001: /*
002: * Copyright 2002-2007 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: /**
020: * Simple implementation of the {@link NativeJdbcExtractor} interface.
021: * Assumes a pool that wraps Connection handles but not DatabaseMetaData:
022: * In this case, the underlying native Connection can be retrieved by simply
023: * calling <code>conHandle.getMetaData().getConnection()</code>.
024: * All other JDBC objects will be returned as passed in.
025: *
026: * <p>This extractor should work with any pool that does not wrap DatabaseMetaData,
027: * and will also work with any plain JDBC driver. Note that a pool can still wrap
028: * Statements, PreparedStatements, etc: The only requirement of this extractor is
029: * that <code>java.sql.DatabaseMetaData</code> does not get wrapped, returning the
030: * native Connection of the JDBC driver on <code>metaData.getConnection()</code>.
031: *
032: * <p>Customize this extractor by setting the "nativeConnectionNecessaryForXxx"
033: * flags accordingly: If Statements, PreparedStatements, and/or CallableStatements
034: * are wrapped by your pool, set the corresponding "nativeConnectionNecessaryForXxx"
035: * flags to "true". If none of the statement types is wrapped - or you solely need
036: * Connection unwrapping in the first place -, the defaults are fine.
037: *
038: * <p>SimpleNativeJdbcExtractor is a common choice for use with OracleLobHandler,
039: * which just needs Connection unwrapping via the
040: * {@link #getNativeConnectionFromStatement} method. This usage will work
041: * with almost any connection pool. Known to work are, for example:
042: * <ul>
043: * <li>Caucho Resin 2.1.x, 3.0.x
044: * <li>Sun Java System Application Server 8
045: * <li>Oracle OC4J 9.0.3, 9.0.4
046: * <li>C3P0 0.8.x
047: * <li>Jakarta Commons DBCP 1.0, 1.1, 1.2 (used in Tomcat 4.1.x, 5.0.x)
048: * <li>JBoss 3.2.x
049: * </ul>
050: *
051: * <p>For full usage with JdbcTemplate, i.e. to also provide Statement unwrapping:
052: * <ul>
053: * <li>Use a default SimpleNativeJdbcExtractor for Resin and SJSAS (no JDBC
054: * Statement objects are wrapped, therefore no special unwrapping is necessary).
055: * <li>Use a SimpleNativeJdbcExtractor with all "nativeConnectionNecessaryForXxx"
056: * flags set to "true" for OC4J and C3P0 (all JDBC Statement objects are wrapped,
057: * but none of the wrappers allow for unwrapping).
058: * <li>Use a CommonsDbcpNativeJdbcExtractor for Jakarta Commons DBCP respectively
059: * a JBossNativeJdbcExtractor for JBoss (all JDBC Statement objects are wrapped,
060: * but all of them can be extracted by casting to implementation classes).
061: * </ul>
062: *
063: * @author Juergen Hoeller
064: * @since 05.12.2003
065: * @see #setNativeConnectionNecessaryForNativeStatements
066: * @see #setNativeConnectionNecessaryForNativePreparedStatements
067: * @see #setNativeConnectionNecessaryForNativeCallableStatements
068: * @see Jdbc4NativeJdbcExtractor
069: * @see org.springframework.jdbc.core.JdbcTemplate#setNativeJdbcExtractor
070: * @see org.springframework.jdbc.support.lob.OracleLobHandler#setNativeJdbcExtractor
071: */
072: public class SimpleNativeJdbcExtractor extends
073: NativeJdbcExtractorAdapter {
074:
075: private boolean nativeConnectionNecessaryForNativeStatements = false;
076:
077: private boolean nativeConnectionNecessaryForNativePreparedStatements = false;
078:
079: private boolean nativeConnectionNecessaryForNativeCallableStatements = false;
080:
081: /**
082: * Set whether it is necessary to work on the native Connection to
083: * receive native Statements. Default is "false". If true, the Connection
084: * will be unwrapped first to create a Statement.
085: * <p>This makes sense if you need to work with native Statements from
086: * a pool that does not allow to extract the native JDBC objects from its
087: * wrappers but returns the native Connection on DatabaseMetaData.getConnection.
088: * <p>The standard SimpleNativeJdbcExtractor is unable to unwrap statements,
089: * so set this to true if your connection pool wraps Statements.
090: * @see java.sql.Connection#createStatement
091: * @see java.sql.DatabaseMetaData#getConnection
092: */
093: public void setNativeConnectionNecessaryForNativeStatements(
094: boolean nativeConnectionNecessaryForNativeStatements) {
095: this .nativeConnectionNecessaryForNativeStatements = nativeConnectionNecessaryForNativeStatements;
096: }
097:
098: public boolean isNativeConnectionNecessaryForNativeStatements() {
099: return this .nativeConnectionNecessaryForNativeStatements;
100: }
101:
102: /**
103: * Set whether it is necessary to work on the native Connection to
104: * receive native PreparedStatements. Default is "false". If true,
105: * the Connection will be unwrapped first to create a PreparedStatement.
106: * <p>This makes sense if you need to work with native PreparedStatements from
107: * a pool that does not allow to extract the native JDBC objects from its
108: * wrappers but returns the native Connection on Statement.getConnection.
109: * <p>The standard SimpleNativeJdbcExtractor is unable to unwrap statements,
110: * so set this to true if your connection pool wraps PreparedStatements.
111: * @see java.sql.Connection#prepareStatement
112: * @see java.sql.DatabaseMetaData#getConnection
113: */
114: public void setNativeConnectionNecessaryForNativePreparedStatements(
115: boolean nativeConnectionNecessary) {
116: this .nativeConnectionNecessaryForNativePreparedStatements = nativeConnectionNecessary;
117: }
118:
119: public boolean isNativeConnectionNecessaryForNativePreparedStatements() {
120: return this .nativeConnectionNecessaryForNativePreparedStatements;
121: }
122:
123: /**
124: * Set whether it is necessary to work on the native Connection to
125: * receive native CallableStatements. Default is "false". If true,
126: * the Connection will be unwrapped first to create a CallableStatement.
127: * <p>This makes sense if you need to work with native CallableStatements from
128: * a pool that does not allow to extract the native JDBC objects from its
129: * wrappers but returns the native Connection on Statement.getConnection.
130: * <p>The standard SimpleNativeJdbcExtractor is unable to unwrap statements,
131: * so set this to true if your connection pool wraps CallableStatements.
132: * @see java.sql.Connection#prepareCall
133: * @see java.sql.DatabaseMetaData#getConnection
134: */
135: public void setNativeConnectionNecessaryForNativeCallableStatements(
136: boolean nativeConnectionNecessary) {
137: this .nativeConnectionNecessaryForNativeCallableStatements = nativeConnectionNecessary;
138: }
139:
140: public boolean isNativeConnectionNecessaryForNativeCallableStatements() {
141: return this.nativeConnectionNecessaryForNativeCallableStatements;
142: }
143:
144: }
|