From 30a9dad5fe88f8458f18427f3907a07e1248764e Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 19 Mar 2013 15:03:38 +0100 Subject: [PATCH] Removed iBATIS SQL Maps support --- .../orm/ibatis/SqlMapClientCallback.java | 65 --- .../orm/ibatis/SqlMapClientFactoryBean.java | 420 ----------------- .../orm/ibatis/SqlMapClientOperations.java | 184 -------- .../orm/ibatis/SqlMapClientTemplate.java | 422 ------------------ .../orm/ibatis/package-info.java | 13 - .../support/AbstractLobTypeHandler.java | 198 -------- .../support/BlobByteArrayTypeHandler.java | 77 ---- .../support/BlobSerializableTypeHandler.java | 113 ----- .../ibatis/support/ClobStringTypeHandler.java | 80 ---- .../support/SqlMapClientDaoSupport.java | 116 ----- .../orm/ibatis/support/package-info.java | 8 - .../orm/ibatis/SqlMapClientTests.java | 358 --------------- .../ibatis/support/LobTypeHandlerTests.java | 205 --------- src/reference/docbook/orm.xml | 232 ---------- 14 files changed, 2491 deletions(-) delete mode 100644 spring-orm/src/main/java/org/springframework/orm/ibatis/SqlMapClientCallback.java delete mode 100644 spring-orm/src/main/java/org/springframework/orm/ibatis/SqlMapClientFactoryBean.java delete mode 100644 spring-orm/src/main/java/org/springframework/orm/ibatis/SqlMapClientOperations.java delete mode 100644 spring-orm/src/main/java/org/springframework/orm/ibatis/SqlMapClientTemplate.java delete mode 100644 spring-orm/src/main/java/org/springframework/orm/ibatis/package-info.java delete mode 100644 spring-orm/src/main/java/org/springframework/orm/ibatis/support/AbstractLobTypeHandler.java delete mode 100644 spring-orm/src/main/java/org/springframework/orm/ibatis/support/BlobByteArrayTypeHandler.java delete mode 100644 spring-orm/src/main/java/org/springframework/orm/ibatis/support/BlobSerializableTypeHandler.java delete mode 100644 spring-orm/src/main/java/org/springframework/orm/ibatis/support/ClobStringTypeHandler.java delete mode 100644 spring-orm/src/main/java/org/springframework/orm/ibatis/support/SqlMapClientDaoSupport.java delete mode 100644 spring-orm/src/main/java/org/springframework/orm/ibatis/support/package-info.java delete mode 100644 spring-orm/src/test/java/org/springframework/orm/ibatis/SqlMapClientTests.java delete mode 100644 spring-orm/src/test/java/org/springframework/orm/ibatis/support/LobTypeHandlerTests.java diff --git a/spring-orm/src/main/java/org/springframework/orm/ibatis/SqlMapClientCallback.java b/spring-orm/src/main/java/org/springframework/orm/ibatis/SqlMapClientCallback.java deleted file mode 100644 index 70fb9b68f3b..00000000000 --- a/spring-orm/src/main/java/org/springframework/orm/ibatis/SqlMapClientCallback.java +++ /dev/null @@ -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 { - - /** - * 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. - * - *

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. - * - *

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; - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/ibatis/SqlMapClientFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/ibatis/SqlMapClientFactoryBean.java deleted file mode 100644 index 8d10aadf8fe..00000000000 --- a/spring-orm/src/main/java/org/springframework/orm/ibatis/SqlMapClientFactoryBean.java +++ /dev/null @@ -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. - * - *

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. - * - *

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. - * - *

Note: 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, InitializingBean { - - private static final ThreadLocal configTimeLobHandlerHolder = new ThreadLocal(); - - /** - * Return the LobHandler for the currently configured iBATIS SqlMapClient, - * to be used by TypeHandler implementations like ClobStringTypeHandler. - *

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. - *

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". - *

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. - *

If specified, this will override corresponding settings in the SqlMapClient - * properties. Usually, you will specify DataSource and transaction configuration - * either here or in SqlMapClient properties. - *

Specifying a DataSource for the SqlMapClient rather than for each individual - * DAO allows for lazy loading, for example when using PaginatedList results. - *

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. - *

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. - *

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. - *

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. - *

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}. - *

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. - *

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. - *

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). - *

It is strongly recommended to use iBATIS SQL Maps with Spring - * transaction management (or EJB CMT). In this case, the default - * ExternalTransactionConfig is fine. Lazy loading and SQL Maps operations - * without explicit transaction demarcation will execute non-transactionally. - *

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: - *

- * @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. - *

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. - *

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 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); - } - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/ibatis/SqlMapClientOperations.java b/spring-orm/src/main/java/org/springframework/orm/ibatis/SqlMapClientOperations.java deleted file mode 100644 index 1379e80b1b0..00000000000 --- a/spring-orm/src/main/java/org/springframework/orm/ibatis/SqlMapClientOperations.java +++ /dev/null @@ -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. - * - *

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; - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/ibatis/SqlMapClientTemplate.java b/spring-orm/src/main/java/org/springframework/orm/ibatis/SqlMapClientTemplate.java deleted file mode 100644 index fce0f2ad195..00000000000 --- a/spring-orm/src/main/java/org/springframework/orm/ibatis/SqlMapClientTemplate.java +++ /dev/null @@ -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}. - * - *

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. - * - *

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: - * - *

- * 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;
- *      }
- * });
- * - * 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 execute(SqlMapClientCallback 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 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 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() { - 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() { - 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() { - 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() { - 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() { - 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() { - 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() { - 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() { - 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() { - 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() { - 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); - } - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/ibatis/package-info.java b/spring-orm/src/main/java/org/springframework/orm/ibatis/package-info.java deleted file mode 100644 index b76167a271c..00000000000 --- a/spring-orm/src/main/java/org/springframework/orm/ibatis/package-info.java +++ /dev/null @@ -1,13 +0,0 @@ - -/** - * - * Package providing integration of - * iBATIS Database Layer - * with Spring concepts. - * - *

Contains resource helper classes and template classes for - * data access with the iBATIS SqlMapClient API. - * - */ -package org.springframework.orm.ibatis; - diff --git a/spring-orm/src/main/java/org/springframework/orm/ibatis/support/AbstractLobTypeHandler.java b/spring-orm/src/main/java/org/springframework/orm/ibatis/support/AbstractLobTypeHandler.java deleted file mode 100644 index 77189f9de70..00000000000 --- a/spring-orm/src/main/java/org/springframework/orm/ibatis/support/AbstractLobTypeHandler.java +++ /dev/null @@ -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. - * - *

For writing LOBs, an active Spring transaction synchronization is required, - * to be able to register a synchronization that closes the LobCreator. - * - *

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(); - } - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/ibatis/support/BlobByteArrayTypeHandler.java b/spring-orm/src/main/java/org/springframework/orm/ibatis/support/BlobByteArrayTypeHandler.java deleted file mode 100644 index 8c9447fa43d..00000000000 --- a/spring-orm/src/main/java/org/springframework/orm/ibatis/support/BlobByteArrayTypeHandler.java +++ /dev/null @@ -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. - * - *

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(); - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/ibatis/support/BlobSerializableTypeHandler.java b/spring-orm/src/main/java/org/springframework/orm/ibatis/support/BlobSerializableTypeHandler.java deleted file mode 100644 index 6c07ed5b22b..00000000000 --- a/spring-orm/src/main/java/org/springframework/orm/ibatis/support/BlobSerializableTypeHandler.java +++ /dev/null @@ -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. - * - *

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; - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/ibatis/support/ClobStringTypeHandler.java b/spring-orm/src/main/java/org/springframework/orm/ibatis/support/ClobStringTypeHandler.java deleted file mode 100644 index e2d80e70f06..00000000000 --- a/spring-orm/src/main/java/org/springframework/orm/ibatis/support/ClobStringTypeHandler.java +++ /dev/null @@ -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. - * - *

