added configurable Connection/Statement/ResultSet target types to Jdbc4NativeJdbcExtractor (SPR-7613); added OracleJdbc4NativeJdbcExtractor with pre-configured Oracle JDBC API types
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@3722 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
parent
f917704e61
commit
37b8aa325b
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2010 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.
|
||||
|
|
@ -122,6 +122,7 @@ public class OracleLobHandler extends AbstractLobHandler {
|
|||
* See SimpleNativeJdbcExtractor's javadoc for details.
|
||||
* @see org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor#getNativeConnectionFromStatement
|
||||
* @see org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor
|
||||
* @see org.springframework.jdbc.support.nativejdbc.OracleJdbc4NativeJdbcExtractor
|
||||
* @see oracle.jdbc.OracleConnection
|
||||
*/
|
||||
public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) {
|
||||
|
|
@ -144,20 +145,16 @@ public class OracleLobHandler extends AbstractLobHandler {
|
|||
* Set whether to agressively release any resources used by the LOB. If set to <code>true</code>
|
||||
* then you can only read the LOB values once. Any subsequent reads will fail since the resources
|
||||
* have been closed.
|
||||
*
|
||||
* <p>Setting this property to <code>true</code> can be useful when your queries generates large
|
||||
* temporary LOBs that occupy space in the TEMPORARY tablespace or when you want to free up any
|
||||
* memory allocated by the driver for the LOB reading.
|
||||
*
|
||||
* <p>Default is <code>false</code>.
|
||||
*
|
||||
* @see oracle.sql.BLOB#freeTemporary
|
||||
* @see oracle.sql.CLOB#freeTemporary
|
||||
* @see oracle.sql.BLOB#open
|
||||
* @see oracle.sql.CLOB#open
|
||||
* @see oracle.sql.BLOB#close
|
||||
* @see oracle.sql.CLOB#close
|
||||
* @since 3.0
|
||||
*/
|
||||
public void setReleaseResourcesAfterRead(boolean releaseResources) {
|
||||
this.releaseResourcesAfterRead = releaseResources;
|
||||
|
|
@ -258,27 +255,25 @@ public class OracleLobHandler extends AbstractLobHandler {
|
|||
|
||||
/**
|
||||
* Initialize any LOB resources before a read is done.
|
||||
*
|
||||
* <p>This implementation calls
|
||||
* <code>BLOB.open(BLOB.MODE_READONLY)</code> or <code>CLOB.open(CLOB.MODE_READONLY)</code>
|
||||
* on any non-temporary LOBs
|
||||
* if <code>releaseResourcesAfterRead</code> property is set to <code>true</code>.
|
||||
* <p>This implementation calls <code>BLOB.open(BLOB.MODE_READONLY)</code> or
|
||||
* <code>CLOB.open(CLOB.MODE_READONLY)</code> on any non-temporary LOBs if
|
||||
* <code>releaseResourcesAfterRead</code> property is set to <code>true</code>.
|
||||
* <p>This method can be overridden by sublcasses if different behavior is desired.
|
||||
* @param con the connection to be usde for initilization
|
||||
* @param lob the LOB to initialize
|
||||
*/
|
||||
protected void initializeResourcesBeforeRead(Connection con, Object lob) {
|
||||
if (releaseResourcesAfterRead) {
|
||||
if (this.releaseResourcesAfterRead) {
|
||||
initOracleDriverClasses(con);
|
||||
try {
|
||||
/*
|
||||
if (!((BLOB)lob.isTemporary() {
|
||||
if (!((BLOB) lob.isTemporary() {
|
||||
*/
|
||||
Method isTemporary = lob.getClass().getMethod("isTemporary");
|
||||
Boolean temporary = (Boolean) isTemporary.invoke(lob);
|
||||
if (!temporary) {
|
||||
/*
|
||||
((BLOB)lob).open(BLOB.MODE_READONLY);
|
||||
((BLOB) lob).open(BLOB.MODE_READONLY);
|
||||
*/
|
||||
Method open = lob.getClass().getMethod("open", int.class);
|
||||
open.invoke(lob, modeReadOnlyConstants.get(lob.getClass()));
|
||||
|
|
@ -295,44 +290,42 @@ public class OracleLobHandler extends AbstractLobHandler {
|
|||
|
||||
/**
|
||||
* Release any LOB resources after read is complete.
|
||||
*
|
||||
* <p>If <code>releaseResourcesAfterRead</code> property is set to <code>true</code>
|
||||
* then this implementation calls
|
||||
* <code>BLOB.close()</code> or <code>CLOB.close()</code>
|
||||
* on any non-temporary LOBs that are open or
|
||||
* <code>BLOB.freeTemporary()</code> or <code>CLOB.freeTemporary()</code>
|
||||
* on any temporary LOBs.
|
||||
*
|
||||
* <p>This method can be overridden by sublcasses if different behavior is desired.
|
||||
* @param con the connection to be usde for initilization
|
||||
* @param lob the LOB to initialize
|
||||
*/
|
||||
protected void releaseResourcesAfterRead(Connection con, Object lob) {
|
||||
if (releaseResourcesAfterRead) {
|
||||
if (this.releaseResourcesAfterRead) {
|
||||
initOracleDriverClasses(con);
|
||||
Boolean temporary = Boolean.FALSE;
|
||||
try {
|
||||
/*
|
||||
if (((BLOB)lob.isTemporary() {
|
||||
if (((BLOB) lob.isTemporary() {
|
||||
*/
|
||||
Method isTemporary = lob.getClass().getMethod("isTemporary");
|
||||
temporary = (Boolean) isTemporary.invoke(lob);
|
||||
if (temporary) {
|
||||
/*
|
||||
((BLOB)lob).freeTemporary();
|
||||
((BLOB) lob).freeTemporary();
|
||||
*/
|
||||
Method freeTemporary = lob.getClass().getMethod("freeTemporary");
|
||||
freeTemporary.invoke(lob);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
if (((BLOB)lob.isOpen() {
|
||||
if (((BLOB) lob.isOpen() {
|
||||
*/
|
||||
Method isOpen = lob.getClass().getMethod("isOpen");
|
||||
Boolean open = (Boolean) isOpen.invoke(lob);
|
||||
if (open) {
|
||||
/*
|
||||
((BLOB)lob).close();
|
||||
((BLOB) lob).close();
|
||||
*/
|
||||
Method close = lob.getClass().getMethod("close");
|
||||
close.invoke(lob);
|
||||
|
|
@ -358,6 +351,7 @@ public class OracleLobHandler extends AbstractLobHandler {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* LobCreator implementation for Oracle databases.
|
||||
* Creates Oracle-style temporary BLOBs and CLOBs that it frees on close.
|
||||
|
|
@ -529,8 +523,8 @@ public class OracleLobHandler extends AbstractLobHandler {
|
|||
protected Connection getOracleConnection(PreparedStatement ps)
|
||||
throws SQLException, ClassNotFoundException {
|
||||
|
||||
return (nativeJdbcExtractor != null) ?
|
||||
nativeJdbcExtractor.getNativeConnectionFromStatement(ps) : ps.getConnection();
|
||||
return (nativeJdbcExtractor != null ?
|
||||
nativeJdbcExtractor.getNativeConnectionFromStatement(ps) : ps.getConnection());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2010 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.
|
||||
|
|
@ -26,10 +26,16 @@ import java.sql.Statement;
|
|||
/**
|
||||
* {@link NativeJdbcExtractor} implementation that delegates to JDBC 4.0's
|
||||
* <code>unwrap</code> 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)!
|
||||
* <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
|
||||
|
|
@ -40,29 +46,76 @@ import java.sql.Statement;
|
|||
*/
|
||||
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</code>.
|
||||
*/
|
||||
public void setConnectionType(Class<? extends Connection> connectionType) {
|
||||
this.connectionType = connectionType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the vendor's Statement type, e.g. <code>oracle.jdbc.OracleStatement</code>.
|
||||
*/
|
||||
public void setStatementType(Class<? extends Statement> statementType) {
|
||||
this.statementType = statementType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the vendor's PreparedStatement type, e.g. <code>oracle.jdbc.OraclePreparedStatement</code>.
|
||||
*/
|
||||
public void setPreparedStatementType(Class<? extends PreparedStatement> preparedStatementType) {
|
||||
this.preparedStatementType = preparedStatementType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the vendor's CallableStatement type, e.g. <code>oracle.jdbc.OracleCallableStatement</code>.
|
||||
*/
|
||||
public void setCallableStatementType(Class<? extends CallableStatement> callableStatementType) {
|
||||
this.callableStatementType = callableStatementType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the vendor's ResultSet type, e.g. <code>oracle.jdbc.OracleResultSet</code>.
|
||||
*/
|
||||
public void setResultSetType(Class<? extends ResultSet> resultSetType) {
|
||||
this.resultSetType = resultSetType;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Connection doGetNativeConnection(Connection con) throws SQLException {
|
||||
return (Connection) con.unwrap(Connection.class);
|
||||
return con.unwrap(this.connectionType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement getNativeStatement(Statement stmt) throws SQLException {
|
||||
return (Statement) stmt.unwrap(Statement.class);
|
||||
return stmt.unwrap(this.statementType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement getNativePreparedStatement(PreparedStatement ps) throws SQLException {
|
||||
return (PreparedStatement) ps.unwrap(PreparedStatement.class);
|
||||
return ps.unwrap(this.preparedStatementType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallableStatement getNativeCallableStatement(CallableStatement cs) throws SQLException {
|
||||
return (CallableStatement) cs.unwrap(CallableStatement.class);
|
||||
return cs.unwrap(this.callableStatementType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getNativeResultSet(ResultSet rs) throws SQLException {
|
||||
return (ResultSet) rs.unwrap(ResultSet.class);
|
||||
return rs.unwrap(this.resultSetType);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright 2002-2010 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</code>
|
||||
* <li><code>oracle.jdbc.OracleStatement</code>
|
||||
* <li><code>oracle.jdbc.OraclePreparedStatement</code>
|
||||
* <li><code>oracle.jdbc.OracleCallableStatement</code>
|
||||
* <li><code>oracle.jdbc.OracleResultSet</code>
|
||||
* </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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ Bundle-ManifestVersion: 2
|
|||
Import-Package:
|
||||
com.ibm.websphere.rsadapter;version="0";resolution:=optional,
|
||||
com.ibm.ws.rsadapter.jdbc;version="0";resolution:=optional,
|
||||
oracle.jdbc;version="0";resolution:=optional,
|
||||
oracle.sql;version="0";resolution:=optional,
|
||||
org.h2;version="[1.8.0, 2.0.0)";resolution:=optional,
|
||||
org.hsqldb;version="[1.0.0, 2.0.0)";resolution:=optional,
|
||||
|
|
|
|||
Loading…
Reference in New Issue