001/* 002 * Copyright 2002-2015 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 * https://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 017package org.springframework.jdbc.support.nativejdbc; 018 019/** 020 * A 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()}. 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} does not get wrapped, returning the 030 * native Connection of the JDBC driver on {@code metaData.getConnection()}. 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, which 039 * just needs Connection unwrapping via the {@link #getNativeConnectionFromStatement} 040 * method. This usage will work with almost any connection pool. 041 * 042 * <p>For full usage with JdbcTemplate, i.e. to also provide Statement unwrapping: 043 * <ul> 044 * <li>Use a default SimpleNativeJdbcExtractor for Resin and SJSAS (no JDBC 045 * Statement objects are wrapped, therefore no special unwrapping is necessary). 046 * <li>Use a SimpleNativeJdbcExtractor with all "nativeConnectionNecessaryForXxx" 047 * flags set to "true" for C3P0 (all JDBC Statement objects are wrapped, 048 * but none of the wrappers allow for unwrapping). 049 * <li>Use a CommonsDbcpNativeJdbcExtractor for Apache Commons DBCP or a 050 * JBossNativeJdbcExtractor for JBoss (all JDBC Statement objects are wrapped, 051 * but all of them can be extracted by casting to implementation classes). 052 * </ul> 053 * 054 * @author Juergen Hoeller 055 * @since 05.12.2003 056 * @see #setNativeConnectionNecessaryForNativeStatements 057 * @see #setNativeConnectionNecessaryForNativePreparedStatements 058 * @see #setNativeConnectionNecessaryForNativeCallableStatements 059 * @see Jdbc4NativeJdbcExtractor 060 * @see org.springframework.jdbc.core.JdbcTemplate#setNativeJdbcExtractor 061 * @see org.springframework.jdbc.support.lob.OracleLobHandler#setNativeJdbcExtractor 062 */ 063public class SimpleNativeJdbcExtractor extends NativeJdbcExtractorAdapter { 064 065 private boolean nativeConnectionNecessaryForNativeStatements = false; 066 067 private boolean nativeConnectionNecessaryForNativePreparedStatements = false; 068 069 private boolean nativeConnectionNecessaryForNativeCallableStatements = false; 070 071 072 /** 073 * Set whether it is necessary to work on the native Connection to 074 * receive native Statements. Default is "false". If true, the Connection 075 * will be unwrapped first to create a Statement. 076 * <p>This makes sense if you need to work with native Statements from 077 * a pool that does not allow to extract the native JDBC objects from its 078 * wrappers but returns the native Connection on DatabaseMetaData.getConnection. 079 * <p>The standard SimpleNativeJdbcExtractor is unable to unwrap statements, 080 * so set this to true if your connection pool wraps Statements. 081 * @see java.sql.Connection#createStatement 082 * @see java.sql.DatabaseMetaData#getConnection 083 */ 084 public void setNativeConnectionNecessaryForNativeStatements(boolean nativeConnectionNecessaryForNativeStatements) { 085 this.nativeConnectionNecessaryForNativeStatements = nativeConnectionNecessaryForNativeStatements; 086 } 087 088 @Override 089 public boolean isNativeConnectionNecessaryForNativeStatements() { 090 return this.nativeConnectionNecessaryForNativeStatements; 091 } 092 093 /** 094 * Set whether it is necessary to work on the native Connection to 095 * receive native PreparedStatements. Default is "false". If true, 096 * the Connection will be unwrapped first to create a PreparedStatement. 097 * <p>This makes sense if you need to work with native PreparedStatements from 098 * a pool that does not allow to extract the native JDBC objects from its 099 * wrappers but returns the native Connection on Statement.getConnection. 100 * <p>The standard SimpleNativeJdbcExtractor is unable to unwrap statements, 101 * so set this to true if your connection pool wraps PreparedStatements. 102 * @see java.sql.Connection#prepareStatement 103 * @see java.sql.DatabaseMetaData#getConnection 104 */ 105 public void setNativeConnectionNecessaryForNativePreparedStatements(boolean nativeConnectionNecessary) { 106 this.nativeConnectionNecessaryForNativePreparedStatements = nativeConnectionNecessary; 107 } 108 109 @Override 110 public boolean isNativeConnectionNecessaryForNativePreparedStatements() { 111 return this.nativeConnectionNecessaryForNativePreparedStatements; 112 } 113 114 /** 115 * Set whether it is necessary to work on the native Connection to 116 * receive native CallableStatements. Default is "false". If true, 117 * the Connection will be unwrapped first to create a CallableStatement. 118 * <p>This makes sense if you need to work with native CallableStatements from 119 * a pool that does not allow to extract the native JDBC objects from its 120 * wrappers but returns the native Connection on Statement.getConnection. 121 * <p>The standard SimpleNativeJdbcExtractor is unable to unwrap statements, 122 * so set this to true if your connection pool wraps CallableStatements. 123 * @see java.sql.Connection#prepareCall 124 * @see java.sql.DatabaseMetaData#getConnection 125 */ 126 public void setNativeConnectionNecessaryForNativeCallableStatements(boolean nativeConnectionNecessary) { 127 this.nativeConnectionNecessaryForNativeCallableStatements = nativeConnectionNecessary; 128 } 129 130 @Override 131 public boolean isNativeConnectionNecessaryForNativeCallableStatements() { 132 return this.nativeConnectionNecessaryForNativeCallableStatements; 133 } 134 135}