Particularly useful for storing Strings with more than 4000 characters in an - * Oracle database (only possible via CLOBs), in combination with OracleLobHandler. - * - *

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; - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/ibatis/support/SqlMapClientDaoSupport.java b/spring-orm/src/main/java/org/springframework/orm/ibatis/support/SqlMapClientDaoSupport.java deleted file mode 100644 index 6b5dc3ee42b..00000000000 --- a/spring-orm/src/main/java/org/springframework/orm/ibatis/support/SqlMapClientDaoSupport.java +++ /dev/null @@ -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. - * - *

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(); - } - } - -} diff --git a/spring-orm/src/main/java/org/springframework/orm/ibatis/support/package-info.java b/spring-orm/src/main/java/org/springframework/orm/ibatis/support/package-info.java deleted file mode 100644 index c0d26486f0e..00000000000 --- a/spring-orm/src/main/java/org/springframework/orm/ibatis/support/package-info.java +++ /dev/null @@ -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; - diff --git a/spring-orm/src/test/java/org/springframework/orm/ibatis/SqlMapClientTests.java b/spring-orm/src/test/java/org/springframework/orm/ibatis/SqlMapClientTests.java deleted file mode 100644 index 802c0a2fa4c..00000000000 --- a/spring-orm/src/test/java/org/springframework/orm/ibatis/SqlMapClientTests.java +++ /dev/null @@ -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) { - } - } - -} diff --git a/spring-orm/src/test/java/org/springframework/orm/ibatis/support/LobTypeHandlerTests.java b/spring-orm/src/test/java/org/springframework/orm/ibatis/support/LobTypeHandlerTests.java deleted file mode 100644 index 0eb1a512438..00000000000 --- a/spring-orm/src/test/java/org/springframework/orm/ibatis/support/LobTypeHandlerTests.java +++ /dev/null @@ -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() { - @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); - } -} diff --git a/src/reference/docbook/orm.xml b/src/reference/docbook/orm.xml index a6d5cbbb3e4..4b1040cf3ca 100644 --- a/src/reference/docbook/orm.xml +++ b/src/reference/docbook/orm.xml @@ -1824,236 +1824,4 @@ TR: REVISED, PLS REVIEW. Should be *inside your war*. --> - - -

- Setting up the <classname>SqlMapClient</classname> - - Using iBATIS SQL Maps involves creating SqlMap configuration files - containing statements and result maps. Spring takes care of loading - those using the SqlMapClientFactoryBean. For the - examples we will be using the following Account - class: - - public class Account { - - private String name; - private String email; - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public String getEmail() { - return this.email; - } - - public void setEmail(String email) { - this.email = email; - } -} - - To map this Account class with iBATIS 2.x we - need to create the following SQL map - Account.xml: - - <sqlMap namespace="Account"> - - <resultMap id="result" class="examples.Account"> - <result property="name" column="NAME" columnIndex="1"/> - <result property="email" column="EMAIL" columnIndex="2"/> - </resultMap> - - <select id="getAccountByEmail" resultMap="result"> - select ACCOUNT.NAME, ACCOUNT.EMAIL - from ACCOUNT - where ACCOUNT.EMAIL = #value# - </select> - - <insert id="insertAccount"> - insert into ACCOUNT (NAME, EMAIL) values (#name#, #email#) - </insert> - -</sqlMap> - - The configuration file for iBATIS 2 looks like this: - - <sqlMapConfig> - - <sqlMap resource="example/Account.xml"/> - -</sqlMapConfig> - - Remember that iBATIS loads resources from the class path, so be - sure to add theAccount.xml file to the class - path. - - We can use the SqlMapClientFactoryBean in - the Spring container. Note that with iBATIS SQL Maps 2.x, the JDBC - DataSource is usually specified on the - SqlMapClientFactoryBean, which enables lazy - loading. This is the configuration needed for these bean - definitions: - - <beans> - - <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> - <property name="driverClassName" value="${jdbc.driverClassName}"/> - <property name="url" value="${jdbc.url}"/> - <property name="username" value="${jdbc.username}"/> - <property name="password" value="${jdbc.password}"/> - </bean> - - <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> - <property name="configLocation" value="WEB-INF/sqlmap-config.xml"/> - <property name="dataSource" ref="dataSource"/> - </bean> - -</beans> -
- -
- Using <classname>SqlMapClientTemplate</classname> and - <classname>SqlMapClientDaoSupport</classname> - - The SqlMapClientDaoSupport class offers a - supporting class similar to the SqlMapDaoSupport. - We extend it to implement our DAO: - - public class SqlMapAccountDao extends SqlMapClientDaoSupport implements AccountDao { - - public Account getAccount(String email) throws DataAccessException { - return (Account) getSqlMapClientTemplate().queryForObject("getAccountByEmail", email); - } - - public void insertAccount(Account account) throws DataAccessException { - getSqlMapClientTemplate().update("insertAccount", account); - } -} - - In the DAO, we use the pre-configured - SqlMapClientTemplate to execute the queries, - after setting up the SqlMapAccountDao in the - application context and wiring it with our - SqlMapClient instance: - - <beans> - - <bean id="accountDao" class="example.SqlMapAccountDao"> - <property name="sqlMapClient" ref="sqlMapClient"/> - </bean> - -</beans> - - An SqlMapTemplate instance can also be - created manually, passing in the SqlMapClient as - constructor argument. The SqlMapClientDaoSupport base - class simply preinitializes a - SqlMapClientTemplate instance for us. - - The SqlMapClientTemplate offers a generic - execute method, taking a custom - SqlMapClientCallback implementation as argument. This - can, for example, be used for batching: - - public class SqlMapAccountDao extends SqlMapClientDaoSupport implements AccountDao { - - public void insertAccount(Account account) throws DataAccessException { - getSqlMapClientTemplate().execute(new SqlMapClientCallback() { - public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException { - executor.startBatch(); - executor.update("insertAccount", account); - executor.update("insertAddress", account.getAddress()); - executor.executeBatch(); - } - }); - } -} - - In general, any combination of operations offered by the native - SqlMapExecutor API can be used in such a callback. - Any thrown SQLException is converted automatically to - Spring's generic DataAccessException - hierarchy. -
- -
- Implementing DAOs based on plain iBATIS API - - DAOs can also be written against plain iBATIS API, without any - Spring dependencies, directly using an injected - SqlMapClient. The following example shows a - corresponding DAO implementation: - - public class SqlMapAccountDao implements AccountDao { - - private SqlMapClient sqlMapClient; - - public void setSqlMapClient(SqlMapClient sqlMapClient) { - this.sqlMapClient = sqlMapClient; - } - - public Account getAccount(String email) { - try { - return (Account) this.sqlMapClient.queryForObject("getAccountByEmail", email); - } - catch (SQLException ex) { - throw new MyDaoException(ex); - } - } - - public void insertAccount(Account account) throws DataAccessException { - try { - this.sqlMapClient.update("insertAccount", account); - } - catch (SQLException ex) { - throw new MyDaoException(ex); - } - } -} - - In this scenario, you need to handle the - SQLException thrown by the iBATIS API in a custom - fashion, usually by wrapping it in your own application-specific DAO - exception. Wiring in the application context would still look like it - does in the example for the - SqlMapClientDaoSupport, - due to the fact that the plain iBATIS-based DAO still follows the - dependency injection pattern: - - <beans> - - <bean id="accountDao" class="example.SqlMapAccountDao"> - <property name="sqlMapClient" ref="sqlMapClient"/> - </bean> - -</beans> -
-