36 changed files with 124 additions and 1693 deletions
@ -1,113 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2002-2012 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.springframework.jdbc.support.nativejdbc; |
|
||||||
|
|
||||||
import java.lang.reflect.Method; |
|
||||||
import java.sql.Connection; |
|
||||||
import java.sql.SQLException; |
|
||||||
|
|
||||||
import com.mchange.v2.c3p0.C3P0ProxyConnection; |
|
||||||
|
|
||||||
import org.springframework.util.ReflectionUtils; |
|
||||||
|
|
||||||
/** |
|
||||||
* Implementation of the {@link NativeJdbcExtractor} interface for the |
|
||||||
* C3P0 connection pool. |
|
||||||
* |
|
||||||
* <p>Returns underlying native Connections to application code instead of C3P0's |
|
||||||
* wrapper implementations; unwraps the Connection for native Statements. |
|
||||||
* The returned JDBC classes can then safely be cast, e.g. to |
|
||||||
* {@code oracle.jdbc.OracleConnection}. |
|
||||||
* |
|
||||||
* <p>This NativeJdbcExtractor can be set just to <i>allow</i> working with |
|
||||||
* a C3P0 DataSource: If a given object is not a C3P0 wrapper, it will be |
|
||||||
* returned as-is. |
|
||||||
* |
|
||||||
* <p>Note that this class requires C3P0 0.8.5 or later; for earlier C3P0 versions, |
|
||||||
* use SimpleNativeJdbcExtractor (which won't work for C3P0 0.8.5 or later). |
|
||||||
* |
|
||||||
* @author Juergen Hoeller |
|
||||||
* @since 1.1.5 |
|
||||||
* @see com.mchange.v2.c3p0.C3P0ProxyConnection#rawConnectionOperation |
|
||||||
* @see SimpleNativeJdbcExtractor |
|
||||||
*/ |
|
||||||
public class C3P0NativeJdbcExtractor extends NativeJdbcExtractorAdapter { |
|
||||||
|
|
||||||
private final Method getRawConnectionMethod; |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* This method is not meant to be used directly; it rather serves |
|
||||||
* as callback method for C3P0's "rawConnectionOperation" API. |
|
||||||
* @param con a native Connection handle |
|
||||||
* @return the native Connection handle, as-is |
|
||||||
*/ |
|
||||||
public static Connection getRawConnection(Connection con) { |
|
||||||
return con; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
public C3P0NativeJdbcExtractor() { |
|
||||||
try { |
|
||||||
this.getRawConnectionMethod = getClass().getMethod("getRawConnection", new Class<?>[] {Connection.class}); |
|
||||||
} |
|
||||||
catch (NoSuchMethodException ex) { |
|
||||||
throw new IllegalStateException("Internal error in C3P0NativeJdbcExtractor: " + ex.getMessage()); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean isNativeConnectionNecessaryForNativeStatements() { |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean isNativeConnectionNecessaryForNativePreparedStatements() { |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean isNativeConnectionNecessaryForNativeCallableStatements() { |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Retrieve the Connection via C3P0's {@code rawConnectionOperation} API, |
|
||||||
* using the {@code getRawConnection} as callback to get access to the |
|
||||||
* raw Connection (which is otherwise not directly supported by C3P0). |
|
||||||
* @see #getRawConnection |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
protected Connection doGetNativeConnection(Connection con) throws SQLException { |
|
||||||
if (con instanceof C3P0ProxyConnection) { |
|
||||||
C3P0ProxyConnection cpCon = (C3P0ProxyConnection) con; |
|
||||||
try { |
|
||||||
return (Connection) cpCon.rawConnectionOperation( |
|
||||||
this.getRawConnectionMethod, null, new Object[] {C3P0ProxyConnection.RAW_CONNECTION}); |
|
||||||
} |
|
||||||
catch (SQLException ex) { |
|
||||||
throw ex; |
|
||||||
} |
|
||||||
catch (Exception ex) { |
|
||||||
ReflectionUtils.handleReflectionException(ex); |
|
||||||
} |
|
||||||
} |
|
||||||
return con; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,159 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2002-2012 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.springframework.jdbc.support.nativejdbc; |
|
||||||
|
|
||||||
import java.lang.reflect.Method; |
|
||||||
import java.sql.CallableStatement; |
|
||||||
import java.sql.Connection; |
|
||||||
import java.sql.PreparedStatement; |
|
||||||
import java.sql.ResultSet; |
|
||||||
import java.sql.SQLException; |
|
||||||
import java.sql.Statement; |
|
||||||
|
|
||||||
import org.springframework.util.ReflectionUtils; |
|
||||||
|
|
||||||
/** |
|
||||||
* Implementation of the {@link NativeJdbcExtractor} interface for JBoss, |
|
||||||
* supporting JBoss Application Server 3.2.4+. As of Spring 3.1.1, it also |
|
||||||
* supports JBoss 7. |
|
||||||
* |
|
||||||
* <p>Returns the underlying native Connection, Statement, etc to |
|
||||||
* application code instead of JBoss' wrapper implementations. |
|
||||||
* The returned JDBC classes can then safely be cast, e.g. to |
|
||||||
* {@code oracle.jdbc.OracleConnection}. |
|
||||||
* |
|
||||||
* <p>This NativeJdbcExtractor can be set just to <i>allow</i> working with |
|
||||||
* a JBoss connection pool: If a given object is not a JBoss wrapper, |
|
||||||
* it will be returned as-is. |
|
||||||
* |
|
||||||
* @author Juergen Hoeller |
|
||||||
* @since 03.01.2004 |
|
||||||
* @see org.jboss.resource.adapter.jdbc.WrappedConnection#getUnderlyingConnection |
|
||||||
* @see org.jboss.resource.adapter.jdbc.WrappedStatement#getUnderlyingStatement |
|
||||||
* @see org.jboss.resource.adapter.jdbc.WrappedResultSet#getUnderlyingResultSet |
|
||||||
*/ |
|
||||||
public class JBossNativeJdbcExtractor extends NativeJdbcExtractorAdapter { |
|
||||||
|
|
||||||
// JBoss 7
|
|
||||||
private static final String JBOSS_JCA_PREFIX = "org.jboss.jca.adapters.jdbc."; |
|
||||||
|
|
||||||
// JBoss <= 6
|
|
||||||
private static final String JBOSS_RESOURCE_PREFIX = "org.jboss.resource.adapter.jdbc."; |
|
||||||
|
|
||||||
|
|
||||||
private Class<?> wrappedConnectionClass; |
|
||||||
|
|
||||||
private Class<?> wrappedStatementClass; |
|
||||||
|
|
||||||
private Class<?> wrappedResultSetClass; |
|
||||||
|
|
||||||
private Method getUnderlyingConnectionMethod; |
|
||||||
|
|
||||||
private Method getUnderlyingStatementMethod; |
|
||||||
|
|
||||||
private Method getUnderlyingResultSetMethod; |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* This constructor retrieves JBoss JDBC wrapper classes, |
|
||||||
* so we can get the underlying vendor connection using reflection. |
|
||||||
*/ |
|
||||||
public JBossNativeJdbcExtractor() { |
|
||||||
String prefix = JBOSS_JCA_PREFIX; |
|
||||||
try { |
|
||||||
// trying JBoss 7 jca package first...
|
|
||||||
this.wrappedConnectionClass = getClass().getClassLoader().loadClass(prefix + "WrappedConnection"); |
|
||||||
} |
|
||||||
catch (ClassNotFoundException ex) { |
|
||||||
// JBoss 7 jca package not found -> try traditional resource package.
|
|
||||||
prefix = JBOSS_RESOURCE_PREFIX; |
|
||||||
try { |
|
||||||
this.wrappedConnectionClass = getClass().getClassLoader().loadClass(prefix + "WrappedConnection"); |
|
||||||
} |
|
||||||
catch (ClassNotFoundException ex2) { |
|
||||||
throw new IllegalStateException("Could not initialize JBossNativeJdbcExtractor: neither JBoss 7's [" + |
|
||||||
JBOSS_JCA_PREFIX + ".WrappedConnection] nor traditional JBoss [" + JBOSS_RESOURCE_PREFIX + |
|
||||||
".WrappedConnection] found"); |
|
||||||
} |
|
||||||
} |
|
||||||
try { |
|
||||||
this.wrappedStatementClass = getClass().getClassLoader().loadClass(prefix + "WrappedStatement"); |
|
||||||
this.wrappedResultSetClass = getClass().getClassLoader().loadClass(prefix + "WrappedResultSet"); |
|
||||||
this.getUnderlyingConnectionMethod = |
|
||||||
this.wrappedConnectionClass.getMethod("getUnderlyingConnection", (Class[]) null); |
|
||||||
this.getUnderlyingStatementMethod = |
|
||||||
this.wrappedStatementClass.getMethod("getUnderlyingStatement", (Class[]) null); |
|
||||||
this.getUnderlyingResultSetMethod = |
|
||||||
this.wrappedResultSetClass.getMethod("getUnderlyingResultSet", (Class[]) null); |
|
||||||
} |
|
||||||
catch (Exception ex) { |
|
||||||
throw new IllegalStateException( |
|
||||||
"Could not initialize JBossNativeJdbcExtractor because of missing JBoss API methods/classes: " + ex); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* Retrieve the Connection via JBoss' {@code getUnderlyingConnection} method. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
protected Connection doGetNativeConnection(Connection con) throws SQLException { |
|
||||||
if (this.wrappedConnectionClass.isAssignableFrom(con.getClass())) { |
|
||||||
return (Connection) ReflectionUtils.invokeJdbcMethod(this.getUnderlyingConnectionMethod, con); |
|
||||||
} |
|
||||||
return con; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Retrieve the Connection via JBoss' {@code getUnderlyingStatement} method. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public Statement getNativeStatement(Statement stmt) throws SQLException { |
|
||||||
if (this.wrappedStatementClass.isAssignableFrom(stmt.getClass())) { |
|
||||||
return (Statement) ReflectionUtils.invokeJdbcMethod(this.getUnderlyingStatementMethod, stmt); |
|
||||||
} |
|
||||||
return stmt; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Retrieve the Connection via JBoss' {@code getUnderlyingStatement} method. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public PreparedStatement getNativePreparedStatement(PreparedStatement ps) throws SQLException { |
|
||||||
return (PreparedStatement) getNativeStatement(ps); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Retrieve the Connection via JBoss' {@code getUnderlyingStatement} method. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public CallableStatement getNativeCallableStatement(CallableStatement cs) throws SQLException { |
|
||||||
return (CallableStatement) getNativeStatement(cs); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Retrieve the Connection via JBoss' {@code getUnderlyingResultSet} method. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public ResultSet getNativeResultSet(ResultSet rs) throws SQLException { |
|
||||||
if (this.wrappedResultSetClass.isAssignableFrom(rs.getClass())) { |
|
||||||
return (ResultSet) ReflectionUtils.invokeJdbcMethod(this.getUnderlyingResultSetMethod, rs); |
|
||||||
} |
|
||||||
return rs; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,120 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2002-2012 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.springframework.jdbc.support.nativejdbc; |
|
||||||
|
|
||||||
import java.sql.CallableStatement; |
|
||||||
import java.sql.Connection; |
|
||||||
import java.sql.PreparedStatement; |
|
||||||
import java.sql.ResultSet; |
|
||||||
import java.sql.SQLException; |
|
||||||
import java.sql.Statement; |
|
||||||
|
|
||||||
/** |
|
||||||
* {@link NativeJdbcExtractor} implementation that delegates to JDBC 4.0's |
|
||||||
* {@code unwrap} method, as defined by {@link java.sql.Wrapper}. |
|
||||||
* You will typically need to specify a vendor {@link #setConnectionType Connection type} |
|
||||||
* / {@link #setStatementType Statement type} / {@link #setResultSetType ResultSet type} |
|
||||||
* to extract, since JDBC 4.0 only actually unwraps to a given target type. |
|
||||||
* |
|
||||||
* <p>Note: Only use this when actually running against a JDBC 4.0 driver, with a |
|
||||||
* connection pool that supports the JDBC 4.0 API (i.e. at least accepts JDBC 4.0 |
|
||||||
* API calls and passes them through to the underlying driver)! Other than that, |
|
||||||
* there is no need for connection pool specific setup. As of JDBC 4.0, |
|
||||||
* NativeJdbcExtractors will typically be implemented for specific drivers |
|
||||||
* instead of for specific pools (e.g. {@link OracleJdbc4NativeJdbcExtractor}). |
|
||||||
* |
|
||||||
* @author Juergen Hoeller |
|
||||||
* @since 2.5 |
|
||||||
* @see java.sql.Wrapper#unwrap |
|
||||||
* @see SimpleNativeJdbcExtractor |
|
||||||
* @see org.springframework.jdbc.core.JdbcTemplate#setNativeJdbcExtractor |
|
||||||
*/ |
|
||||||
public class Jdbc4NativeJdbcExtractor extends NativeJdbcExtractorAdapter { |
|
||||||
|
|
||||||
private Class<? extends Connection> connectionType = Connection.class; |
|
||||||
|
|
||||||
private Class<? extends Statement> statementType = Statement.class; |
|
||||||
|
|
||||||
private Class<? extends PreparedStatement> preparedStatementType = PreparedStatement.class; |
|
||||||
|
|
||||||
private Class<? extends CallableStatement> callableStatementType = CallableStatement.class; |
|
||||||
|
|
||||||
private Class<? extends ResultSet> resultSetType = ResultSet.class; |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* Set the vendor's Connection type, e.g. {@code oracle.jdbc.OracleConnection}. |
|
||||||
*/ |
|
||||||
public void setConnectionType(Class<? extends Connection> connectionType) { |
|
||||||
this.connectionType = connectionType; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Set the vendor's Statement type, e.g. {@code oracle.jdbc.OracleStatement}. |
|
||||||
*/ |
|
||||||
public void setStatementType(Class<? extends Statement> statementType) { |
|
||||||
this.statementType = statementType; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Set the vendor's PreparedStatement type, e.g. {@code oracle.jdbc.OraclePreparedStatement}. |
|
||||||
*/ |
|
||||||
public void setPreparedStatementType(Class<? extends PreparedStatement> preparedStatementType) { |
|
||||||
this.preparedStatementType = preparedStatementType; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Set the vendor's CallableStatement type, e.g. {@code oracle.jdbc.OracleCallableStatement}. |
|
||||||
*/ |
|
||||||
public void setCallableStatementType(Class<? extends CallableStatement> callableStatementType) { |
|
||||||
this.callableStatementType = callableStatementType; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Set the vendor's ResultSet type, e.g. {@code oracle.jdbc.OracleResultSet}. |
|
||||||
*/ |
|
||||||
public void setResultSetType(Class<? extends ResultSet> resultSetType) { |
|
||||||
this.resultSetType = resultSetType; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
@Override |
|
||||||
protected Connection doGetNativeConnection(Connection con) throws SQLException { |
|
||||||
return con.unwrap(this.connectionType); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Statement getNativeStatement(Statement stmt) throws SQLException { |
|
||||||
return stmt.unwrap(this.statementType); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public PreparedStatement getNativePreparedStatement(PreparedStatement ps) throws SQLException { |
|
||||||
return ps.unwrap(this.preparedStatementType); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public CallableStatement getNativeCallableStatement(CallableStatement cs) throws SQLException { |
|
||||||
return cs.unwrap(this.callableStatementType); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public ResultSet getNativeResultSet(ResultSet rs) throws SQLException { |
|
||||||
return rs.unwrap(this.resultSetType); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,157 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2002-2016 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.springframework.jdbc.support.nativejdbc; |
|
||||||
|
|
||||||
import java.sql.CallableStatement; |
|
||||||
import java.sql.Connection; |
|
||||||
import java.sql.PreparedStatement; |
|
||||||
import java.sql.ResultSet; |
|
||||||
import java.sql.SQLException; |
|
||||||
import java.sql.Statement; |
|
||||||
|
|
||||||
/** |
|
||||||
* Interface for extracting native JDBC objects from wrapped objects coming from |
|
||||||
* connection pools. This is necessary to allow for casting to native implementations |
|
||||||
* like {@code OracleConnection} or {@code OracleResultSet} in application |
|
||||||
* code, for example to create Blobs or to access vendor-specific features. |
|
||||||
* |
|
||||||
* <p>Note: Setting a custom {@code NativeJdbcExtractor} is just necessary |
|
||||||
* if you intend to cast to database-specific implementations like |
|
||||||
* {@code OracleConnection} or {@code OracleResultSet}. |
|
||||||
* Otherwise, any wrapped JDBC object will be fine, with no need for unwrapping. |
|
||||||
* |
|
||||||
* <p>Note: To be able to support any pool's strategy of native ResultSet wrapping, |
|
||||||
* it is advisable to get both the native Statement <i>and</i> the native ResultSet |
|
||||||
* via this extractor. Some pools just allow to unwrap the Statement, some just to |
|
||||||
* unwrap the ResultSet - the above strategy will cover both. It is typically |
|
||||||
* <i>not</i> necessary to unwrap the Connection to retrieve a native ResultSet. |
|
||||||
* |
|
||||||
* <p>When working with a simple connection pool that wraps Connections but not |
|
||||||
* Statements, a {@link SimpleNativeJdbcExtractor} is often sufficient. |
|
||||||
* |
|
||||||
* <p>{@link org.springframework.jdbc.core.JdbcTemplate} can properly apply a |
|
||||||
* {@code NativeJdbcExtractor} if specified, unwrapping all JDBC objects |
|
||||||
* that it creates. Note that this is just necessary if you intend to cast to |
|
||||||
* native implementations in your data access code. |
|
||||||
* |
|
||||||
* @author Juergen Hoeller |
|
||||||
* @since 25.08.2003 |
|
||||||
* @see SimpleNativeJdbcExtractor |
|
||||||
* @see org.springframework.jdbc.core.JdbcTemplate#setNativeJdbcExtractor |
|
||||||
*/ |
|
||||||
public interface NativeJdbcExtractor { |
|
||||||
|
|
||||||
/** |
|
||||||
* Return whether it is necessary to work on the native Connection to |
|
||||||
* receive native Statements. |
|
||||||
* <p>This should be true if the connection pool does not allow to extract |
|
||||||
* the native JDBC objects from its Statement wrapper but supports a way |
|
||||||
* to retrieve the native JDBC Connection. This way, applications can |
|
||||||
* still receive native Statements and ResultSet via working on the |
|
||||||
* native JDBC Connection. |
|
||||||
*/ |
|
||||||
boolean isNativeConnectionNecessaryForNativeStatements(); |
|
||||||
|
|
||||||
/** |
|
||||||
* Return whether it is necessary to work on the native Connection to |
|
||||||
* receive native PreparedStatements. |
|
||||||
* <p>This should be true if the connection pool does not allow to extract |
|
||||||
* the native JDBC objects from its PreparedStatement wrappers but |
|
||||||
* supports a way to retrieve the native JDBC Connection. This way, |
|
||||||
* applications can still receive native Statements and ResultSet via |
|
||||||
* working on the native JDBC Connection. |
|
||||||
*/ |
|
||||||
boolean isNativeConnectionNecessaryForNativePreparedStatements(); |
|
||||||
|
|
||||||
/** |
|
||||||
* Return whether it is necessary to work on the native Connection to |
|
||||||
* receive native CallableStatements. |
|
||||||
* <p>This should be true if the connection pool does not allow to extract |
|
||||||
* the native JDBC objects from its CallableStatement wrappers but |
|
||||||
* supports a way to retrieve the native JDBC Connection. This way, |
|
||||||
* applications can still receive native Statements and ResultSet via |
|
||||||
* working on the native JDBC Connection. |
|
||||||
*/ |
|
||||||
boolean isNativeConnectionNecessaryForNativeCallableStatements(); |
|
||||||
|
|
||||||
/** |
|
||||||
* Retrieve the underlying native JDBC Connection for the given Connection. |
|
||||||
* Supposed to return the given Connection if not capable of unwrapping. |
|
||||||
* @param con the Connection handle, potentially wrapped by a connection pool |
|
||||||
* @return the underlying native JDBC Connection, if possible; |
|
||||||
* else, the original Connection |
|
||||||
* @throws SQLException if thrown by JDBC methods |
|
||||||
*/ |
|
||||||
Connection getNativeConnection(Connection con) throws SQLException; |
|
||||||
|
|
||||||
/** |
|
||||||
* Retrieve the underlying native JDBC Connection for the given Statement. |
|
||||||
* Supposed to return the {@code Statement.getConnection()} if not |
|
||||||
* capable of unwrapping. |
|
||||||
* <p>Having this extra method allows for more efficient unwrapping if data |
|
||||||
* access code already has a Statement. {@code Statement.getConnection()} |
|
||||||
* often returns the native JDBC Connection even if the Statement itself |
|
||||||
* is wrapped by a pool. |
|
||||||
* @param stmt the Statement handle, potentially wrapped by a connection pool |
|
||||||
* @return the underlying native JDBC Connection, if possible; |
|
||||||
* else, the original Connection |
|
||||||
* @throws SQLException if thrown by JDBC methods |
|
||||||
* @see java.sql.Statement#getConnection() |
|
||||||
*/ |
|
||||||
Connection getNativeConnectionFromStatement(Statement stmt) throws SQLException; |
|
||||||
|
|
||||||
/** |
|
||||||
* Retrieve the underlying native JDBC Statement for the given Statement. |
|
||||||
* Supposed to return the given Statement if not capable of unwrapping. |
|
||||||
* @param stmt the Statement handle, potentially wrapped by a connection pool |
|
||||||
* @return the underlying native JDBC Statement, if possible; |
|
||||||
* else, the original Statement |
|
||||||
* @throws SQLException if thrown by JDBC methods |
|
||||||
*/ |
|
||||||
Statement getNativeStatement(Statement stmt) throws SQLException; |
|
||||||
|
|
||||||
/** |
|
||||||
* Retrieve the underlying native JDBC PreparedStatement for the given statement. |
|
||||||
* Supposed to return the given PreparedStatement if not capable of unwrapping. |
|
||||||
* @param ps the PreparedStatement handle, potentially wrapped by a connection pool |
|
||||||
* @return the underlying native JDBC PreparedStatement, if possible; |
|
||||||
* else, the original PreparedStatement |
|
||||||
* @throws SQLException if thrown by JDBC methods |
|
||||||
*/ |
|
||||||
PreparedStatement getNativePreparedStatement(PreparedStatement ps) throws SQLException; |
|
||||||
|
|
||||||
/** |
|
||||||
* Retrieve the underlying native JDBC CallableStatement for the given statement. |
|
||||||
* Supposed to return the given CallableStatement if not capable of unwrapping. |
|
||||||
* @param cs the CallableStatement handle, potentially wrapped by a connection pool |
|
||||||
* @return the underlying native JDBC CallableStatement, if possible; |
|
||||||
* else, the original CallableStatement |
|
||||||
* @throws SQLException if thrown by JDBC methods |
|
||||||
*/ |
|
||||||
CallableStatement getNativeCallableStatement(CallableStatement cs) throws SQLException; |
|
||||||
|
|
||||||
/** |
|
||||||
* Retrieve the underlying native JDBC ResultSet for the given statement. |
|
||||||
* Supposed to return the given ResultSet if not capable of unwrapping. |
|
||||||
* @param rs the ResultSet handle, potentially wrapped by a connection pool |
|
||||||
* @return the underlying native JDBC ResultSet, if possible; |
|
||||||
* else, the original ResultSet |
|
||||||
* @throws SQLException if thrown by JDBC methods |
|
||||||
*/ |
|
||||||
ResultSet getNativeResultSet(ResultSet rs) throws SQLException; |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,175 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2002-2012 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.springframework.jdbc.support.nativejdbc; |
|
||||||
|
|
||||||
import java.sql.CallableStatement; |
|
||||||
import java.sql.Connection; |
|
||||||
import java.sql.DatabaseMetaData; |
|
||||||
import java.sql.PreparedStatement; |
|
||||||
import java.sql.ResultSet; |
|
||||||
import java.sql.SQLException; |
|
||||||
import java.sql.Statement; |
|
||||||
|
|
||||||
import org.springframework.jdbc.datasource.DataSourceUtils; |
|
||||||
|
|
||||||
/** |
|
||||||
* Abstract adapter class for the {@link NativeJdbcExtractor} interface, |
|
||||||
* for simplified implementation of basic extractors. |
|
||||||
* Basically returns the passed-in JDBC objects on all methods. |
|
||||||
* |
|
||||||
* <p>{@code getNativeConnection} checks for a ConnectionProxy chain, |
|
||||||
* for example from a TransactionAwareDataSourceProxy, before delegating to |
|
||||||
* {@code doGetNativeConnection} for actual unwrapping. You can override |
|
||||||
* either of the two for a specific connection pool, but the latter is |
|
||||||
* recommended to participate in ConnectionProxy unwrapping. |
|
||||||
* |
|
||||||
* <p>{@code getNativeConnection} also applies a fallback if the first |
|
||||||
* native extraction process failed, that is, returned the same Connection as |
|
||||||
* passed in. It assumes that some additional proxying is going in this case: |
|
||||||
* Hence, it retrieves the underlying native Connection from the DatabaseMetaData |
|
||||||
* via {@code conHandle.getMetaData().getConnection()} and retries the native |
|
||||||
* extraction process based on that Connection handle. This works, for example, |
|
||||||
* for the Connection proxies exposed by Hibernate 3.1's {@code Session.connection()}. |
|
||||||
* |
|
||||||
* <p>The {@code getNativeConnectionFromStatement} method is implemented |
|
||||||
* to simply delegate to {@code getNativeConnection} with the Statement's |
|
||||||
* Connection. This is what most extractor implementations will stick to, |
|
||||||
* unless there's a more efficient version for a specific pool. |
|
||||||
* |
|
||||||
* @author Juergen Hoeller |
|
||||||
* @since 1.1 |
|
||||||
* @see #getNativeConnection |
|
||||||
* @see #getNativeConnectionFromStatement |
|
||||||
* @see org.springframework.jdbc.datasource.ConnectionProxy |
|
||||||
*/ |
|
||||||
public abstract class NativeJdbcExtractorAdapter implements NativeJdbcExtractor { |
|
||||||
|
|
||||||
/** |
|
||||||
* Return {@code false} by default. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public boolean isNativeConnectionNecessaryForNativeStatements() { |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Return {@code false} by default. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public boolean isNativeConnectionNecessaryForNativePreparedStatements() { |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Return {@code false} by default. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public boolean isNativeConnectionNecessaryForNativeCallableStatements() { |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Check for a ConnectionProxy chain, then delegate to doGetNativeConnection. |
|
||||||
* <p>ConnectionProxy is used by Spring's TransactionAwareDataSourceProxy |
|
||||||
* and LazyConnectionDataSourceProxy. The target connection behind it is |
|
||||||
* typically one from a local connection pool, to be unwrapped by the |
|
||||||
* doGetNativeConnection implementation of a concrete subclass. |
|
||||||
* @see #doGetNativeConnection |
|
||||||
* @see org.springframework.jdbc.datasource.ConnectionProxy |
|
||||||
* @see org.springframework.jdbc.datasource.DataSourceUtils#getTargetConnection |
|
||||||
* @see org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy |
|
||||||
* @see org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public Connection getNativeConnection(Connection con) throws SQLException { |
|
||||||
if (con == null) { |
|
||||||
return null; |
|
||||||
} |
|
||||||
Connection targetCon = DataSourceUtils.getTargetConnection(con); |
|
||||||
Connection nativeCon = doGetNativeConnection(targetCon); |
|
||||||
if (nativeCon == targetCon) { |
|
||||||
// We haven't received a different Connection, so we'll assume that there's
|
|
||||||
// some additional proxying going on. Let's check whether we get something
|
|
||||||
// different back from the DatabaseMetaData.getConnection() call.
|
|
||||||
DatabaseMetaData metaData = targetCon.getMetaData(); |
|
||||||
// The following check is only really there for mock Connections
|
|
||||||
// which might not carry a DatabaseMetaData instance.
|
|
||||||
if (metaData != null) { |
|
||||||
Connection metaCon = metaData.getConnection(); |
|
||||||
if (metaCon != null && metaCon != targetCon) { |
|
||||||
// We've received a different Connection there:
|
|
||||||
// Let's retry the native extraction process with it.
|
|
||||||
nativeCon = doGetNativeConnection(metaCon); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return nativeCon; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Not able to unwrap: return passed-in Connection. |
|
||||||
*/ |
|
||||||
protected Connection doGetNativeConnection(Connection con) throws SQLException { |
|
||||||
return con; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Retrieve the Connection via the Statement's Connection. |
|
||||||
* @see #getNativeConnection |
|
||||||
* @see Statement#getConnection |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public Connection getNativeConnectionFromStatement(Statement stmt) throws SQLException { |
|
||||||
if (stmt == null) { |
|
||||||
return null; |
|
||||||
} |
|
||||||
return getNativeConnection(stmt.getConnection()); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Not able to unwrap: return passed-in Statement. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public Statement getNativeStatement(Statement stmt) throws SQLException { |
|
||||||
return stmt; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Not able to unwrap: return passed-in PreparedStatement. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public PreparedStatement getNativePreparedStatement(PreparedStatement ps) throws SQLException { |
|
||||||
return ps; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Not able to unwrap: return passed-in CallableStatement. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public CallableStatement getNativeCallableStatement(CallableStatement cs) throws SQLException { |
|
||||||
return cs; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Not able to unwrap: return passed-in ResultSet. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public ResultSet getNativeResultSet(ResultSet rs) throws SQLException { |
|
||||||
return rs; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,60 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2002-2012 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.springframework.jdbc.support.nativejdbc; |
|
||||||
|
|
||||||
import java.sql.CallableStatement; |
|
||||||
import java.sql.Connection; |
|
||||||
import java.sql.PreparedStatement; |
|
||||||
import java.sql.ResultSet; |
|
||||||
import java.sql.Statement; |
|
||||||
|
|
||||||
/** |
|
||||||
* A {@link Jdbc4NativeJdbcExtractor} which comes pre-configured for Oracle's JDBC driver, |
|
||||||
* specifying the following vendor-specific API types for unwrapping: |
|
||||||
* <ul> |
|
||||||
* <li>{@code oracle.jdbc.OracleConnection} |
|
||||||
* <li>{@code oracle.jdbc.OracleStatement} |
|
||||||
* <li>{@code oracle.jdbc.OraclePreparedStatement} |
|
||||||
* <li>{@code oracle.jdbc.OracleCallableStatement} |
|
||||||
* <li>{@code oracle.jdbc.OracleResultSet} |
|
||||||
* </ul> |
|
||||||
* |
|
||||||
* <p>Note: This will work with any JDBC 4.0 compliant connection pool, without a need for |
|
||||||
* connection pool specific setup. In other words, as of JDBC 4.0, NativeJdbcExtractors |
|
||||||
* will typically be implemented for specific drivers instead of for specific pools. |
|
||||||
* |
|
||||||
* @author Juergen Hoeller |
|
||||||
* @since 3.0.5 |
|
||||||
*/ |
|
||||||
public class OracleJdbc4NativeJdbcExtractor extends Jdbc4NativeJdbcExtractor { |
|
||||||
|
|
||||||
@SuppressWarnings("unchecked") |
|
||||||
public OracleJdbc4NativeJdbcExtractor() { |
|
||||||
try { |
|
||||||
setConnectionType((Class<Connection>) getClass().getClassLoader().loadClass("oracle.jdbc.OracleConnection")); |
|
||||||
setStatementType((Class<Statement>) getClass().getClassLoader().loadClass("oracle.jdbc.OracleStatement")); |
|
||||||
setPreparedStatementType((Class<PreparedStatement>) getClass().getClassLoader().loadClass("oracle.jdbc.OraclePreparedStatement")); |
|
||||||
setCallableStatementType((Class<CallableStatement>) getClass().getClassLoader().loadClass("oracle.jdbc.OracleCallableStatement")); |
|
||||||
setResultSetType((Class<ResultSet>) getClass().getClassLoader().loadClass("oracle.jdbc.OracleResultSet")); |
|
||||||
} |
|
||||||
catch (Exception ex) { |
|
||||||
throw new IllegalStateException( |
|
||||||
"Could not initialize OracleJdbc4NativeJdbcExtractor because Oracle API classes are not available: " + ex); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,129 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2002-2016 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.springframework.jdbc.support.nativejdbc; |
|
||||||
|
|
||||||
/** |
|
||||||
* A simple implementation of the {@link NativeJdbcExtractor} interface. |
|
||||||
* Assumes a pool that wraps Connection handles but not DatabaseMetaData: |
|
||||||
* In this case, the underlying native Connection can be retrieved by simply |
|
||||||
* calling {@code conHandle.getMetaData().getConnection()}. |
|
||||||
* All other JDBC objects will be returned as passed in. |
|
||||||
* |
|
||||||
* <p>This extractor should work with any pool that does not wrap DatabaseMetaData, |
|
||||||
* and will also work with any plain JDBC driver. Note that a pool can still wrap |
|
||||||
* Statements, PreparedStatements, etc: The only requirement of this extractor is |
|
||||||
* that {@code java.sql.DatabaseMetaData} does not get wrapped, returning the |
|
||||||
* native Connection of the JDBC driver on {@code metaData.getConnection()}. |
|
||||||
* |
|
||||||
* <p>Customize this extractor by setting the "nativeConnectionNecessaryForXxx" |
|
||||||
* flags accordingly: If Statements, PreparedStatements, and/or CallableStatements |
|
||||||
* are wrapped by your pool, set the corresponding "nativeConnectionNecessaryForXxx" |
|
||||||
* flags to "true". If none of the statement types is wrapped - or you solely need |
|
||||||
* Connection unwrapping in the first place -, the defaults are fine. |
|
||||||
* |
|
||||||
* <p>For full usage with JdbcTemplate, i.e. to also provide Statement unwrapping: |
|
||||||
* <ul> |
|
||||||
* <li>Use a default SimpleNativeJdbcExtractor for Resin and SJSAS (no JDBC |
|
||||||
* Statement objects are wrapped, therefore no special unwrapping is necessary). |
|
||||||
* <li>Use a SimpleNativeJdbcExtractor with all "nativeConnectionNecessaryForXxx" |
|
||||||
* flags set to "true" for C3P0 (all JDBC Statement objects are wrapped, |
|
||||||
* but none of the wrappers allow for unwrapping). |
|
||||||
* <li>Use a JBossNativeJdbcExtractor for JBoss (all JDBC Statement objects are |
|
||||||
* wrapped, but all of them can be extracted by casting to implementation classes). |
|
||||||
* </ul> |
|
||||||
* |
|
||||||
* @author Juergen Hoeller |
|
||||||
* @since 05.12.2003 |
|
||||||
* @see #setNativeConnectionNecessaryForNativeStatements |
|
||||||
* @see #setNativeConnectionNecessaryForNativePreparedStatements |
|
||||||
* @see #setNativeConnectionNecessaryForNativeCallableStatements |
|
||||||
* @see Jdbc4NativeJdbcExtractor |
|
||||||
* @see org.springframework.jdbc.core.JdbcTemplate#setNativeJdbcExtractor |
|
||||||
*/ |
|
||||||
public class SimpleNativeJdbcExtractor extends NativeJdbcExtractorAdapter { |
|
||||||
|
|
||||||
private boolean nativeConnectionNecessaryForNativeStatements = false; |
|
||||||
|
|
||||||
private boolean nativeConnectionNecessaryForNativePreparedStatements = false; |
|
||||||
|
|
||||||
private boolean nativeConnectionNecessaryForNativeCallableStatements = false; |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* Set whether it is necessary to work on the native Connection to |
|
||||||
* receive native Statements. Default is "false". If true, the Connection |
|
||||||
* will be unwrapped first to create a Statement. |
|
||||||
* <p>This makes sense if you need to work with native Statements from |
|
||||||
* a pool that does not allow to extract the native JDBC objects from its |
|
||||||
* wrappers but returns the native Connection on DatabaseMetaData.getConnection. |
|
||||||
* <p>The standard SimpleNativeJdbcExtractor is unable to unwrap statements, |
|
||||||
* so set this to true if your connection pool wraps Statements. |
|
||||||
* @see java.sql.Connection#createStatement |
|
||||||
* @see java.sql.DatabaseMetaData#getConnection |
|
||||||
*/ |
|
||||||
public void setNativeConnectionNecessaryForNativeStatements(boolean nativeConnectionNecessaryForNativeStatements) { |
|
||||||
this.nativeConnectionNecessaryForNativeStatements = nativeConnectionNecessaryForNativeStatements; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean isNativeConnectionNecessaryForNativeStatements() { |
|
||||||
return this.nativeConnectionNecessaryForNativeStatements; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Set whether it is necessary to work on the native Connection to |
|
||||||
* receive native PreparedStatements. Default is "false". If true, |
|
||||||
* the Connection will be unwrapped first to create a PreparedStatement. |
|
||||||
* <p>This makes sense if you need to work with native PreparedStatements from |
|
||||||
* a pool that does not allow to extract the native JDBC objects from its |
|
||||||
* wrappers but returns the native Connection on Statement.getConnection. |
|
||||||
* <p>The standard SimpleNativeJdbcExtractor is unable to unwrap statements, |
|
||||||
* so set this to true if your connection pool wraps PreparedStatements. |
|
||||||
* @see java.sql.Connection#prepareStatement |
|
||||||
* @see java.sql.DatabaseMetaData#getConnection |
|
||||||
*/ |
|
||||||
public void setNativeConnectionNecessaryForNativePreparedStatements(boolean nativeConnectionNecessary) { |
|
||||||
this.nativeConnectionNecessaryForNativePreparedStatements = nativeConnectionNecessary; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean isNativeConnectionNecessaryForNativePreparedStatements() { |
|
||||||
return this.nativeConnectionNecessaryForNativePreparedStatements; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Set whether it is necessary to work on the native Connection to |
|
||||||
* receive native CallableStatements. Default is "false". If true, |
|
||||||
* the Connection will be unwrapped first to create a CallableStatement. |
|
||||||
* <p>This makes sense if you need to work with native CallableStatements from |
|
||||||
* a pool that does not allow to extract the native JDBC objects from its |
|
||||||
* wrappers but returns the native Connection on Statement.getConnection. |
|
||||||
* <p>The standard SimpleNativeJdbcExtractor is unable to unwrap statements, |
|
||||||
* so set this to true if your connection pool wraps CallableStatements. |
|
||||||
* @see java.sql.Connection#prepareCall |
|
||||||
* @see java.sql.DatabaseMetaData#getConnection |
|
||||||
*/ |
|
||||||
public void setNativeConnectionNecessaryForNativeCallableStatements(boolean nativeConnectionNecessary) { |
|
||||||
this.nativeConnectionNecessaryForNativeCallableStatements = nativeConnectionNecessary; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean isNativeConnectionNecessaryForNativeCallableStatements() { |
|
||||||
return this.nativeConnectionNecessaryForNativeCallableStatements; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,105 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2002-2013 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.springframework.jdbc.support.nativejdbc; |
|
||||||
|
|
||||||
import java.lang.reflect.Method; |
|
||||||
import java.sql.Connection; |
|
||||||
import java.sql.SQLException; |
|
||||||
|
|
||||||
import org.springframework.util.ReflectionUtils; |
|
||||||
|
|
||||||
/** |
|
||||||
* Implementation of the {@link NativeJdbcExtractor} interface for WebLogic, |
|
||||||
* supporting WebLogic Server 9.0 and higher. |
|
||||||
* |
|
||||||
* <p>Returns the underlying native Connection to application code instead |
|
||||||
* of WebLogic's wrapper implementation; unwraps the Connection for native |
|
||||||
* statements. The returned JDBC classes can then safely be cast, e.g. to |
|
||||||
* {@code oracle.jdbc.OracleConnection}. |
|
||||||
* |
|
||||||
* <p>This NativeJdbcExtractor can be set just to <i>allow</i> working |
|
||||||
* with a WebLogic DataSource: If a given object is not a WebLogic |
|
||||||
* Connection wrapper, it will be returned as-is. |
|
||||||
* |
|
||||||
* @author Thomas Risberg |
|
||||||
* @author Juergen Hoeller |
|
||||||
* @since 1.0.2 |
|
||||||
* @see #getNativeConnection |
|
||||||
* @see weblogic.jdbc.extensions.WLConnection#getVendorConnection |
|
||||||
*/ |
|
||||||
public class WebLogicNativeJdbcExtractor extends NativeJdbcExtractorAdapter { |
|
||||||
|
|
||||||
private static final String JDBC_EXTENSION_NAME = "weblogic.jdbc.extensions.WLConnection"; |
|
||||||
|
|
||||||
|
|
||||||
private final Class<?> jdbcExtensionClass; |
|
||||||
|
|
||||||
private final Method getVendorConnectionMethod; |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* This constructor retrieves the WebLogic JDBC extension interface, |
|
||||||
* so we can get the underlying vendor connection using reflection. |
|
||||||
*/ |
|
||||||
public WebLogicNativeJdbcExtractor() { |
|
||||||
try { |
|
||||||
this.jdbcExtensionClass = getClass().getClassLoader().loadClass(JDBC_EXTENSION_NAME); |
|
||||||
this.getVendorConnectionMethod = this.jdbcExtensionClass.getMethod("getVendorConnection", (Class[]) null); |
|
||||||
} |
|
||||||
catch (Exception ex) { |
|
||||||
throw new IllegalStateException( |
|
||||||
"Could not initialize WebLogicNativeJdbcExtractor because WebLogic API classes are not available: " + ex); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* Return {@code true}, as WebLogic returns wrapped Statements. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public boolean isNativeConnectionNecessaryForNativeStatements() { |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Return {@code true}, as WebLogic returns wrapped PreparedStatements. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public boolean isNativeConnectionNecessaryForNativePreparedStatements() { |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Return {@code true}, as WebLogic returns wrapped CallableStatements. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public boolean isNativeConnectionNecessaryForNativeCallableStatements() { |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Retrieve the Connection via WebLogic's {@code getVendorConnection} method. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
protected Connection doGetNativeConnection(Connection con) throws SQLException { |
|
||||||
if (this.jdbcExtensionClass.isAssignableFrom(con.getClass())) { |
|
||||||
return (Connection) ReflectionUtils.invokeJdbcMethod(this.getVendorConnectionMethod, con); |
|
||||||
} |
|
||||||
return con; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,106 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2002-2013 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.springframework.jdbc.support.nativejdbc; |
|
||||||
|
|
||||||
import java.lang.reflect.Method; |
|
||||||
import java.sql.Connection; |
|
||||||
import java.sql.SQLException; |
|
||||||
|
|
||||||
import org.springframework.util.ReflectionUtils; |
|
||||||
|
|
||||||
/** |
|
||||||
* Implementation of the {@link NativeJdbcExtractor} interface for WebSphere, |
|
||||||
* supporting WebSphere Application Server 6.1 and higher. |
|
||||||
* |
|
||||||
* <p>Returns the underlying native Connection to application code instead |
|
||||||
* of WebSphere's wrapper implementation; unwraps the Connection for |
|
||||||
* native statements. The returned JDBC classes can then safely be cast, |
|
||||||
* e.g. to {@code oracle.jdbc.OracleConnection}. |
|
||||||
* |
|
||||||
* <p>This NativeJdbcExtractor can be set just to <i>allow</i> working |
|
||||||
* with a WebSphere DataSource: If a given object is not a WebSphere |
|
||||||
* Connection wrapper, it will be returned as-is. |
|
||||||
* |
|
||||||
* @author Juergen Hoeller |
|
||||||
* @since 1.1 |
|
||||||
*/ |
|
||||||
public class WebSphereNativeJdbcExtractor extends NativeJdbcExtractorAdapter { |
|
||||||
|
|
||||||
private static final String JDBC_ADAPTER_CONNECTION_NAME = "com.ibm.ws.rsadapter.jdbc.WSJdbcConnection"; |
|
||||||
|
|
||||||
private static final String JDBC_ADAPTER_UTIL_NAME = "com.ibm.ws.rsadapter.jdbc.WSJdbcUtil"; |
|
||||||
|
|
||||||
|
|
||||||
private Class<?> webSphereConnectionClass; |
|
||||||
|
|
||||||
private Method webSphereNativeConnectionMethod; |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* This constructor retrieves WebSphere JDBC adapter classes, |
|
||||||
* so we can get the underlying vendor connection using reflection. |
|
||||||
*/ |
|
||||||
public WebSphereNativeJdbcExtractor() { |
|
||||||
try { |
|
||||||
this.webSphereConnectionClass = getClass().getClassLoader().loadClass(JDBC_ADAPTER_CONNECTION_NAME); |
|
||||||
Class<?> jdbcAdapterUtilClass = getClass().getClassLoader().loadClass(JDBC_ADAPTER_UTIL_NAME); |
|
||||||
this.webSphereNativeConnectionMethod = |
|
||||||
jdbcAdapterUtilClass.getMethod("getNativeConnection", new Class<?>[] {this.webSphereConnectionClass}); |
|
||||||
} |
|
||||||
catch (Exception ex) { |
|
||||||
throw new IllegalStateException( |
|
||||||
"Could not initialize WebSphereNativeJdbcExtractor because WebSphere API classes are not available: " + ex); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* Return {@code true}, as WebSphere returns wrapped Statements. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public boolean isNativeConnectionNecessaryForNativeStatements() { |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Return {@code true}, as WebSphere returns wrapped PreparedStatements. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public boolean isNativeConnectionNecessaryForNativePreparedStatements() { |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Return {@code true}, as WebSphere returns wrapped CallableStatements. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public boolean isNativeConnectionNecessaryForNativeCallableStatements() { |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Retrieve the Connection via WebSphere's {@code getNativeConnection} method. |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
protected Connection doGetNativeConnection(Connection con) throws SQLException { |
|
||||||
if (this.webSphereConnectionClass.isAssignableFrom(con.getClass())) { |
|
||||||
return (Connection) ReflectionUtils.invokeJdbcMethod(this.webSphereNativeConnectionMethod, null, con); |
|
||||||
} |
|
||||||
return con; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
@ -1,7 +0,0 @@ |
|||||||
/** |
|
||||||
* Provides a mechanism for extracting native implementations of JDBC |
|
||||||
* interfaces from wrapper objects that got returned from connection pools. |
|
||||||
* |
|
||||||
* <p>Can be used independently, for example in custom JDBC access code. |
|
||||||
*/ |
|
||||||
package org.springframework.jdbc.support.nativejdbc; |
|
||||||
@ -1,78 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2002-2016 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||||
* you may not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software |
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
||||||
* See the License for the specific language governing permissions and |
|
||||||
* limitations under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.springframework.jdbc.support; |
|
||||||
|
|
||||||
import java.sql.CallableStatement; |
|
||||||
import java.sql.Connection; |
|
||||||
import java.sql.DatabaseMetaData; |
|
||||||
import java.sql.PreparedStatement; |
|
||||||
import java.sql.ResultSet; |
|
||||||
import java.sql.SQLException; |
|
||||||
import java.sql.Statement; |
|
||||||
|
|
||||||
import org.junit.Test; |
|
||||||
|
|
||||||
import org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor; |
|
||||||
|
|
||||||
import static org.junit.Assert.*; |
|
||||||
import static org.mockito.BDDMockito.*; |
|
||||||
|
|
||||||
/** |
|
||||||
* @author Andre Biryukov |
|
||||||
* @author Juergen Hoeller |
|
||||||
*/ |
|
||||||
public class NativeJdbcExtractorTests { |
|
||||||
|
|
||||||
@Test |
|
||||||
public void simpleNativeJdbcExtractor() throws SQLException { |
|
||||||
SimpleNativeJdbcExtractor extractor = new SimpleNativeJdbcExtractor(); |
|
||||||
|
|
||||||
Connection con = mock(Connection.class); |
|
||||||
DatabaseMetaData dbmd = mock(DatabaseMetaData.class); |
|
||||||
Connection con2 = mock(Connection.class); |
|
||||||
given(con.getMetaData()).willReturn(dbmd); |
|
||||||
given(dbmd.getConnection()).willReturn(con2); |
|
||||||
|
|
||||||
Connection nativeCon = extractor.getNativeConnection(con); |
|
||||||
assertEquals(con2, nativeCon); |
|
||||||
|
|
||||||
Statement stmt = mock(Statement.class); |
|
||||||
given(stmt.getConnection()).willReturn(con); |
|
||||||
|
|
||||||
nativeCon = extractor.getNativeConnectionFromStatement(stmt); |
|
||||||
assertEquals(con2, nativeCon); |
|
||||||
|
|
||||||
Statement nativeStmt = extractor.getNativeStatement(stmt); |
|
||||||
assertEquals(nativeStmt, stmt); |
|
||||||
|
|
||||||
PreparedStatement ps = mock(PreparedStatement.class); |
|
||||||
|
|
||||||
PreparedStatement nativePs = extractor.getNativePreparedStatement(ps); |
|
||||||
assertEquals(ps, nativePs); |
|
||||||
|
|
||||||
CallableStatement cs = mock(CallableStatement.class); |
|
||||||
ResultSet rs = mock(ResultSet.class); |
|
||||||
given(cs.getResultSet()).willReturn(rs); |
|
||||||
|
|
||||||
CallableStatement nativeCs = extractor.getNativeCallableStatement(cs); |
|
||||||
assertEquals(cs, nativeCs); |
|
||||||
|
|
||||||
ResultSet nativeRs = extractor.getNativeResultSet(cs.getResultSet()); |
|
||||||
assertEquals(nativeRs, rs); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
Loading…
Reference in new issue