14 changed files with 0 additions and 2491 deletions
@ -1,65 +0,0 @@
@@ -1,65 +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.orm.ibatis; |
||||
|
||||
import java.sql.SQLException; |
||||
|
||||
import com.ibatis.sqlmap.client.SqlMapExecutor; |
||||
|
||||
/** |
||||
* Callback interface for data access code that works with the iBATIS |
||||
* {@link com.ibatis.sqlmap.client.SqlMapExecutor} interface. To be used |
||||
* with {@link SqlMapClientTemplate}'s {@code execute} method, |
||||
* assumably often as anonymous classes within a method implementation. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 24.02.2004 |
||||
* @see SqlMapClientTemplate |
||||
* @see org.springframework.jdbc.datasource.DataSourceTransactionManager |
||||
* @deprecated as of Spring 3.2, in favor of the native Spring support |
||||
* in the Mybatis follow-up project (http://code.google.com/p/mybatis/)
|
||||
*/ |
||||
@Deprecated |
||||
public interface SqlMapClientCallback<T> { |
||||
|
||||
/** |
||||
* Gets called by {@code SqlMapClientTemplate.execute} with an active |
||||
* {@code SqlMapExecutor}. Does not need to care about activating |
||||
* or closing the {@code SqlMapExecutor}, or handling transactions. |
||||
* |
||||
* <p>If called without a thread-bound JDBC transaction (initiated by |
||||
* DataSourceTransactionManager), the code will simply get executed on the |
||||
* underlying JDBC connection with its transactional semantics. If using |
||||
* a JTA-aware DataSource, the JDBC connection and thus the callback code |
||||
* will be transactional if a JTA transaction is active. |
||||
* |
||||
* <p>Allows for returning a result object created within the callback, |
||||
* i.e. a domain object or a collection of domain objects. |
||||
* A thrown custom RuntimeException is treated as an application exception: |
||||
* It gets propagated to the caller of the template. |
||||
* |
||||
* @param executor an active iBATIS SqlMapSession, passed-in as |
||||
* SqlMapExecutor interface here to avoid manual lifecycle handling |
||||
* @return a result object, or {@code null} if none |
||||
* @throws SQLException if thrown by the iBATIS SQL Maps API |
||||
* @see SqlMapClientTemplate#execute |
||||
* @see SqlMapClientTemplate#executeWithListResult |
||||
* @see SqlMapClientTemplate#executeWithMapResult |
||||
*/ |
||||
T doInSqlMapClient(SqlMapExecutor executor) throws SQLException; |
||||
|
||||
} |
||||
@ -1,420 +0,0 @@
@@ -1,420 +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.orm.ibatis; |
||||
|
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.lang.reflect.Field; |
||||
import java.util.Properties; |
||||
import javax.sql.DataSource; |
||||
|
||||
import com.ibatis.common.xml.NodeletException; |
||||
import com.ibatis.sqlmap.client.SqlMapClient; |
||||
import com.ibatis.sqlmap.client.SqlMapClientBuilder; |
||||
import com.ibatis.sqlmap.engine.builder.xml.SqlMapConfigParser; |
||||
import com.ibatis.sqlmap.engine.builder.xml.SqlMapParser; |
||||
import com.ibatis.sqlmap.engine.builder.xml.XmlParserState; |
||||
import com.ibatis.sqlmap.engine.impl.ExtendedSqlMapClient; |
||||
import com.ibatis.sqlmap.engine.transaction.TransactionConfig; |
||||
import com.ibatis.sqlmap.engine.transaction.TransactionManager; |
||||
import com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig; |
||||
|
||||
import org.springframework.beans.factory.FactoryBean; |
||||
import org.springframework.beans.factory.InitializingBean; |
||||
import org.springframework.core.NestedIOException; |
||||
import org.springframework.core.io.Resource; |
||||
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; |
||||
import org.springframework.jdbc.support.lob.LobHandler; |
||||
import org.springframework.util.ObjectUtils; |
||||
|
||||
/** |
||||
* {@link org.springframework.beans.factory.FactoryBean} that creates an |
||||
* iBATIS {@link com.ibatis.sqlmap.client.SqlMapClient}. This is the usual |
||||
* way to set up a shared iBATIS SqlMapClient in a Spring application context; |
||||
* the SqlMapClient can then be passed to iBATIS-based DAOs via dependency |
||||
* injection. |
||||
* |
||||
* <p>Either {@link org.springframework.jdbc.datasource.DataSourceTransactionManager} |
||||
* or {@link org.springframework.transaction.jta.JtaTransactionManager} can be |
||||
* used for transaction demarcation in combination with a SqlMapClient, |
||||
* with JTA only necessary for transactions which span multiple databases. |
||||
* |
||||
* <p>Allows for specifying a DataSource at the SqlMapClient level. This |
||||
* is preferable to per-DAO DataSource references, as it allows for lazy |
||||
* loading and avoids repeated DataSource references in every DAO. |
||||
* |
||||
* <p><b>Note:</b> As of Spring 2.5.5, this class (finally) requires iBATIS 2.3 |
||||
* or higher. The new "mappingLocations" feature requires iBATIS 2.3.2. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 24.02.2004 |
||||
* @see #setConfigLocation |
||||
* @see #setDataSource |
||||
* @see SqlMapClientTemplate#setSqlMapClient |
||||
* @see SqlMapClientTemplate#setDataSource |
||||
* @deprecated as of Spring 3.2, in favor of the native Spring support |
||||
* in the Mybatis follow-up project (http://code.google.com/p/mybatis/)
|
||||
*/ |
||||
@Deprecated |
||||
public class SqlMapClientFactoryBean implements FactoryBean<SqlMapClient>, InitializingBean { |
||||
|
||||
private static final ThreadLocal<LobHandler> configTimeLobHandlerHolder = new ThreadLocal<LobHandler>(); |
||||
|
||||
/** |
||||
* Return the LobHandler for the currently configured iBATIS SqlMapClient, |
||||
* to be used by TypeHandler implementations like ClobStringTypeHandler. |
||||
* <p>This instance will be set before initialization of the corresponding |
||||
* SqlMapClient, and reset immediately afterwards. It is thus only available |
||||
* during configuration. |
||||
* @see #setLobHandler |
||||
* @see org.springframework.orm.ibatis.support.ClobStringTypeHandler |
||||
* @see org.springframework.orm.ibatis.support.BlobByteArrayTypeHandler |
||||
* @see org.springframework.orm.ibatis.support.BlobSerializableTypeHandler |
||||
*/ |
||||
public static LobHandler getConfigTimeLobHandler() { |
||||
return configTimeLobHandlerHolder.get(); |
||||
} |
||||
|
||||
|
||||
private Resource[] configLocations; |
||||
|
||||
private Resource[] mappingLocations; |
||||
|
||||
private Properties sqlMapClientProperties; |
||||
|
||||
private DataSource dataSource; |
||||
|
||||
private boolean useTransactionAwareDataSource = true; |
||||
|
||||
private Class transactionConfigClass = ExternalTransactionConfig.class; |
||||
|
||||
private Properties transactionConfigProperties; |
||||
|
||||
private LobHandler lobHandler; |
||||
|
||||
private SqlMapClient sqlMapClient; |
||||
|
||||
|
||||
public SqlMapClientFactoryBean() { |
||||
this.transactionConfigProperties = new Properties(); |
||||
this.transactionConfigProperties.setProperty("SetAutoCommitAllowed", "false"); |
||||
} |
||||
|
||||
/** |
||||
* Set the location of the iBATIS SqlMapClient config file. |
||||
* A typical value is "WEB-INF/sql-map-config.xml". |
||||
* @see #setConfigLocations |
||||
*/ |
||||
public void setConfigLocation(Resource configLocation) { |
||||
this.configLocations = (configLocation != null ? new Resource[] {configLocation} : null); |
||||
} |
||||
|
||||
/** |
||||
* Set multiple locations of iBATIS SqlMapClient config files that |
||||
* are going to be merged into one unified configuration at runtime. |
||||
*/ |
||||
public void setConfigLocations(Resource[] configLocations) { |
||||
this.configLocations = configLocations; |
||||
} |
||||
|
||||
/** |
||||
* Set locations of iBATIS sql-map mapping files that are going to be |
||||
* merged into the SqlMapClient configuration at runtime. |
||||
* <p>This is an alternative to specifying "<sqlMap>" entries |
||||
* in a sql-map-client config file. This property being based on Spring's |
||||
* resource abstraction also allows for specifying resource patterns here: |
||||
* e.g. "/myApp/*-map.xml". |
||||
* <p>Note that this feature requires iBATIS 2.3.2; it will not work |
||||
* with any previous iBATIS version. |
||||
*/ |
||||
public void setMappingLocations(Resource[] mappingLocations) { |
||||
this.mappingLocations = mappingLocations; |
||||
} |
||||
|
||||
/** |
||||
* Set optional properties to be passed into the SqlMapClientBuilder, as |
||||
* alternative to a {@code <properties>} tag in the sql-map-config.xml |
||||
* file. Will be used to resolve placeholders in the config file. |
||||
* @see #setConfigLocation |
||||
* @see com.ibatis.sqlmap.client.SqlMapClientBuilder#buildSqlMapClient(java.io.InputStream, java.util.Properties) |
||||
*/ |
||||
public void setSqlMapClientProperties(Properties sqlMapClientProperties) { |
||||
this.sqlMapClientProperties = sqlMapClientProperties; |
||||
} |
||||
|
||||
/** |
||||
* Set the DataSource to be used by iBATIS SQL Maps. This will be passed to the |
||||
* SqlMapClient as part of a TransactionConfig instance. |
||||
* <p>If specified, this will override corresponding settings in the SqlMapClient |
||||
* properties. Usually, you will specify DataSource and transaction configuration |
||||
* <i>either</i> here <i>or</i> in SqlMapClient properties. |
||||
* <p>Specifying a DataSource for the SqlMapClient rather than for each individual |
||||
* DAO allows for lazy loading, for example when using PaginatedList results. |
||||
* <p>With a DataSource passed in here, you don't need to specify one for each DAO. |
||||
* Passing the SqlMapClient to the DAOs is enough, as it already carries a DataSource. |
||||
* Thus, it's recommended to specify the DataSource at this central location only. |
||||
* <p>Thanks to Brandon Goodin from the iBATIS team for the hint on how to make |
||||
* this work with Spring's integration strategy! |
||||
* @see #setTransactionConfigClass |
||||
* @see #setTransactionConfigProperties |
||||
* @see com.ibatis.sqlmap.client.SqlMapClient#getDataSource |
||||
* @see SqlMapClientTemplate#setDataSource |
||||
*/ |
||||
public void setDataSource(DataSource dataSource) { |
||||
this.dataSource = dataSource; |
||||
} |
||||
|
||||
/** |
||||
* Set whether to use a transaction-aware DataSource for the SqlMapClient, |
||||
* i.e. whether to automatically wrap the passed-in DataSource with Spring's |
||||
* TransactionAwareDataSourceProxy. |
||||
* <p>Default is "true": When the SqlMapClient performs direct database operations |
||||
* outside of Spring's SqlMapClientTemplate (for example, lazy loading or direct |
||||
* SqlMapClient access), it will still participate in active Spring-managed |
||||
* transactions. |
||||
* <p>As a further effect, using a transaction-aware DataSource will apply |
||||
* remaining transaction timeouts to all created JDBC Statements. This means |
||||
* that all operations performed by the SqlMapClient will automatically |
||||
* participate in Spring-managed transaction timeouts. |
||||
* <p>Turn this flag off to get raw DataSource handling, without Spring transaction |
||||
* checks. Operations on Spring's SqlMapClientTemplate will still detect |
||||
* Spring-managed transactions, but lazy loading or direct SqlMapClient access won't. |
||||
* @see #setDataSource |
||||
* @see org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy |
||||
* @see org.springframework.jdbc.datasource.DataSourceTransactionManager |
||||
* @see SqlMapClientTemplate |
||||
* @see com.ibatis.sqlmap.client.SqlMapClient |
||||
*/ |
||||
public void setUseTransactionAwareDataSource(boolean useTransactionAwareDataSource) { |
||||
this.useTransactionAwareDataSource = useTransactionAwareDataSource; |
||||
} |
||||
|
||||
/** |
||||
* Set the iBATIS TransactionConfig class to use. Default is |
||||
* {@code com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig}. |
||||
* <p>Will only get applied when using a Spring-managed DataSource. |
||||
* An instance of this class will get populated with the given DataSource |
||||
* and initialized with the given properties. |
||||
* <p>The default ExternalTransactionConfig is appropriate if there is |
||||
* external transaction management that the SqlMapClient should participate |
||||
* in: be it Spring transaction management, EJB CMT or plain JTA. This |
||||
* should be the typical scenario. If there is no active transaction, |
||||
* SqlMapClient operations will execute SQL statements non-transactionally. |
||||
* <p>JdbcTransactionConfig or JtaTransactionConfig is only necessary |
||||
* when using the iBATIS SqlMapTransactionManager API instead of external |
||||
* transactions. If there is no explicit transaction, SqlMapClient operations |
||||
* will automatically start a transaction for their own scope (in contrast |
||||
* to the external transaction mode, see above). |
||||
* <p><b>It is strongly recommended to use iBATIS SQL Maps with Spring |
||||
* transaction management (or EJB CMT).</b> In this case, the default |
||||
* ExternalTransactionConfig is fine. Lazy loading and SQL Maps operations |
||||
* without explicit transaction demarcation will execute non-transactionally. |
||||
* <p>Even with Spring transaction management, it might be desirable to |
||||
* specify JdbcTransactionConfig: This will still participate in existing |
||||
* Spring-managed transactions, but lazy loading and operations without |
||||
* explicit transaction demaration will execute in their own auto-started |
||||
* transactions. However, this is usually not necessary. |
||||
* @see #setDataSource |
||||
* @see #setTransactionConfigProperties |
||||
* @see com.ibatis.sqlmap.engine.transaction.TransactionConfig |
||||
* @see com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig |
||||
* @see com.ibatis.sqlmap.engine.transaction.jdbc.JdbcTransactionConfig |
||||
* @see com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig |
||||
* @see com.ibatis.sqlmap.client.SqlMapTransactionManager |
||||
*/ |
||||
public void setTransactionConfigClass(Class transactionConfigClass) { |
||||
if (transactionConfigClass == null || !TransactionConfig.class.isAssignableFrom(transactionConfigClass)) { |
||||
throw new IllegalArgumentException("Invalid transactionConfigClass: does not implement " + |
||||
"com.ibatis.sqlmap.engine.transaction.TransactionConfig"); |
||||
} |
||||
this.transactionConfigClass = transactionConfigClass; |
||||
} |
||||
|
||||
/** |
||||
* Set properties to be passed to the TransactionConfig instance used |
||||
* by this SqlMapClient. Supported properties depend on the concrete |
||||
* TransactionConfig implementation used: |
||||
* <p><ul> |
||||
* <li><b>ExternalTransactionConfig</b> supports "DefaultAutoCommit" |
||||
* (default: false) and "SetAutoCommitAllowed" (default: true). |
||||
* Note that Spring uses SetAutoCommitAllowed = false as default, |
||||
* in contrast to the iBATIS default, to always keep the original |
||||
* autoCommit value as provided by the connection pool. |
||||
* <li><b>JdbcTransactionConfig</b> does not supported any properties. |
||||
* <li><b>JtaTransactionConfig</b> supports "UserTransaction" |
||||
* (no default), specifying the JNDI location of the JTA UserTransaction |
||||
* (usually "java:comp/UserTransaction"). |
||||
* </ul> |
||||
* @see com.ibatis.sqlmap.engine.transaction.TransactionConfig#initialize |
||||
* @see com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig |
||||
* @see com.ibatis.sqlmap.engine.transaction.jdbc.JdbcTransactionConfig |
||||
* @see com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig |
||||
*/ |
||||
public void setTransactionConfigProperties(Properties transactionConfigProperties) { |
||||
this.transactionConfigProperties = transactionConfigProperties; |
||||
} |
||||
|
||||
/** |
||||
* Set the LobHandler to be used by the SqlMapClient. |
||||
* Will be exposed at config time for TypeHandler implementations. |
||||
* @see #getConfigTimeLobHandler |
||||
* @see com.ibatis.sqlmap.engine.type.TypeHandler |
||||
* @see org.springframework.orm.ibatis.support.ClobStringTypeHandler |
||||
* @see org.springframework.orm.ibatis.support.BlobByteArrayTypeHandler |
||||
* @see org.springframework.orm.ibatis.support.BlobSerializableTypeHandler |
||||
*/ |
||||
public void setLobHandler(LobHandler lobHandler) { |
||||
this.lobHandler = lobHandler; |
||||
} |
||||
|
||||
|
||||
public void afterPropertiesSet() throws Exception { |
||||
if (this.lobHandler != null) { |
||||
// Make given LobHandler available for SqlMapClient configuration.
|
||||
// Do early because because mapping resource might refer to custom types.
|
||||
configTimeLobHandlerHolder.set(this.lobHandler); |
||||
} |
||||
|
||||
try { |
||||
this.sqlMapClient = buildSqlMapClient(this.configLocations, this.mappingLocations, this.sqlMapClientProperties); |
||||
|
||||
// Tell the SqlMapClient to use the given DataSource, if any.
|
||||
if (this.dataSource != null) { |
||||
TransactionConfig transactionConfig = (TransactionConfig) this.transactionConfigClass.newInstance(); |
||||
DataSource dataSourceToUse = this.dataSource; |
||||
if (this.useTransactionAwareDataSource && !(this.dataSource instanceof TransactionAwareDataSourceProxy)) { |
||||
dataSourceToUse = new TransactionAwareDataSourceProxy(this.dataSource); |
||||
} |
||||
transactionConfig.setDataSource(dataSourceToUse); |
||||
transactionConfig.initialize(this.transactionConfigProperties); |
||||
applyTransactionConfig(this.sqlMapClient, transactionConfig); |
||||
} |
||||
} |
||||
|
||||
finally { |
||||
if (this.lobHandler != null) { |
||||
// Reset LobHandler holder.
|
||||
configTimeLobHandlerHolder.remove(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Build a SqlMapClient instance based on the given standard configuration. |
||||
* <p>The default implementation uses the standard iBATIS {@link SqlMapClientBuilder} |
||||
* API to build a SqlMapClient instance based on an InputStream (if possible, |
||||
* on iBATIS 2.3 and higher) or on a Reader (on iBATIS up to version 2.2). |
||||
* @param configLocations the config files to load from |
||||
* @param properties the SqlMapClient properties (if any) |
||||
* @return the SqlMapClient instance (never {@code null}) |
||||
* @throws IOException if loading the config file failed |
||||
* @see com.ibatis.sqlmap.client.SqlMapClientBuilder#buildSqlMapClient |
||||
*/ |
||||
protected SqlMapClient buildSqlMapClient( |
||||
Resource[] configLocations, Resource[] mappingLocations, Properties properties) |
||||
throws IOException { |
||||
|
||||
if (ObjectUtils.isEmpty(configLocations)) { |
||||
throw new IllegalArgumentException("At least 1 'configLocation' entry is required"); |
||||
} |
||||
|
||||
SqlMapClient client = null; |
||||
SqlMapConfigParser configParser = new SqlMapConfigParser(); |
||||
for (Resource configLocation : configLocations) { |
||||
InputStream is = configLocation.getInputStream(); |
||||
try { |
||||
client = configParser.parse(is, properties); |
||||
} |
||||
catch (RuntimeException ex) { |
||||
throw new NestedIOException("Failed to parse config resource: " + configLocation, ex.getCause()); |
||||
} |
||||
} |
||||
|
||||
if (mappingLocations != null) { |
||||
SqlMapParser mapParser = SqlMapParserFactory.createSqlMapParser(configParser); |
||||
for (Resource mappingLocation : mappingLocations) { |
||||
try { |
||||
mapParser.parse(mappingLocation.getInputStream()); |
||||
} |
||||
catch (NodeletException ex) { |
||||
throw new NestedIOException("Failed to parse mapping resource: " + mappingLocation, ex); |
||||
} |
||||
} |
||||
} |
||||
|
||||
return client; |
||||
} |
||||
|
||||
/** |
||||
* Apply the given iBATIS TransactionConfig to the SqlMapClient. |
||||
* <p>The default implementation casts to ExtendedSqlMapClient, retrieves the maximum |
||||
* number of concurrent transactions from the SqlMapExecutorDelegate, and sets |
||||
* an iBATIS TransactionManager with the given TransactionConfig. |
||||
* @param sqlMapClient the SqlMapClient to apply the TransactionConfig to |
||||
* @param transactionConfig the iBATIS TransactionConfig to apply |
||||
* @see com.ibatis.sqlmap.engine.impl.ExtendedSqlMapClient |
||||
* @see com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate#getMaxTransactions |
||||
* @see com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate#setTxManager |
||||
*/ |
||||
protected void applyTransactionConfig(SqlMapClient sqlMapClient, TransactionConfig transactionConfig) { |
||||
if (!(sqlMapClient instanceof ExtendedSqlMapClient)) { |
||||
throw new IllegalArgumentException( |
||||
"Cannot set TransactionConfig with DataSource for SqlMapClient if not of type " + |
||||
"ExtendedSqlMapClient: " + sqlMapClient); |
||||
} |
||||
ExtendedSqlMapClient extendedClient = (ExtendedSqlMapClient) sqlMapClient; |
||||
transactionConfig.setMaximumConcurrentTransactions(extendedClient.getDelegate().getMaxTransactions()); |
||||
extendedClient.getDelegate().setTxManager(new TransactionManager(transactionConfig)); |
||||
} |
||||
|
||||
|
||||
public SqlMapClient getObject() { |
||||
return this.sqlMapClient; |
||||
} |
||||
|
||||
public Class<? extends SqlMapClient> getObjectType() { |
||||
return (this.sqlMapClient != null ? this.sqlMapClient.getClass() : SqlMapClient.class); |
||||
} |
||||
|
||||
public boolean isSingleton() { |
||||
return true; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Inner class to avoid hard-coded iBATIS 2.3.2 dependency (XmlParserState class). |
||||
*/ |
||||
private static class SqlMapParserFactory { |
||||
|
||||
public static SqlMapParser createSqlMapParser(SqlMapConfigParser configParser) { |
||||
// Ideally: XmlParserState state = configParser.getState();
|
||||
// Should raise an enhancement request with iBATIS...
|
||||
XmlParserState state = null; |
||||
try { |
||||
Field stateField = SqlMapConfigParser.class.getDeclaredField("state"); |
||||
stateField.setAccessible(true); |
||||
state = (XmlParserState) stateField.get(configParser); |
||||
} |
||||
catch (Exception ex) { |
||||
throw new IllegalStateException("iBATIS 2.3.2 'state' field not found in SqlMapConfigParser class - " + |
||||
"please upgrade to IBATIS 2.3.2 or higher in order to use the new 'mappingLocations' feature. " + ex); |
||||
} |
||||
return new SqlMapParser(state); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -1,184 +0,0 @@
@@ -1,184 +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.orm.ibatis; |
||||
|
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import com.ibatis.sqlmap.client.event.RowHandler; |
||||
|
||||
import org.springframework.dao.DataAccessException; |
||||
|
||||
/** |
||||
* Interface that specifies a basic set of iBATIS SqlMapClient operations, |
||||
* implemented by {@link SqlMapClientTemplate}. Not often used, but a useful |
||||
* option to enhance testability, as it can easily be mocked or stubbed. |
||||
* |
||||
* <p>Defines SqlMapClientTemplate's convenience methods that mirror |
||||
* the iBATIS {@link com.ibatis.sqlmap.client.SqlMapExecutor}'s execution |
||||
* methods. Users are strongly encouraged to read the iBATIS javadocs |
||||
* for details on the semantics of those methods. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 24.02.2004 |
||||
* @see SqlMapClientTemplate |
||||
* @see com.ibatis.sqlmap.client.SqlMapClient |
||||
* @see com.ibatis.sqlmap.client.SqlMapExecutor |
||||
* @deprecated as of Spring 3.2, in favor of the native Spring support |
||||
* in the Mybatis follow-up project (http://code.google.com/p/mybatis/)
|
||||
*/ |
||||
@Deprecated |
||||
public interface SqlMapClientOperations { |
||||
|
||||
/** |
||||
* @see com.ibatis.sqlmap.client.SqlMapExecutor#queryForObject(String) |
||||
* @throws org.springframework.dao.DataAccessException in case of errors |
||||
*/ |
||||
Object queryForObject(String statementName) throws DataAccessException; |
||||
|
||||
/** |
||||
* @see com.ibatis.sqlmap.client.SqlMapExecutor#queryForObject(String, Object) |
||||
* @throws org.springframework.dao.DataAccessException in case of errors |
||||
*/ |
||||
Object queryForObject(String statementName, Object parameterObject) |
||||
throws DataAccessException; |
||||
|
||||
/** |
||||
* @see com.ibatis.sqlmap.client.SqlMapExecutor#queryForObject(String, Object, Object) |
||||
* @throws org.springframework.dao.DataAccessException in case of errors |
||||
*/ |
||||
Object queryForObject(String statementName, Object parameterObject, Object resultObject) |
||||
throws DataAccessException; |
||||
|
||||
/** |
||||
* @see com.ibatis.sqlmap.client.SqlMapExecutor#queryForList(String) |
||||
* @throws org.springframework.dao.DataAccessException in case of errors |
||||
*/ |
||||
List queryForList(String statementName) throws DataAccessException; |
||||
|
||||
/** |
||||
* @see com.ibatis.sqlmap.client.SqlMapExecutor#queryForList(String, Object) |
||||
* @throws org.springframework.dao.DataAccessException in case of errors |
||||
*/ |
||||
List queryForList(String statementName, Object parameterObject) |
||||
throws DataAccessException; |
||||
|
||||
/** |
||||
* @see com.ibatis.sqlmap.client.SqlMapExecutor#queryForList(String, int, int) |
||||
* @throws org.springframework.dao.DataAccessException in case of errors |
||||
*/ |
||||
List queryForList(String statementName, int skipResults, int maxResults) |
||||
throws DataAccessException; |
||||
|
||||
/** |
||||
* @see com.ibatis.sqlmap.client.SqlMapExecutor#queryForList(String, Object, int, int) |
||||
* @throws org.springframework.dao.DataAccessException in case of errors |
||||
*/ |
||||
List queryForList(String statementName, Object parameterObject, int skipResults, int maxResults) |
||||
throws DataAccessException; |
||||
|
||||
/** |
||||
* @see com.ibatis.sqlmap.client.SqlMapExecutor#queryWithRowHandler(String, RowHandler) |
||||
* @throws org.springframework.dao.DataAccessException in case of errors |
||||
*/ |
||||
void queryWithRowHandler(String statementName, RowHandler rowHandler) |
||||
throws DataAccessException; |
||||
|
||||
/** |
||||
* @see com.ibatis.sqlmap.client.SqlMapExecutor#queryWithRowHandler(String, Object, RowHandler) |
||||
* @throws org.springframework.dao.DataAccessException in case of errors |
||||
*/ |
||||
void queryWithRowHandler(String statementName, Object parameterObject, RowHandler rowHandler) |
||||
throws DataAccessException; |
||||
|
||||
/** |
||||
* @see com.ibatis.sqlmap.client.SqlMapExecutor#queryForMap(String, Object, String) |
||||
* @throws org.springframework.dao.DataAccessException in case of errors |
||||
*/ |
||||
Map queryForMap(String statementName, Object parameterObject, String keyProperty) |
||||
throws DataAccessException; |
||||
|
||||
/** |
||||
* @see com.ibatis.sqlmap.client.SqlMapExecutor#queryForMap(String, Object, String, String) |
||||
* @throws org.springframework.dao.DataAccessException in case of errors |
||||
*/ |
||||
Map queryForMap(String statementName, Object parameterObject, String keyProperty, String valueProperty) |
||||
throws DataAccessException; |
||||
|
||||
/** |
||||
* @see com.ibatis.sqlmap.client.SqlMapExecutor#insert(String) |
||||
* @throws org.springframework.dao.DataAccessException in case of errors |
||||
*/ |
||||
Object insert(String statementName) throws DataAccessException; |
||||
|
||||
/** |
||||
* @see com.ibatis.sqlmap.client.SqlMapExecutor#insert(String, Object) |
||||
* @throws org.springframework.dao.DataAccessException in case of errors |
||||
*/ |
||||
Object insert(String statementName, Object parameterObject) throws DataAccessException; |
||||
|
||||
/** |
||||
* @see com.ibatis.sqlmap.client.SqlMapExecutor#update(String) |
||||
* @throws org.springframework.dao.DataAccessException in case of errors |
||||
*/ |
||||
int update(String statementName) throws DataAccessException; |
||||
|
||||
/** |
||||
* @see com.ibatis.sqlmap.client.SqlMapExecutor#update(String, Object) |
||||
* @throws org.springframework.dao.DataAccessException in case of errors |
||||
*/ |
||||
int update(String statementName, Object parameterObject) throws DataAccessException; |
||||
|
||||
/** |
||||
* Convenience method provided by Spring: execute an update operation |
||||
* with an automatic check that the update affected the given required |
||||
* number of rows. |
||||
* @param statementName the name of the mapped statement |
||||
* @param parameterObject the parameter object |
||||
* @param requiredRowsAffected the number of rows that the update is |
||||
* required to affect |
||||
* @throws org.springframework.dao.DataAccessException in case of errors |
||||
*/ |
||||
void update(String statementName, Object parameterObject, int requiredRowsAffected) |
||||
throws DataAccessException; |
||||
|
||||
/** |
||||
* @see com.ibatis.sqlmap.client.SqlMapExecutor#delete(String) |
||||
* @throws org.springframework.dao.DataAccessException in case of errors |
||||
*/ |
||||
int delete(String statementName) throws DataAccessException; |
||||
|
||||
/** |
||||
* @see com.ibatis.sqlmap.client.SqlMapExecutor#delete(String, Object) |
||||
* @throws org.springframework.dao.DataAccessException in case of errors |
||||
*/ |
||||
int delete(String statementName, Object parameterObject) throws DataAccessException; |
||||
|
||||
/** |
||||
* Convenience method provided by Spring: execute a delete operation |
||||
* with an automatic check that the delete affected the given required |
||||
* number of rows. |
||||
* @param statementName the name of the mapped statement |
||||
* @param parameterObject the parameter object |
||||
* @param requiredRowsAffected the number of rows that the delete is |
||||
* required to affect |
||||
* @throws org.springframework.dao.DataAccessException in case of errors |
||||
*/ |
||||
void delete(String statementName, Object parameterObject, int requiredRowsAffected) |
||||
throws DataAccessException; |
||||
|
||||
} |
||||
@ -1,422 +0,0 @@
@@ -1,422 +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.orm.ibatis; |
||||
|
||||
import java.sql.Connection; |
||||
import java.sql.SQLException; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import javax.sql.DataSource; |
||||
|
||||
import com.ibatis.sqlmap.client.SqlMapClient; |
||||
import com.ibatis.sqlmap.client.SqlMapExecutor; |
||||
import com.ibatis.sqlmap.client.SqlMapSession; |
||||
import com.ibatis.sqlmap.client.event.RowHandler; |
||||
|
||||
import org.springframework.dao.DataAccessException; |
||||
import org.springframework.jdbc.CannotGetJdbcConnectionException; |
||||
import org.springframework.jdbc.JdbcUpdateAffectedIncorrectNumberOfRowsException; |
||||
import org.springframework.jdbc.datasource.DataSourceUtils; |
||||
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; |
||||
import org.springframework.jdbc.support.JdbcAccessor; |
||||
import org.springframework.util.Assert; |
||||
|
||||
/** |
||||
* Helper class that simplifies data access via the iBATIS |
||||
* {@link com.ibatis.sqlmap.client.SqlMapClient} API, converting checked |
||||
* SQLExceptions into unchecked DataAccessExceptions, following the |
||||
* {@code org.springframework.dao} exception hierarchy. |
||||
* Uses the same {@link org.springframework.jdbc.support.SQLExceptionTranslator} |
||||
* mechanism as {@link org.springframework.jdbc.core.JdbcTemplate}. |
||||
* |
||||
* <p>The main method of this class executes a callback that implements a |
||||
* data access action. Furthermore, this class provides numerous convenience |
||||
* methods that mirror {@link com.ibatis.sqlmap.client.SqlMapExecutor}'s |
||||
* execution methods. |
||||
* |
||||
* <p>It is generally recommended to use the convenience methods on this template |
||||
* for plain query/insert/update/delete operations. However, for more complex |
||||
* operations like batch updates, a custom SqlMapClientCallback must be implemented, |
||||
* usually as anonymous inner class. For example: |
||||
* |
||||
* <pre class="code"> |
||||
* getSqlMapClientTemplate().execute(new SqlMapClientCallback() { |
||||
* public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException { |
||||
* executor.startBatch(); |
||||
* executor.update("insertSomething", "myParamValue"); |
||||
* executor.update("insertSomethingElse", "myOtherParamValue"); |
||||
* executor.executeBatch(); |
||||
* return null; |
||||
* } |
||||
* });</pre> |
||||
* |
||||
* The template needs a SqlMapClient to work on, passed in via the "sqlMapClient" |
||||
* property. A Spring context typically uses a {@link SqlMapClientFactoryBean} |
||||
* to build the SqlMapClient. The template an additionally be configured with a |
||||
* DataSource for fetching Connections, although this is not necessary if a |
||||
* DataSource is specified for the SqlMapClient itself (typically through |
||||
* SqlMapClientFactoryBean's "dataSource" property). |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 24.02.2004 |
||||
* @see #execute |
||||
* @see #setSqlMapClient |
||||
* @see #setDataSource |
||||
* @see #setExceptionTranslator |
||||
* @see SqlMapClientFactoryBean#setDataSource |
||||
* @see com.ibatis.sqlmap.client.SqlMapClient#getDataSource |
||||
* @see com.ibatis.sqlmap.client.SqlMapExecutor |
||||
* @deprecated as of Spring 3.2, in favor of the native Spring support |
||||
* in the Mybatis follow-up project (http://code.google.com/p/mybatis/)
|
||||
*/ |
||||
@Deprecated |
||||
public class SqlMapClientTemplate extends JdbcAccessor implements SqlMapClientOperations { |
||||
|
||||
private SqlMapClient sqlMapClient; |
||||
|
||||
|
||||
/** |
||||
* Create a new SqlMapClientTemplate. |
||||
*/ |
||||
public SqlMapClientTemplate() { |
||||
} |
||||
|
||||
/** |
||||
* Create a new SqlMapTemplate. |
||||
* @param sqlMapClient iBATIS SqlMapClient that defines the mapped statements |
||||
*/ |
||||
public SqlMapClientTemplate(SqlMapClient sqlMapClient) { |
||||
setSqlMapClient(sqlMapClient); |
||||
afterPropertiesSet(); |
||||
} |
||||
|
||||
/** |
||||
* Create a new SqlMapTemplate. |
||||
* @param dataSource JDBC DataSource to obtain connections from |
||||
* @param sqlMapClient iBATIS SqlMapClient that defines the mapped statements |
||||
*/ |
||||
public SqlMapClientTemplate(DataSource dataSource, SqlMapClient sqlMapClient) { |
||||
setDataSource(dataSource); |
||||
setSqlMapClient(sqlMapClient); |
||||
afterPropertiesSet(); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Set the iBATIS Database Layer SqlMapClient that defines the mapped statements. |
||||
*/ |
||||
public void setSqlMapClient(SqlMapClient sqlMapClient) { |
||||
this.sqlMapClient = sqlMapClient; |
||||
} |
||||
|
||||
/** |
||||
* Return the iBATIS Database Layer SqlMapClient that this template works with. |
||||
*/ |
||||
public SqlMapClient getSqlMapClient() { |
||||
return this.sqlMapClient; |
||||
} |
||||
|
||||
/** |
||||
* If no DataSource specified, use SqlMapClient's DataSource. |
||||
* @see com.ibatis.sqlmap.client.SqlMapClient#getDataSource() |
||||
*/ |
||||
@Override |
||||
public DataSource getDataSource() { |
||||
DataSource ds = super.getDataSource(); |
||||
return (ds != null ? ds : this.sqlMapClient.getDataSource()); |
||||
} |
||||
|
||||
@Override |
||||
public void afterPropertiesSet() { |
||||
if (this.sqlMapClient == null) { |
||||
throw new IllegalArgumentException("Property 'sqlMapClient' is required"); |
||||
} |
||||
super.afterPropertiesSet(); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Execute the given data access action on a SqlMapExecutor. |
||||
* @param action callback object that specifies the data access action |
||||
* @return a result object returned by the action, or {@code null} |
||||
* @throws DataAccessException in case of SQL Maps errors |
||||
*/ |
||||
public <T> T execute(SqlMapClientCallback<T> action) throws DataAccessException { |
||||
Assert.notNull(action, "Callback object must not be null"); |
||||
Assert.notNull(this.sqlMapClient, "No SqlMapClient specified"); |
||||
|
||||
// We always need to use a SqlMapSession, as we need to pass a Spring-managed
|
||||
// Connection (potentially transactional) in. This shouldn't be necessary if
|
||||
// we run against a TransactionAwareDataSourceProxy underneath, but unfortunately
|
||||
// we still need it to make iBATIS batch execution work properly: If iBATIS
|
||||
// doesn't recognize an existing transaction, it automatically executes the
|
||||
// batch for every single statement...
|
||||
|
||||
SqlMapSession session = this.sqlMapClient.openSession(); |
||||
if (logger.isDebugEnabled()) { |
||||
logger.debug("Opened SqlMapSession [" + session + "] for iBATIS operation"); |
||||
} |
||||
Connection ibatisCon = null; |
||||
|
||||
try { |
||||
Connection springCon = null; |
||||
DataSource dataSource = getDataSource(); |
||||
boolean transactionAware = (dataSource instanceof TransactionAwareDataSourceProxy); |
||||
|
||||
// Obtain JDBC Connection to operate on...
|
||||
try { |
||||
ibatisCon = session.getCurrentConnection(); |
||||
if (ibatisCon == null) { |
||||
springCon = (transactionAware ? |
||||
dataSource.getConnection() : DataSourceUtils.doGetConnection(dataSource)); |
||||
session.setUserConnection(springCon); |
||||
if (logger.isDebugEnabled()) { |
||||
logger.debug("Obtained JDBC Connection [" + springCon + "] for iBATIS operation"); |
||||
} |
||||
} |
||||
else { |
||||
if (logger.isDebugEnabled()) { |
||||
logger.debug("Reusing JDBC Connection [" + ibatisCon + "] for iBATIS operation"); |
||||
} |
||||
} |
||||
} |
||||
catch (SQLException ex) { |
||||
throw new CannotGetJdbcConnectionException("Could not get JDBC Connection", ex); |
||||
} |
||||
|
||||
// Execute given callback...
|
||||
try { |
||||
return action.doInSqlMapClient(session); |
||||
} |
||||
catch (SQLException ex) { |
||||
throw getExceptionTranslator().translate("SqlMapClient operation", null, ex); |
||||
} |
||||
finally { |
||||
try { |
||||
if (springCon != null) { |
||||
if (transactionAware) { |
||||
springCon.close(); |
||||
} |
||||
else { |
||||
DataSourceUtils.doReleaseConnection(springCon, dataSource); |
||||
} |
||||
} |
||||
} |
||||
catch (Throwable ex) { |
||||
logger.debug("Could not close JDBC Connection", ex); |
||||
} |
||||
} |
||||
|
||||
// Processing finished - potentially session still to be closed.
|
||||
} |
||||
finally { |
||||
// Only close SqlMapSession if we know we've actually opened it
|
||||
// at the present level.
|
||||
if (ibatisCon == null) { |
||||
session.close(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Execute the given data access action on a SqlMapExecutor, |
||||
* expecting a List result. |
||||
* @param action callback object that specifies the data access action |
||||
* @return the List result |
||||
* @throws DataAccessException in case of SQL Maps errors |
||||
* @deprecated as of Spring 3.0 - not really needed anymore with generic |
||||
* {@link #execute} method |
||||
*/ |
||||
@Deprecated |
||||
public List executeWithListResult(SqlMapClientCallback<List> action) throws DataAccessException { |
||||
return execute(action); |
||||
} |
||||
|
||||
/** |
||||
* Execute the given data access action on a SqlMapExecutor, |
||||
* expecting a Map result. |
||||
* @param action callback object that specifies the data access action |
||||
* @return the Map result |
||||
* @throws DataAccessException in case of SQL Maps errors |
||||
* @deprecated as of Spring 3.0 - not really needed anymore with generic |
||||
* {@link #execute} method |
||||
*/ |
||||
@Deprecated |
||||
public Map executeWithMapResult(SqlMapClientCallback<Map> action) throws DataAccessException { |
||||
return execute(action); |
||||
} |
||||
|
||||
|
||||
public Object queryForObject(String statementName) throws DataAccessException { |
||||
return queryForObject(statementName, null); |
||||
} |
||||
|
||||
public Object queryForObject(final String statementName, final Object parameterObject) |
||||
throws DataAccessException { |
||||
|
||||
return execute(new SqlMapClientCallback<Object>() { |
||||
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException { |
||||
return executor.queryForObject(statementName, parameterObject); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
public Object queryForObject( |
||||
final String statementName, final Object parameterObject, final Object resultObject) |
||||
throws DataAccessException { |
||||
|
||||
return execute(new SqlMapClientCallback<Object>() { |
||||
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException { |
||||
return executor.queryForObject(statementName, parameterObject, resultObject); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
public List queryForList(String statementName) throws DataAccessException { |
||||
return queryForList(statementName, null); |
||||
} |
||||
|
||||
public List queryForList(final String statementName, final Object parameterObject) |
||||
throws DataAccessException { |
||||
|
||||
return execute(new SqlMapClientCallback<List>() { |
||||
public List doInSqlMapClient(SqlMapExecutor executor) throws SQLException { |
||||
return executor.queryForList(statementName, parameterObject); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
public List queryForList(String statementName, int skipResults, int maxResults) |
||||
throws DataAccessException { |
||||
|
||||
return queryForList(statementName, null, skipResults, maxResults); |
||||
} |
||||
|
||||
public List queryForList( |
||||
final String statementName, final Object parameterObject, final int skipResults, final int maxResults) |
||||
throws DataAccessException { |
||||
|
||||
return execute(new SqlMapClientCallback<List>() { |
||||
public List doInSqlMapClient(SqlMapExecutor executor) throws SQLException { |
||||
return executor.queryForList(statementName, parameterObject, skipResults, maxResults); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
public void queryWithRowHandler(String statementName, RowHandler rowHandler) |
||||
throws DataAccessException { |
||||
|
||||
queryWithRowHandler(statementName, null, rowHandler); |
||||
} |
||||
|
||||
public void queryWithRowHandler( |
||||
final String statementName, final Object parameterObject, final RowHandler rowHandler) |
||||
throws DataAccessException { |
||||
|
||||
execute(new SqlMapClientCallback<Object>() { |
||||
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException { |
||||
executor.queryWithRowHandler(statementName, parameterObject, rowHandler); |
||||
return null; |
||||
} |
||||
}); |
||||
} |
||||
|
||||
public Map queryForMap( |
||||
final String statementName, final Object parameterObject, final String keyProperty) |
||||
throws DataAccessException { |
||||
|
||||
return execute(new SqlMapClientCallback<Map>() { |
||||
public Map doInSqlMapClient(SqlMapExecutor executor) throws SQLException { |
||||
return executor.queryForMap(statementName, parameterObject, keyProperty); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
public Map queryForMap( |
||||
final String statementName, final Object parameterObject, final String keyProperty, final String valueProperty) |
||||
throws DataAccessException { |
||||
|
||||
return execute(new SqlMapClientCallback<Map>() { |
||||
public Map doInSqlMapClient(SqlMapExecutor executor) throws SQLException { |
||||
return executor.queryForMap(statementName, parameterObject, keyProperty, valueProperty); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
public Object insert(String statementName) throws DataAccessException { |
||||
return insert(statementName, null); |
||||
} |
||||
|
||||
public Object insert(final String statementName, final Object parameterObject) |
||||
throws DataAccessException { |
||||
|
||||
return execute(new SqlMapClientCallback<Object>() { |
||||
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException { |
||||
return executor.insert(statementName, parameterObject); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
public int update(String statementName) throws DataAccessException { |
||||
return update(statementName, null); |
||||
} |
||||
|
||||
public int update(final String statementName, final Object parameterObject) |
||||
throws DataAccessException { |
||||
|
||||
return execute(new SqlMapClientCallback<Integer>() { |
||||
public Integer doInSqlMapClient(SqlMapExecutor executor) throws SQLException { |
||||
return executor.update(statementName, parameterObject); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
public void update(String statementName, Object parameterObject, int requiredRowsAffected) |
||||
throws DataAccessException { |
||||
|
||||
int actualRowsAffected = update(statementName, parameterObject); |
||||
if (actualRowsAffected != requiredRowsAffected) { |
||||
throw new JdbcUpdateAffectedIncorrectNumberOfRowsException( |
||||
statementName, requiredRowsAffected, actualRowsAffected); |
||||
} |
||||
} |
||||
|
||||
public int delete(String statementName) throws DataAccessException { |
||||
return delete(statementName, null); |
||||
} |
||||
|
||||
public int delete(final String statementName, final Object parameterObject) |
||||
throws DataAccessException { |
||||
|
||||
return execute(new SqlMapClientCallback<Integer>() { |
||||
public Integer doInSqlMapClient(SqlMapExecutor executor) throws SQLException { |
||||
return executor.delete(statementName, parameterObject); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
public void delete(String statementName, Object parameterObject, int requiredRowsAffected) |
||||
throws DataAccessException { |
||||
|
||||
int actualRowsAffected = delete(statementName, parameterObject); |
||||
if (actualRowsAffected != requiredRowsAffected) { |
||||
throw new JdbcUpdateAffectedIncorrectNumberOfRowsException( |
||||
statementName, requiredRowsAffected, actualRowsAffected); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -1,13 +0,0 @@
@@ -1,13 +0,0 @@
|
||||
|
||||
/** |
||||
* |
||||
* Package providing integration of |
||||
* <a href="http://ibatis.apache.org">iBATIS Database Layer</a> |
||||
* with Spring concepts. |
||||
* |
||||
* <p>Contains resource helper classes and template classes for |
||||
* data access with the iBATIS SqlMapClient API. |
||||
* |
||||
*/ |
||||
package org.springframework.orm.ibatis; |
||||
|
||||
@ -1,198 +0,0 @@
@@ -1,198 +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.orm.ibatis.support; |
||||
|
||||
import java.io.IOException; |
||||
import java.sql.CallableStatement; |
||||
import java.sql.PreparedStatement; |
||||
import java.sql.ResultSet; |
||||
import java.sql.SQLException; |
||||
|
||||
import com.ibatis.sqlmap.engine.type.BaseTypeHandler; |
||||
|
||||
import org.springframework.jdbc.datasource.DataSourceUtils; |
||||
import org.springframework.jdbc.support.lob.LobCreator; |
||||
import org.springframework.jdbc.support.lob.LobHandler; |
||||
import org.springframework.orm.ibatis.SqlMapClientFactoryBean; |
||||
import org.springframework.transaction.support.TransactionSynchronizationAdapter; |
||||
import org.springframework.transaction.support.TransactionSynchronizationManager; |
||||
|
||||
/** |
||||
* Abstract base class for iBATIS TypeHandler implementations that map to LOBs. |
||||
* Retrieves the LobHandler to use from SqlMapClientFactoryBean at config time. |
||||
* |
||||
* <p>For writing LOBs, an active Spring transaction synchronization is required, |
||||
* to be able to register a synchronization that closes the LobCreator. |
||||
* |
||||
* <p>Offers template methods for setting parameters and getting result values, |
||||
* passing in the LobHandler or LobCreator to use. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 1.1.5 |
||||
* @see org.springframework.jdbc.support.lob.LobHandler |
||||
* @see org.springframework.jdbc.support.lob.LobCreator |
||||
* @see org.springframework.orm.ibatis.SqlMapClientFactoryBean#setLobHandler |
||||
* @deprecated as of Spring 3.2, in favor of the native Spring support |
||||
* in the Mybatis follow-up project (http://code.google.com/p/mybatis/)
|
||||
*/ |
||||
@Deprecated |
||||
public abstract class AbstractLobTypeHandler extends BaseTypeHandler { |
||||
|
||||
/** |
||||
* Order value for TransactionSynchronization objects that clean up LobCreators. |
||||
* Return DataSourceUtils.#CONNECTION_SYNCHRONIZATION_ORDER - 100 to execute |
||||
* LobCreator cleanup before JDBC Connection cleanup, if any. |
||||
* @see org.springframework.jdbc.datasource.DataSourceUtils#CONNECTION_SYNCHRONIZATION_ORDER |
||||
*/ |
||||
public static final int LOB_CREATOR_SYNCHRONIZATION_ORDER = |
||||
DataSourceUtils.CONNECTION_SYNCHRONIZATION_ORDER - 200; |
||||
|
||||
private LobHandler lobHandler; |
||||
|
||||
|
||||
/** |
||||
* Constructor used by iBATIS: fetches config-time LobHandler from |
||||
* SqlMapClientFactoryBean. |
||||
* @see org.springframework.orm.ibatis.SqlMapClientFactoryBean#getConfigTimeLobHandler |
||||
*/ |
||||
public AbstractLobTypeHandler() { |
||||
this(SqlMapClientFactoryBean.getConfigTimeLobHandler()); |
||||
} |
||||
|
||||
/** |
||||
* Constructor used for testing: takes an explicit LobHandler. |
||||
*/ |
||||
protected AbstractLobTypeHandler(LobHandler lobHandler) { |
||||
if (lobHandler == null) { |
||||
throw new IllegalStateException("No LobHandler found for configuration - " + |
||||
"lobHandler property must be set on SqlMapClientFactoryBean"); |
||||
} |
||||
this.lobHandler = lobHandler; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* This implementation delegates to setParameterInternal, |
||||
* passing in a transaction-synchronized LobCreator for the |
||||
* LobHandler of this type. |
||||
* @see #setParameterInternal |
||||
*/ |
||||
public final void setParameter(PreparedStatement ps, int i, Object parameter, String jdbcType) |
||||
throws SQLException { |
||||
|
||||
if (!TransactionSynchronizationManager.isSynchronizationActive()) { |
||||
throw new IllegalStateException("Spring transaction synchronization needs to be active for " + |
||||
"setting values in iBATIS TypeHandlers that delegate to a Spring LobHandler"); |
||||
} |
||||
final LobCreator lobCreator = this.lobHandler.getLobCreator(); |
||||
try { |
||||
setParameterInternal(ps, i, parameter, jdbcType, lobCreator); |
||||
} |
||||
catch (IOException ex) { |
||||
throw new SQLException("I/O errors during LOB access: " + ex.getMessage()); |
||||
} |
||||
|
||||
TransactionSynchronizationManager.registerSynchronization( |
||||
new LobCreatorSynchronization(lobCreator)); |
||||
} |
||||
|
||||
/** |
||||
* This implementation delegates to the getResult version |
||||
* that takes a column index. |
||||
* @see #getResult(java.sql.ResultSet, String) |
||||
* @see java.sql.ResultSet#findColumn |
||||
*/ |
||||
public final Object getResult(ResultSet rs, String columnName) throws SQLException { |
||||
return getResult(rs, rs.findColumn(columnName)); |
||||
} |
||||
|
||||
/** |
||||
* This implementation delegates to getResultInternal, |
||||
* passing in the LobHandler of this type. |
||||
* @see #getResultInternal |
||||
*/ |
||||
public final Object getResult(ResultSet rs, int columnIndex) throws SQLException { |
||||
try { |
||||
return getResultInternal(rs, columnIndex, this.lobHandler); |
||||
} |
||||
catch (IOException ex) { |
||||
throw new SQLException( |
||||
"I/O errors during LOB access: " + ex.getClass().getName() + ": " + ex.getMessage()); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* This implementation always throws a SQLException: |
||||
* retrieving LOBs from a CallableStatement is not supported. |
||||
*/ |
||||
public Object getResult(CallableStatement cs, int columnIndex) throws SQLException { |
||||
throw new SQLException("Retrieving LOBs from a CallableStatement is not supported"); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Template method to set the given value on the given statement. |
||||
* @param ps the PreparedStatement to set on |
||||
* @param index the statement parameter index |
||||
* @param value the parameter value to set |
||||
* @param jdbcType the JDBC type of the parameter |
||||
* @param lobCreator the LobCreator to use |
||||
* @throws SQLException if thrown by JDBC methods |
||||
* @throws IOException if thrown by streaming methods |
||||
*/ |
||||
protected abstract void setParameterInternal( |
||||
PreparedStatement ps, int index, Object value, String jdbcType, LobCreator lobCreator) |
||||
throws SQLException, IOException; |
||||
|
||||
/** |
||||
* Template method to extract a value from the given result set. |
||||
* @param rs the ResultSet to extract from |
||||
* @param index the index in the ResultSet |
||||
* @param lobHandler the LobHandler to use |
||||
* @return the extracted value |
||||
* @throws SQLException if thrown by JDBC methods |
||||
* @throws IOException if thrown by streaming methods |
||||
*/ |
||||
protected abstract Object getResultInternal(ResultSet rs, int index, LobHandler lobHandler) |
||||
throws SQLException, IOException; |
||||
|
||||
|
||||
/** |
||||
* Callback for resource cleanup at the end of a Spring transaction. |
||||
* Invokes LobCreator.close to clean up temporary LOBs that might have been created. |
||||
* @see org.springframework.jdbc.support.lob.LobCreator#close |
||||
*/ |
||||
private static class LobCreatorSynchronization extends TransactionSynchronizationAdapter { |
||||
|
||||
private final LobCreator lobCreator; |
||||
|
||||
public LobCreatorSynchronization(LobCreator lobCreator) { |
||||
this.lobCreator = lobCreator; |
||||
} |
||||
|
||||
@Override |
||||
public int getOrder() { |
||||
return LOB_CREATOR_SYNCHRONIZATION_ORDER; |
||||
} |
||||
|
||||
@Override |
||||
public void beforeCompletion() { |
||||
this.lobCreator.close(); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -1,77 +0,0 @@
@@ -1,77 +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.orm.ibatis.support; |
||||
|
||||
import java.sql.PreparedStatement; |
||||
import java.sql.ResultSet; |
||||
import java.sql.SQLException; |
||||
|
||||
import org.springframework.jdbc.support.lob.LobCreator; |
||||
import org.springframework.jdbc.support.lob.LobHandler; |
||||
|
||||
/** |
||||
* iBATIS TypeHandler implementation for byte arrays that get mapped to BLOBs. |
||||
* Retrieves the LobHandler to use from SqlMapClientFactoryBean at config time. |
||||
* |
||||
* <p>Can also be defined in generic iBATIS mappings, as DefaultLobCreator will |
||||
* work with most JDBC-compliant database drivers. In this case, the field type |
||||
* does not have to be BLOB: For databases like MySQL and MS SQL Server, any |
||||
* large enough binary type will work. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 1.1.5 |
||||
* @see org.springframework.orm.ibatis.SqlMapClientFactoryBean#setLobHandler |
||||
* @deprecated as of Spring 3.2, in favor of the native Spring support |
||||
* in the Mybatis follow-up project (http://code.google.com/p/mybatis/)
|
||||
*/ |
||||
@Deprecated |
||||
public class BlobByteArrayTypeHandler extends AbstractLobTypeHandler { |
||||
|
||||
/** |
||||
* Constructor used by iBATIS: fetches config-time LobHandler from |
||||
* SqlMapClientFactoryBean. |
||||
* @see org.springframework.orm.ibatis.SqlMapClientFactoryBean#getConfigTimeLobHandler |
||||
*/ |
||||
public BlobByteArrayTypeHandler() { |
||||
super(); |
||||
} |
||||
|
||||
/** |
||||
* Constructor used for testing: takes an explicit LobHandler. |
||||
*/ |
||||
protected BlobByteArrayTypeHandler(LobHandler lobHandler) { |
||||
super(lobHandler); |
||||
} |
||||
|
||||
@Override |
||||
protected void setParameterInternal( |
||||
PreparedStatement ps, int index, Object value, String jdbcType, LobCreator lobCreator) |
||||
throws SQLException { |
||||
lobCreator.setBlobAsBytes(ps, index, (byte[]) value); |
||||
} |
||||
|
||||
@Override |
||||
protected Object getResultInternal(ResultSet rs, int index, LobHandler lobHandler) |
||||
throws SQLException { |
||||
return lobHandler.getBlobAsBytes(rs, index); |
||||
} |
||||
|
||||
public Object valueOf(String s) { |
||||
return s.getBytes(); |
||||
} |
||||
|
||||
} |
||||
@ -1,113 +0,0 @@
@@ -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.orm.ibatis.support; |
||||
|
||||
import java.io.ByteArrayOutputStream; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.io.ObjectInputStream; |
||||
import java.io.ObjectOutputStream; |
||||
import java.sql.PreparedStatement; |
||||
import java.sql.ResultSet; |
||||
import java.sql.SQLException; |
||||
|
||||
import org.springframework.jdbc.support.lob.LobCreator; |
||||
import org.springframework.jdbc.support.lob.LobHandler; |
||||
|
||||
/** |
||||
* iBATIS TypeHandler implementation for arbitrary objects that get serialized to BLOBs. |
||||
* Retrieves the LobHandler to use from SqlMapClientFactoryBean at config time. |
||||
* |
||||
* <p>Can also be defined in generic iBATIS mappings, as DefaultLobCreator will |
||||
* work with most JDBC-compliant database drivers. In this case, the field type |
||||
* does not have to be BLOB: For databases like MySQL and MS SQL Server, any |
||||
* large enough binary type will work. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 1.1.5 |
||||
* @see org.springframework.orm.ibatis.SqlMapClientFactoryBean#setLobHandler |
||||
* @deprecated as of Spring 3.2, in favor of the native Spring support |
||||
* in the Mybatis follow-up project (http://code.google.com/p/mybatis/)
|
||||
*/ |
||||
@Deprecated |
||||
public class BlobSerializableTypeHandler extends AbstractLobTypeHandler { |
||||
|
||||
/** |
||||
* Constructor used by iBATIS: fetches config-time LobHandler from |
||||
* SqlMapClientFactoryBean. |
||||
* @see org.springframework.orm.ibatis.SqlMapClientFactoryBean#getConfigTimeLobHandler |
||||
*/ |
||||
public BlobSerializableTypeHandler() { |
||||
super(); |
||||
} |
||||
|
||||
/** |
||||
* Constructor used for testing: takes an explicit LobHandler. |
||||
*/ |
||||
protected BlobSerializableTypeHandler(LobHandler lobHandler) { |
||||
super(lobHandler); |
||||
} |
||||
|
||||
@Override |
||||
protected void setParameterInternal( |
||||
PreparedStatement ps, int index, Object value, String jdbcType, LobCreator lobCreator) |
||||
throws SQLException, IOException { |
||||
|
||||
if (value != null) { |
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
||||
ObjectOutputStream oos = new ObjectOutputStream(baos); |
||||
try { |
||||
oos.writeObject(value); |
||||
oos.flush(); |
||||
lobCreator.setBlobAsBytes(ps, index, baos.toByteArray()); |
||||
} |
||||
finally { |
||||
oos.close(); |
||||
} |
||||
} |
||||
else { |
||||
lobCreator.setBlobAsBytes(ps, index, null); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
protected Object getResultInternal(ResultSet rs, int index, LobHandler lobHandler) |
||||
throws SQLException, IOException { |
||||
|
||||
InputStream is = lobHandler.getBlobAsBinaryStream(rs, index); |
||||
if (is != null) { |
||||
ObjectInputStream ois = new ObjectInputStream(is); |
||||
try { |
||||
return ois.readObject(); |
||||
} |
||||
catch (ClassNotFoundException ex) { |
||||
throw new SQLException("Could not deserialize BLOB contents: " + ex.getMessage()); |
||||
} |
||||
finally { |
||||
ois.close(); |
||||
} |
||||
} |
||||
else { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public Object valueOf(String s) { |
||||
return s; |
||||
} |
||||
|
||||
} |
||||
@ -1,80 +0,0 @@
@@ -1,80 +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.orm.ibatis.support; |
||||
|
||||
import java.sql.PreparedStatement; |
||||
import java.sql.ResultSet; |
||||
import java.sql.SQLException; |
||||
|
||||
import org.springframework.jdbc.support.lob.LobCreator; |
||||
import org.springframework.jdbc.support.lob.LobHandler; |
||||
|
||||
/** |
||||
* iBATIS TypeHandler implementation for Strings that get mapped to CLOBs. |
||||
* Retrieves the LobHandler to use from SqlMapClientFactoryBean at config time. |
||||
* |
||||
* <p>Particularly useful for storing Strings with more than 4000 characters in an |
||||
* Oracle database (only possible via CLOBs), in combination with OracleLobHandler. |
||||
* |
||||
* <p>Can also be defined in generic iBATIS mappings, as DefaultLobCreator will |
||||
* work with most JDBC-compliant database drivers. In this case, the field type |
||||
* does not have to be BLOB: For databases like MySQL and MS SQL Server, any |
||||
* large enough binary type will work. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 1.1.5 |
||||
* @see org.springframework.orm.ibatis.SqlMapClientFactoryBean#setLobHandler |
||||
* @deprecated as of Spring 3.2, in favor of the native Spring support |
||||
* in the Mybatis follow-up project (http://code.google.com/p/mybatis/)
|
||||
*/ |
||||
@Deprecated |
||||
public class ClobStringTypeHandler extends AbstractLobTypeHandler { |
||||
|
||||
/** |
||||
* Constructor used by iBATIS: fetches config-time LobHandler from |
||||
* SqlMapClientFactoryBean. |
||||
* @see org.springframework.orm.ibatis.SqlMapClientFactoryBean#getConfigTimeLobHandler |
||||
*/ |
||||
public ClobStringTypeHandler() { |
||||
super(); |
||||
} |
||||
|
||||
/** |
||||
* Constructor used for testing: takes an explicit LobHandler. |
||||
*/ |
||||
protected ClobStringTypeHandler(LobHandler lobHandler) { |
||||
super(lobHandler); |
||||
} |
||||
|
||||
@Override |
||||
protected void setParameterInternal( |
||||
PreparedStatement ps, int index, Object value, String jdbcType, LobCreator lobCreator) |
||||
throws SQLException { |
||||
lobCreator.setClobAsString(ps, index, (String) value); |
||||
} |
||||
|
||||
@Override |
||||
protected Object getResultInternal(ResultSet rs, int index, LobHandler lobHandler) |
||||
throws SQLException { |
||||
return lobHandler.getClobAsString(rs, index); |
||||
} |
||||
|
||||
public Object valueOf(String s) { |
||||
return s; |
||||
} |
||||
|
||||
} |
||||
@ -1,116 +0,0 @@
@@ -1,116 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2008 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.orm.ibatis.support; |
||||
|
||||
import javax.sql.DataSource; |
||||
|
||||
import com.ibatis.sqlmap.client.SqlMapClient; |
||||
|
||||
import org.springframework.dao.support.DaoSupport; |
||||
import org.springframework.orm.ibatis.SqlMapClientTemplate; |
||||
import org.springframework.util.Assert; |
||||
|
||||
/** |
||||
* Convenient super class for iBATIS SqlMapClient data access objects. |
||||
* Requires a SqlMapClient to be set, providing a SqlMapClientTemplate |
||||
* based on it to subclasses. |
||||
* |
||||
* <p>Instead of a plain SqlMapClient, you can also pass a preconfigured |
||||
* SqlMapClientTemplate instance in. This allows you to share your |
||||
* SqlMapClientTemplate configuration for all your DAOs, for example |
||||
* a custom SQLExceptionTranslator to use. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 24.02.2004 |
||||
* @see #setSqlMapClient |
||||
* @see #setSqlMapClientTemplate |
||||
* @see org.springframework.orm.ibatis.SqlMapClientTemplate |
||||
* @see org.springframework.orm.ibatis.SqlMapClientTemplate#setExceptionTranslator |
||||
* @deprecated as of Spring 3.2, in favor of the native Spring support |
||||
* in the Mybatis follow-up project (http://code.google.com/p/mybatis/)
|
||||
*/ |
||||
@Deprecated |
||||
public abstract class SqlMapClientDaoSupport extends DaoSupport { |
||||
|
||||
private SqlMapClientTemplate sqlMapClientTemplate = new SqlMapClientTemplate(); |
||||
|
||||
private boolean externalTemplate = false; |
||||
|
||||
|
||||
/** |
||||
* Set the JDBC DataSource to be used by this DAO. |
||||
* Not required: The SqlMapClient might carry a shared DataSource. |
||||
* @see #setSqlMapClient |
||||
*/ |
||||
public final void setDataSource(DataSource dataSource) { |
||||
if (!this.externalTemplate) { |
||||
this.sqlMapClientTemplate.setDataSource(dataSource); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Return the JDBC DataSource used by this DAO. |
||||
*/ |
||||
public final DataSource getDataSource() { |
||||
return this.sqlMapClientTemplate.getDataSource(); |
||||
} |
||||
|
||||
/** |
||||
* Set the iBATIS Database Layer SqlMapClient to work with. |
||||
* Either this or a "sqlMapClientTemplate" is required. |
||||
* @see #setSqlMapClientTemplate |
||||
*/ |
||||
public final void setSqlMapClient(SqlMapClient sqlMapClient) { |
||||
if (!this.externalTemplate) { |
||||
this.sqlMapClientTemplate.setSqlMapClient(sqlMapClient); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Return the iBATIS Database Layer SqlMapClient that this template works with. |
||||
*/ |
||||
public final SqlMapClient getSqlMapClient() { |
||||
return this.sqlMapClientTemplate.getSqlMapClient(); |
||||
} |
||||
|
||||
/** |
||||
* Set the SqlMapClientTemplate for this DAO explicitly, |
||||
* as an alternative to specifying a SqlMapClient. |
||||
* @see #setSqlMapClient |
||||
*/ |
||||
public final void setSqlMapClientTemplate(SqlMapClientTemplate sqlMapClientTemplate) { |
||||
Assert.notNull(sqlMapClientTemplate, "SqlMapClientTemplate must not be null"); |
||||
this.sqlMapClientTemplate = sqlMapClientTemplate; |
||||
this.externalTemplate = true; |
||||
} |
||||
|
||||
/** |
||||
* Return the SqlMapClientTemplate for this DAO, |
||||
* pre-initialized with the SqlMapClient or set explicitly. |
||||
*/ |
||||
public final SqlMapClientTemplate getSqlMapClientTemplate() { |
||||
return this.sqlMapClientTemplate; |
||||
} |
||||
|
||||
@Override |
||||
protected final void checkDaoConfig() { |
||||
if (!this.externalTemplate) { |
||||
this.sqlMapClientTemplate.afterPropertiesSet(); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -1,8 +0,0 @@
@@ -1,8 +0,0 @@
|
||||
/** |
||||
* |
||||
* Classes supporting the {@code org.springframework.orm.ibatis} package. |
||||
* Contains a DAO base class for SqlMapClientTemplate usage. |
||||
* |
||||
*/ |
||||
package org.springframework.orm.ibatis.support; |
||||
|
||||
@ -1,358 +0,0 @@
@@ -1,358 +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.orm.ibatis; |
||||
|
||||
import java.sql.Connection; |
||||
import java.sql.SQLException; |
||||
import java.util.ArrayList; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import javax.sql.DataSource; |
||||
|
||||
import org.junit.Test; |
||||
import org.springframework.dao.DataAccessException; |
||||
import org.springframework.jdbc.JdbcUpdateAffectedIncorrectNumberOfRowsException; |
||||
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport; |
||||
|
||||
import com.ibatis.sqlmap.client.SqlMapClient; |
||||
import com.ibatis.sqlmap.client.SqlMapExecutor; |
||||
import com.ibatis.sqlmap.client.SqlMapSession; |
||||
import com.ibatis.sqlmap.client.event.RowHandler; |
||||
|
||||
import static org.junit.Assert.*; |
||||
import static org.mockito.BDDMockito.*; |
||||
|
||||
/** |
||||
* @author Juergen Hoeller |
||||
* @author Alef Arendsen |
||||
* @author Phillip Webb |
||||
* @since 09.10.2004 |
||||
*/ |
||||
public class SqlMapClientTests { |
||||
|
||||
@Test |
||||
public void testSqlMapClientFactoryBeanWithoutConfig() throws Exception { |
||||
SqlMapClientFactoryBean factory = new SqlMapClientFactoryBean(); |
||||
// explicitly set to null, don't know why ;-)
|
||||
factory.setConfigLocation(null); |
||||
try { |
||||
factory.afterPropertiesSet(); |
||||
fail("Should have thrown IllegalArgumentException"); |
||||
} |
||||
catch (IllegalArgumentException ex) { |
||||
// expected
|
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void testSqlMapClientTemplate() throws SQLException { |
||||
DataSource ds = mock(DataSource.class); |
||||
Connection con = mock(Connection.class); |
||||
final SqlMapSession session = mock(SqlMapSession.class); |
||||
SqlMapClient client = mock(SqlMapClient.class); |
||||
|
||||
given(ds.getConnection()).willReturn(con); |
||||
given(client.openSession()).willReturn(session); |
||||
|
||||
SqlMapClientTemplate template = new SqlMapClientTemplate(); |
||||
template.setDataSource(ds); |
||||
template.setSqlMapClient(client); |
||||
template.afterPropertiesSet(); |
||||
Object result = template.execute(new SqlMapClientCallback() { |
||||
@Override |
||||
public Object doInSqlMapClient(SqlMapExecutor executor) { |
||||
assertTrue(executor == session); |
||||
return "done"; |
||||
} |
||||
}); |
||||
assertEquals("done", result); |
||||
|
||||
verify(con).close(); |
||||
verify(session).setUserConnection(con); |
||||
verify(session).close(); |
||||
} |
||||
|
||||
@Test |
||||
public void testSqlMapClientTemplateWithNestedSqlMapSession() throws SQLException { |
||||
DataSource ds = mock(DataSource.class); |
||||
final Connection con = mock(Connection.class); |
||||
final SqlMapSession session = mock(SqlMapSession.class); |
||||
SqlMapClient client = mock(SqlMapClient.class); |
||||
|
||||
given(client.openSession()).willReturn(session); |
||||
given(session.getCurrentConnection()).willReturn(con); |
||||
|
||||
SqlMapClientTemplate template = new SqlMapClientTemplate(); |
||||
template.setDataSource(ds); |
||||
template.setSqlMapClient(client); |
||||
template.afterPropertiesSet(); |
||||
Object result = template.execute(new SqlMapClientCallback() { |
||||
@Override |
||||
public Object doInSqlMapClient(SqlMapExecutor executor) { |
||||
assertTrue(executor == session); |
||||
return "done"; |
||||
} |
||||
}); |
||||
assertEquals("done", result); |
||||
} |
||||
|
||||
@Test |
||||
public void testQueryForObjectOnSqlMapSession() throws SQLException { |
||||
DataSource ds = mock(DataSource.class); |
||||
Connection con = mock(Connection.class); |
||||
SqlMapClient client = mock(SqlMapClient.class); |
||||
SqlMapSession session = mock(SqlMapSession.class); |
||||
|
||||
given(ds.getConnection()).willReturn(con); |
||||
given(client.getDataSource()).willReturn(ds); |
||||
given(client.openSession()).willReturn(session); |
||||
given(session.queryForObject("myStatement", "myParameter")).willReturn("myResult"); |
||||
|
||||
SqlMapClientTemplate template = new SqlMapClientTemplate(); |
||||
template.setSqlMapClient(client); |
||||
template.afterPropertiesSet(); |
||||
assertEquals("myResult", template.queryForObject("myStatement", "myParameter")); |
||||
|
||||
verify(con).close(); |
||||
verify(session).setUserConnection(con); |
||||
verify(session).close(); |
||||
} |
||||
|
||||
@Test |
||||
public void testQueryForObject() throws SQLException { |
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate(); |
||||
given(template.executor.queryForObject("myStatement", null)).willReturn("myResult"); |
||||
assertEquals("myResult", template.queryForObject("myStatement")); |
||||
} |
||||
|
||||
@Test |
||||
public void testQueryForObjectWithParameter() throws SQLException { |
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate(); |
||||
given(template.executor.queryForObject("myStatement", "myParameter")).willReturn("myResult"); |
||||
assertEquals("myResult", template.queryForObject("myStatement", "myParameter")); |
||||
} |
||||
|
||||
@Test |
||||
public void testQueryForObjectWithParameterAndResultObject() throws SQLException { |
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate(); |
||||
given(template.executor.queryForObject("myStatement", "myParameter", |
||||
"myResult")).willReturn("myResult"); |
||||
assertEquals("myResult", template.queryForObject("myStatement", "myParameter", "myResult")); |
||||
} |
||||
|
||||
@Test |
||||
public void testQueryForList() throws SQLException { |
||||
List result = new ArrayList(); |
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate(); |
||||
given(template.executor.queryForList("myStatement", null)).willReturn(result); |
||||
assertEquals(result, template.queryForList("myStatement")); |
||||
} |
||||
|
||||
@Test |
||||
public void testQueryForListWithParameter() throws SQLException { |
||||
List result = new ArrayList(); |
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate(); |
||||
given(template.executor.queryForList("myStatement", "myParameter")).willReturn(result); |
||||
assertEquals(result, template.queryForList("myStatement", "myParameter")); |
||||
} |
||||
|
||||
@Test |
||||
public void testQueryForListWithResultSize() throws SQLException { |
||||
List result = new ArrayList(); |
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate(); |
||||
given(template.executor.queryForList("myStatement", null, 10, 20)).willReturn(result); |
||||
assertEquals(result, template.queryForList("myStatement", 10, 20)); |
||||
} |
||||
|
||||
@Test |
||||
public void testQueryForListParameterAndWithResultSize() throws SQLException { |
||||
List result = new ArrayList(); |
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate(); |
||||
given(template.executor.queryForList("myStatement", "myParameter", 10, 20)).willReturn(result); |
||||
assertEquals(result, template.queryForList("myStatement", "myParameter", 10, 20)); |
||||
} |
||||
|
||||
@Test |
||||
public void testQueryWithRowHandler() throws SQLException { |
||||
RowHandler rowHandler = new TestRowHandler(); |
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate(); |
||||
template.queryWithRowHandler("myStatement", rowHandler); |
||||
verify(template.executor).queryWithRowHandler("myStatement", null, rowHandler); |
||||
} |
||||
|
||||
@Test |
||||
public void testQueryWithRowHandlerWithParameter() throws SQLException { |
||||
RowHandler rowHandler = new TestRowHandler(); |
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate(); |
||||
template.queryWithRowHandler("myStatement", "myParameter", rowHandler); |
||||
verify(template.executor).queryWithRowHandler("myStatement", "myParameter", rowHandler); |
||||
} |
||||
|
||||
@Test |
||||
public void testQueryForMap() throws SQLException { |
||||
Map result = new HashMap(); |
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate(); |
||||
given(template.executor.queryForMap("myStatement", "myParameter", "myKey")).willReturn(result); |
||||
assertEquals(result, template.queryForMap("myStatement", "myParameter", "myKey")); |
||||
} |
||||
|
||||
@Test |
||||
public void testQueryForMapWithValueProperty() throws SQLException { |
||||
Map result = new HashMap(); |
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate(); |
||||
given(template.executor.queryForMap("myStatement", "myParameter", "myKey", |
||||
"myValue")).willReturn(result); |
||||
assertEquals(result, template.queryForMap("myStatement", "myParameter", "myKey", "myValue")); |
||||
} |
||||
|
||||
@Test |
||||
public void testInsert() throws SQLException { |
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate(); |
||||
given(template.executor.insert("myStatement", null)).willReturn("myResult"); |
||||
assertEquals("myResult", template.insert("myStatement")); |
||||
} |
||||
|
||||
@Test |
||||
public void testInsertWithParameter() throws SQLException { |
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate(); |
||||
given(template.executor.insert("myStatement", "myParameter")).willReturn("myResult"); |
||||
assertEquals("myResult", template.insert("myStatement", "myParameter")); |
||||
} |
||||
|
||||
@Test |
||||
public void testUpdate() throws SQLException { |
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate(); |
||||
given(template.executor.update("myStatement", null)).willReturn(10); |
||||
assertEquals(10, template.update("myStatement")); |
||||
} |
||||
|
||||
@Test |
||||
public void testUpdateWithParameter() throws SQLException { |
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate(); |
||||
given(template.executor.update("myStatement", "myParameter")).willReturn(10); |
||||
assertEquals(10, template.update("myStatement", "myParameter")); |
||||
} |
||||
|
||||
@Test |
||||
public void testUpdateWithRequiredRowsAffected() throws SQLException { |
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate(); |
||||
given(template.executor.update("myStatement", "myParameter")).willReturn(10); |
||||
template.update("myStatement", "myParameter", 10); |
||||
verify(template.executor).update("myStatement", "myParameter"); |
||||
} |
||||
|
||||
@Test |
||||
public void testUpdateWithRequiredRowsAffectedAndInvalidRowCount() throws SQLException { |
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate(); |
||||
given(template.executor.update("myStatement", "myParameter")).willReturn(20); |
||||
try { |
||||
template.update("myStatement", "myParameter", 10); |
||||
fail("Should have thrown JdbcUpdateAffectedIncorrectNumberOfRowsException"); |
||||
} |
||||
catch (JdbcUpdateAffectedIncorrectNumberOfRowsException ex) { |
||||
// expected
|
||||
assertEquals(10, ex.getExpectedRowsAffected()); |
||||
assertEquals(20, ex.getActualRowsAffected()); |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void testDelete() throws SQLException { |
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate(); |
||||
given(template.executor.delete("myStatement", null)).willReturn(10); |
||||
assertEquals(10, template.delete("myStatement")); |
||||
} |
||||
|
||||
@Test |
||||
public void testDeleteWithParameter() throws SQLException { |
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate(); |
||||
given(template.executor.delete("myStatement", "myParameter")).willReturn(10); |
||||
assertEquals(10, template.delete("myStatement", "myParameter")); |
||||
} |
||||
|
||||
@Test |
||||
public void testDeleteWithRequiredRowsAffected() throws SQLException { |
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate(); |
||||
given(template.executor.delete("myStatement", "myParameter")).willReturn(10); |
||||
template.delete("myStatement", "myParameter", 10); |
||||
verify(template.executor).delete("myStatement", "myParameter"); |
||||
} |
||||
|
||||
@Test |
||||
public void testDeleteWithRequiredRowsAffectedAndInvalidRowCount() throws SQLException { |
||||
TestSqlMapClientTemplate template = new TestSqlMapClientTemplate(); |
||||
given(template.executor.delete("myStatement", "myParameter")).willReturn(20); |
||||
try { |
||||
template.delete("myStatement", "myParameter", 10); |
||||
fail("Should have thrown JdbcUpdateAffectedIncorrectNumberOfRowsException"); |
||||
} |
||||
catch (JdbcUpdateAffectedIncorrectNumberOfRowsException ex) { |
||||
// expected
|
||||
assertEquals(10, ex.getExpectedRowsAffected()); |
||||
assertEquals(20, ex.getActualRowsAffected()); |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void testSqlMapClientDaoSupport() throws Exception { |
||||
DataSource ds = mock(DataSource.class); |
||||
SqlMapClientDaoSupport testDao = new SqlMapClientDaoSupport() { |
||||
}; |
||||
testDao.setDataSource(ds); |
||||
assertEquals(ds, testDao.getDataSource()); |
||||
|
||||
SqlMapClient client = mock(SqlMapClient.class); |
||||
|
||||
testDao.setSqlMapClient(client); |
||||
assertEquals(client, testDao.getSqlMapClient()); |
||||
|
||||
SqlMapClientTemplate template = new SqlMapClientTemplate(); |
||||
template.setDataSource(ds); |
||||
template.setSqlMapClient(client); |
||||
testDao.setSqlMapClientTemplate(template); |
||||
assertEquals(template, testDao.getSqlMapClientTemplate()); |
||||
|
||||
testDao.afterPropertiesSet(); |
||||
} |
||||
|
||||
|
||||
private static class TestSqlMapClientTemplate extends SqlMapClientTemplate { |
||||
|
||||
public SqlMapExecutor executor = mock(SqlMapExecutor.class); |
||||
|
||||
@Override |
||||
public Object execute(SqlMapClientCallback action) throws DataAccessException { |
||||
try { |
||||
return action.doInSqlMapClient(executor); |
||||
} |
||||
catch (SQLException ex) { |
||||
throw getExceptionTranslator().translate("SqlMapClient operation", null, ex); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
private static class TestRowHandler implements RowHandler { |
||||
|
||||
@Override |
||||
public void handleRow(Object row) { |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -1,205 +0,0 @@
@@ -1,205 +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.orm.ibatis.support; |
||||
|
||||
import java.io.ByteArrayInputStream; |
||||
import java.io.ByteArrayOutputStream; |
||||
import java.io.InputStream; |
||||
import java.io.ObjectOutputStream; |
||||
import java.sql.PreparedStatement; |
||||
import java.sql.ResultSet; |
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
|
||||
import javax.sql.DataSource; |
||||
|
||||
import org.junit.After; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.mockito.invocation.InvocationOnMock; |
||||
import org.mockito.stubbing.Answer; |
||||
import org.springframework.jdbc.datasource.DataSourceUtils; |
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource; |
||||
import org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy; |
||||
import org.springframework.jdbc.support.lob.LobCreator; |
||||
import org.springframework.jdbc.support.lob.LobHandler; |
||||
import org.springframework.transaction.support.TransactionSynchronization; |
||||
import org.springframework.transaction.support.TransactionSynchronizationManager; |
||||
|
||||
import static org.junit.Assert.*; |
||||
import static org.mockito.BDDMockito.*; |
||||
|
||||
/** |
||||
* @author Juergen Hoeller |
||||
* @author Phillip Webb |
||||
* @since 27.02.2005 |
||||
*/ |
||||
public class LobTypeHandlerTests { |
||||
|
||||
private ResultSet rs = mock(ResultSet.class); |
||||
private PreparedStatement ps = mock(PreparedStatement.class); |
||||
|
||||
private LobHandler lobHandler = mock(LobHandler.class); |
||||
private LobCreator lobCreator = mock(LobCreator.class); |
||||
|
||||
@Before |
||||
public void setUp() throws Exception { |
||||
given(rs.findColumn("column")).willReturn(1); |
||||
given(lobHandler.getLobCreator()).willReturn(lobCreator); |
||||
} |
||||
|
||||
@After |
||||
public void tearDown() throws Exception { |
||||
verify(lobCreator).close(); |
||||
assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty()); |
||||
assertFalse(TransactionSynchronizationManager.isSynchronizationActive()); |
||||
} |
||||
|
||||
@Test |
||||
public void testClobStringTypeHandler() throws Exception { |
||||
given(lobHandler.getClobAsString(rs, 1)).willReturn("content"); |
||||
|
||||
ClobStringTypeHandler type = new ClobStringTypeHandler(lobHandler); |
||||
assertEquals("content", type.valueOf("content")); |
||||
assertEquals("content", type.getResult(rs, "column")); |
||||
assertEquals("content", type.getResult(rs, 1)); |
||||
|
||||
TransactionSynchronizationManager.initSynchronization(); |
||||
try { |
||||
type.setParameter(ps, 1, "content", null); |
||||
List synchs = TransactionSynchronizationManager.getSynchronizations(); |
||||
assertEquals(1, synchs.size()); |
||||
assertTrue(synchs.get(0).getClass().getName().endsWith("LobCreatorSynchronization")); |
||||
((TransactionSynchronization) synchs.get(0)).beforeCompletion(); |
||||
((TransactionSynchronization) synchs.get(0)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED); |
||||
} |
||||
finally { |
||||
TransactionSynchronizationManager.clearSynchronization(); |
||||
} |
||||
verify(lobCreator).setClobAsString(ps, 1, "content"); |
||||
} |
||||
|
||||
@Test |
||||
public void testClobStringTypeWithSynchronizedConnection() throws Exception { |
||||
DataSource dsTarget = new DriverManagerDataSource(); |
||||
DataSource ds = new LazyConnectionDataSourceProxy(dsTarget); |
||||
|
||||
given(lobHandler.getClobAsString(rs, 1)).willReturn("content"); |
||||
|
||||
ClobStringTypeHandler type = new ClobStringTypeHandler(lobHandler); |
||||
assertEquals("content", type.valueOf("content")); |
||||
assertEquals("content", type.getResult(rs, "column")); |
||||
assertEquals("content", type.getResult(rs, 1)); |
||||
|
||||
TransactionSynchronizationManager.initSynchronization(); |
||||
try { |
||||
DataSourceUtils.getConnection(ds); |
||||
type.setParameter(ps, 1, "content", null); |
||||
List synchs = TransactionSynchronizationManager.getSynchronizations(); |
||||
assertEquals(2, synchs.size()); |
||||
assertTrue(synchs.get(0).getClass().getName().endsWith("LobCreatorSynchronization")); |
||||
((TransactionSynchronization) synchs.get(0)).beforeCompletion(); |
||||
((TransactionSynchronization) synchs.get(0)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED); |
||||
((TransactionSynchronization) synchs.get(1)).beforeCompletion(); |
||||
((TransactionSynchronization) synchs.get(1)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED); |
||||
} |
||||
finally { |
||||
TransactionSynchronizationManager.clearSynchronization(); |
||||
} |
||||
verify(lobCreator).setClobAsString(ps, 1, "content"); |
||||
} |
||||
|
||||
@Test |
||||
public void testBlobByteArrayType() throws Exception { |
||||
byte[] content = "content".getBytes(); |
||||
given(lobHandler.getBlobAsBytes(rs, 1)).willReturn(content); |
||||
|
||||
BlobByteArrayTypeHandler type = new BlobByteArrayTypeHandler(lobHandler); |
||||
assertTrue(Arrays.equals(content, (byte[]) type.valueOf("content"))); |
||||
assertEquals(content, type.getResult(rs, "column")); |
||||
assertEquals(content, type.getResult(rs, 1)); |
||||
|
||||
TransactionSynchronizationManager.initSynchronization(); |
||||
try { |
||||
type.setParameter(ps, 1, content, null); |
||||
List synchs = TransactionSynchronizationManager.getSynchronizations(); |
||||
assertEquals(1, synchs.size()); |
||||
((TransactionSynchronization) synchs.get(0)).beforeCompletion(); |
||||
((TransactionSynchronization) synchs.get(0)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED); |
||||
} |
||||
finally { |
||||
TransactionSynchronizationManager.clearSynchronization(); |
||||
} |
||||
verify(lobCreator).setBlobAsBytes(ps, 1, content); |
||||
} |
||||
|
||||
@Test |
||||
public void testBlobSerializableType() throws Exception { |
||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
||||
ObjectOutputStream oos = new ObjectOutputStream(baos); |
||||
oos.writeObject("content"); |
||||
oos.close(); |
||||
|
||||
given(lobHandler.getBlobAsBinaryStream(rs, 1)).willAnswer(new Answer<InputStream>() { |
||||
@Override |
||||
public InputStream answer(InvocationOnMock invocation) |
||||
throws Throwable { |
||||
return new ByteArrayInputStream(baos.toByteArray()); |
||||
} |
||||
}); |
||||
|
||||
BlobSerializableTypeHandler type = new BlobSerializableTypeHandler(lobHandler); |
||||
assertEquals("content", type.valueOf("content")); |
||||
assertEquals("content", type.getResult(rs, "column")); |
||||
assertEquals("content", type.getResult(rs, 1)); |
||||
|
||||
TransactionSynchronizationManager.initSynchronization(); |
||||
try { |
||||
type.setParameter(ps, 1, "content", null); |
||||
List synchs = TransactionSynchronizationManager.getSynchronizations(); |
||||
assertEquals(1, synchs.size()); |
||||
((TransactionSynchronization) synchs.get(0)).beforeCompletion(); |
||||
((TransactionSynchronization) synchs.get(0)).afterCompletion(TransactionSynchronization.STATUS_COMMITTED); |
||||
} |
||||
finally { |
||||
TransactionSynchronizationManager.clearSynchronization(); |
||||
} |
||||
verify(lobCreator).setBlobAsBytes(ps, 1, baos.toByteArray()); |
||||
} |
||||
|
||||
@Test |
||||
public void testBlobSerializableTypeWithNull() throws Exception { |
||||
given(lobHandler.getBlobAsBinaryStream(rs, 1)).willReturn(null); |
||||
|
||||
BlobSerializableTypeHandler type = new BlobSerializableTypeHandler(lobHandler); |
||||
assertEquals(null, type.valueOf(null)); |
||||
assertEquals(null, type.getResult(rs, "column")); |
||||
assertEquals(null, type.getResult(rs, 1)); |
||||
|
||||
TransactionSynchronizationManager.initSynchronization(); |
||||
try { |
||||
type.setParameter(ps, 1, null, null); |
||||
List synchs = TransactionSynchronizationManager.getSynchronizations(); |
||||
assertEquals(1, synchs.size()); |
||||
((TransactionSynchronization) synchs.get(0)).beforeCompletion(); |
||||
} |
||||
finally { |
||||
TransactionSynchronizationManager.clearSynchronization(); |
||||
} |
||||
verify(lobCreator).setBlobAsBytes(ps, 1, null); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue