Removed iBATIS SQL Maps support

This commit is contained in:
Juergen Hoeller
2013-03-19 15:03:38 +01:00
parent 3f35bdc79a
commit 30a9dad5fe
14 changed files with 0 additions and 2491 deletions

View File

@@ -1,65 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.orm.ibatis;
import java.sql.SQLException;
import com.ibatis.sqlmap.client.SqlMapExecutor;
/**
* Callback interface for data access code that works with the iBATIS
* {@link com.ibatis.sqlmap.client.SqlMapExecutor} interface. To be used
* with {@link SqlMapClientTemplate}'s {@code execute} method,
* assumably often as anonymous classes within a method implementation.
*
* @author Juergen Hoeller
* @since 24.02.2004
* @see SqlMapClientTemplate
* @see org.springframework.jdbc.datasource.DataSourceTransactionManager
* @deprecated as of Spring 3.2, in favor of the native Spring support
* in the Mybatis follow-up project (http://code.google.com/p/mybatis/)
*/
@Deprecated
public interface SqlMapClientCallback<T> {
/**
* Gets called by {@code SqlMapClientTemplate.execute} with an active
* {@code SqlMapExecutor}. Does not need to care about activating
* or closing the {@code SqlMapExecutor}, or handling transactions.
*
* <p>If called without a thread-bound JDBC transaction (initiated by
* DataSourceTransactionManager), the code will simply get executed on the
* underlying JDBC connection with its transactional semantics. If using
* a JTA-aware DataSource, the JDBC connection and thus the callback code
* will be transactional if a JTA transaction is active.
*
* <p>Allows for returning a result object created within the callback,
* i.e. a domain object or a collection of domain objects.
* A thrown custom RuntimeException is treated as an application exception:
* It gets propagated to the caller of the template.
*
* @param executor an active iBATIS SqlMapSession, passed-in as
* SqlMapExecutor interface here to avoid manual lifecycle handling
* @return a result object, or {@code null} if none
* @throws SQLException if thrown by the iBATIS SQL Maps API
* @see SqlMapClientTemplate#execute
* @see SqlMapClientTemplate#executeWithListResult
* @see SqlMapClientTemplate#executeWithMapResult
*/
T doInSqlMapClient(SqlMapExecutor executor) throws SQLException;
}

View File

@@ -1,420 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.orm.ibatis;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.Properties;
import javax.sql.DataSource;
import com.ibatis.common.xml.NodeletException;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
import com.ibatis.sqlmap.engine.builder.xml.SqlMapConfigParser;
import com.ibatis.sqlmap.engine.builder.xml.SqlMapParser;
import com.ibatis.sqlmap.engine.builder.xml.XmlParserState;
import com.ibatis.sqlmap.engine.impl.ExtendedSqlMapClient;
import com.ibatis.sqlmap.engine.transaction.TransactionConfig;
import com.ibatis.sqlmap.engine.transaction.TransactionManager;
import com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.NestedIOException;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
import org.springframework.jdbc.support.lob.LobHandler;
import org.springframework.util.ObjectUtils;
/**
* {@link org.springframework.beans.factory.FactoryBean} that creates an
* iBATIS {@link com.ibatis.sqlmap.client.SqlMapClient}. This is the usual
* way to set up a shared iBATIS SqlMapClient in a Spring application context;
* the SqlMapClient can then be passed to iBATIS-based DAOs via dependency
* injection.
*
* <p>Either {@link org.springframework.jdbc.datasource.DataSourceTransactionManager}
* or {@link org.springframework.transaction.jta.JtaTransactionManager} can be
* used for transaction demarcation in combination with a SqlMapClient,
* with JTA only necessary for transactions which span multiple databases.
*
* <p>Allows for specifying a DataSource at the SqlMapClient level. This
* is preferable to per-DAO DataSource references, as it allows for lazy
* loading and avoids repeated DataSource references in every DAO.
*
* <p><b>Note:</b> As of Spring 2.5.5, this class (finally) requires iBATIS 2.3
* or higher. The new "mappingLocations" feature requires iBATIS 2.3.2.
*
* @author Juergen Hoeller
* @since 24.02.2004
* @see #setConfigLocation
* @see #setDataSource
* @see SqlMapClientTemplate#setSqlMapClient
* @see SqlMapClientTemplate#setDataSource
* @deprecated as of Spring 3.2, in favor of the native Spring support
* in the Mybatis follow-up project (http://code.google.com/p/mybatis/)
*/
@Deprecated
public class SqlMapClientFactoryBean implements FactoryBean<SqlMapClient>, InitializingBean {
private static final ThreadLocal<LobHandler> configTimeLobHandlerHolder = new ThreadLocal<LobHandler>();
/**
* Return the LobHandler for the currently configured iBATIS SqlMapClient,
* to be used by TypeHandler implementations like ClobStringTypeHandler.
* <p>This instance will be set before initialization of the corresponding
* SqlMapClient, and reset immediately afterwards. It is thus only available
* during configuration.
* @see #setLobHandler
* @see org.springframework.orm.ibatis.support.ClobStringTypeHandler
* @see org.springframework.orm.ibatis.support.BlobByteArrayTypeHandler
* @see org.springframework.orm.ibatis.support.BlobSerializableTypeHandler
*/
public static LobHandler getConfigTimeLobHandler() {
return configTimeLobHandlerHolder.get();
}
private Resource[] configLocations;
private Resource[] mappingLocations;
private Properties sqlMapClientProperties;
private DataSource dataSource;
private boolean useTransactionAwareDataSource = true;
private Class transactionConfigClass = ExternalTransactionConfig.class;
private Properties transactionConfigProperties;
private LobHandler lobHandler;
private SqlMapClient sqlMapClient;
public SqlMapClientFactoryBean() {
this.transactionConfigProperties = new Properties();
this.transactionConfigProperties.setProperty("SetAutoCommitAllowed", "false");
}
/**
* Set the location of the iBATIS SqlMapClient config file.
* A typical value is "WEB-INF/sql-map-config.xml".
* @see #setConfigLocations
*/
public void setConfigLocation(Resource configLocation) {
this.configLocations = (configLocation != null ? new Resource[] {configLocation} : null);
}
/**
* Set multiple locations of iBATIS SqlMapClient config files that
* are going to be merged into one unified configuration at runtime.
*/
public void setConfigLocations(Resource[] configLocations) {
this.configLocations = configLocations;
}
/**
* Set locations of iBATIS sql-map mapping files that are going to be
* merged into the SqlMapClient configuration at runtime.
* <p>This is an alternative to specifying "&lt;sqlMap&gt;" entries
* in a sql-map-client config file. This property being based on Spring's
* resource abstraction also allows for specifying resource patterns here:
* e.g. "/myApp/*-map.xml".
* <p>Note that this feature requires iBATIS 2.3.2; it will not work
* with any previous iBATIS version.
*/
public void setMappingLocations(Resource[] mappingLocations) {
this.mappingLocations = mappingLocations;
}
/**
* Set optional properties to be passed into the SqlMapClientBuilder, as
* alternative to a {@code &lt;properties&gt;} tag in the sql-map-config.xml
* file. Will be used to resolve placeholders in the config file.
* @see #setConfigLocation
* @see com.ibatis.sqlmap.client.SqlMapClientBuilder#buildSqlMapClient(java.io.InputStream, java.util.Properties)
*/
public void setSqlMapClientProperties(Properties sqlMapClientProperties) {
this.sqlMapClientProperties = sqlMapClientProperties;
}
/**
* Set the DataSource to be used by iBATIS SQL Maps. This will be passed to the
* SqlMapClient as part of a TransactionConfig instance.
* <p>If specified, this will override corresponding settings in the SqlMapClient
* properties. Usually, you will specify DataSource and transaction configuration
* <i>either</i> here <i>or</i> in SqlMapClient properties.
* <p>Specifying a DataSource for the SqlMapClient rather than for each individual
* DAO allows for lazy loading, for example when using PaginatedList results.
* <p>With a DataSource passed in here, you don't need to specify one for each DAO.
* Passing the SqlMapClient to the DAOs is enough, as it already carries a DataSource.
* Thus, it's recommended to specify the DataSource at this central location only.
* <p>Thanks to Brandon Goodin from the iBATIS team for the hint on how to make
* this work with Spring's integration strategy!
* @see #setTransactionConfigClass
* @see #setTransactionConfigProperties
* @see com.ibatis.sqlmap.client.SqlMapClient#getDataSource
* @see SqlMapClientTemplate#setDataSource
*/
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
/**
* Set whether to use a transaction-aware DataSource for the SqlMapClient,
* i.e. whether to automatically wrap the passed-in DataSource with Spring's
* TransactionAwareDataSourceProxy.
* <p>Default is "true": When the SqlMapClient performs direct database operations
* outside of Spring's SqlMapClientTemplate (for example, lazy loading or direct
* SqlMapClient access), it will still participate in active Spring-managed
* transactions.
* <p>As a further effect, using a transaction-aware DataSource will apply
* remaining transaction timeouts to all created JDBC Statements. This means
* that all operations performed by the SqlMapClient will automatically
* participate in Spring-managed transaction timeouts.
* <p>Turn this flag off to get raw DataSource handling, without Spring transaction
* checks. Operations on Spring's SqlMapClientTemplate will still detect
* Spring-managed transactions, but lazy loading or direct SqlMapClient access won't.
* @see #setDataSource
* @see org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy
* @see org.springframework.jdbc.datasource.DataSourceTransactionManager
* @see SqlMapClientTemplate
* @see com.ibatis.sqlmap.client.SqlMapClient
*/
public void setUseTransactionAwareDataSource(boolean useTransactionAwareDataSource) {
this.useTransactionAwareDataSource = useTransactionAwareDataSource;
}
/**
* Set the iBATIS TransactionConfig class to use. Default is
* {@code com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig}.
* <p>Will only get applied when using a Spring-managed DataSource.
* An instance of this class will get populated with the given DataSource
* and initialized with the given properties.
* <p>The default ExternalTransactionConfig is appropriate if there is
* external transaction management that the SqlMapClient should participate
* in: be it Spring transaction management, EJB CMT or plain JTA. This
* should be the typical scenario. If there is no active transaction,
* SqlMapClient operations will execute SQL statements non-transactionally.
* <p>JdbcTransactionConfig or JtaTransactionConfig is only necessary
* when using the iBATIS SqlMapTransactionManager API instead of external
* transactions. If there is no explicit transaction, SqlMapClient operations
* will automatically start a transaction for their own scope (in contrast
* to the external transaction mode, see above).
* <p><b>It is strongly recommended to use iBATIS SQL Maps with Spring
* transaction management (or EJB CMT).</b> In this case, the default
* ExternalTransactionConfig is fine. Lazy loading and SQL Maps operations
* without explicit transaction demarcation will execute non-transactionally.
* <p>Even with Spring transaction management, it might be desirable to
* specify JdbcTransactionConfig: This will still participate in existing
* Spring-managed transactions, but lazy loading and operations without
* explicit transaction demaration will execute in their own auto-started
* transactions. However, this is usually not necessary.
* @see #setDataSource
* @see #setTransactionConfigProperties
* @see com.ibatis.sqlmap.engine.transaction.TransactionConfig
* @see com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig
* @see com.ibatis.sqlmap.engine.transaction.jdbc.JdbcTransactionConfig
* @see com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig
* @see com.ibatis.sqlmap.client.SqlMapTransactionManager
*/
public void setTransactionConfigClass(Class transactionConfigClass) {
if (transactionConfigClass == null || !TransactionConfig.class.isAssignableFrom(transactionConfigClass)) {
throw new IllegalArgumentException("Invalid transactionConfigClass: does not implement " +
"com.ibatis.sqlmap.engine.transaction.TransactionConfig");
}
this.transactionConfigClass = transactionConfigClass;
}
/**
* Set properties to be passed to the TransactionConfig instance used
* by this SqlMapClient. Supported properties depend on the concrete
* TransactionConfig implementation used:
* <p><ul>
* <li><b>ExternalTransactionConfig</b> supports "DefaultAutoCommit"
* (default: false) and "SetAutoCommitAllowed" (default: true).
* Note that Spring uses SetAutoCommitAllowed = false as default,
* in contrast to the iBATIS default, to always keep the original
* autoCommit value as provided by the connection pool.
* <li><b>JdbcTransactionConfig</b> does not supported any properties.
* <li><b>JtaTransactionConfig</b> supports "UserTransaction"
* (no default), specifying the JNDI location of the JTA UserTransaction
* (usually "java:comp/UserTransaction").
* </ul>
* @see com.ibatis.sqlmap.engine.transaction.TransactionConfig#initialize
* @see com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig
* @see com.ibatis.sqlmap.engine.transaction.jdbc.JdbcTransactionConfig
* @see com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig
*/
public void setTransactionConfigProperties(Properties transactionConfigProperties) {
this.transactionConfigProperties = transactionConfigProperties;
}
/**
* Set the LobHandler to be used by the SqlMapClient.
* Will be exposed at config time for TypeHandler implementations.
* @see #getConfigTimeLobHandler
* @see com.ibatis.sqlmap.engine.type.TypeHandler
* @see org.springframework.orm.ibatis.support.ClobStringTypeHandler
* @see org.springframework.orm.ibatis.support.BlobByteArrayTypeHandler
* @see org.springframework.orm.ibatis.support.BlobSerializableTypeHandler
*/
public void setLobHandler(LobHandler lobHandler) {
this.lobHandler = lobHandler;
}
public void afterPropertiesSet() throws Exception {
if (this.lobHandler != null) {
// Make given LobHandler available for SqlMapClient configuration.
// Do early because because mapping resource might refer to custom types.
configTimeLobHandlerHolder.set(this.lobHandler);
}
try {
this.sqlMapClient = buildSqlMapClient(this.configLocations, this.mappingLocations, this.sqlMapClientProperties);
// Tell the SqlMapClient to use the given DataSource, if any.
if (this.dataSource != null) {
TransactionConfig transactionConfig = (TransactionConfig) this.transactionConfigClass.newInstance();
DataSource dataSourceToUse = this.dataSource;
if (this.useTransactionAwareDataSource && !(this.dataSource instanceof TransactionAwareDataSourceProxy)) {
dataSourceToUse = new TransactionAwareDataSourceProxy(this.dataSource);
}
transactionConfig.setDataSource(dataSourceToUse);
transactionConfig.initialize(this.transactionConfigProperties);
applyTransactionConfig(this.sqlMapClient, transactionConfig);
}
}
finally {
if (this.lobHandler != null) {
// Reset LobHandler holder.
configTimeLobHandlerHolder.remove();
}
}
}
/**
* Build a SqlMapClient instance based on the given standard configuration.
* <p>The default implementation uses the standard iBATIS {@link SqlMapClientBuilder}
* API to build a SqlMapClient instance based on an InputStream (if possible,
* on iBATIS 2.3 and higher) or on a Reader (on iBATIS up to version 2.2).
* @param configLocations the config files to load from
* @param properties the SqlMapClient properties (if any)
* @return the SqlMapClient instance (never {@code null})
* @throws IOException if loading the config file failed
* @see com.ibatis.sqlmap.client.SqlMapClientBuilder#buildSqlMapClient
*/
protected SqlMapClient buildSqlMapClient(
Resource[] configLocations, Resource[] mappingLocations, Properties properties)
throws IOException {
if (ObjectUtils.isEmpty(configLocations)) {
throw new IllegalArgumentException("At least 1 'configLocation' entry is required");
}
SqlMapClient client = null;
SqlMapConfigParser configParser = new SqlMapConfigParser();
for (Resource configLocation : configLocations) {
InputStream is = configLocation.getInputStream();
try {
client = configParser.parse(is, properties);
}
catch (RuntimeException ex) {
throw new NestedIOException("Failed to parse config resource: " + configLocation, ex.getCause());
}
}
if (mappingLocations != null) {
SqlMapParser mapParser = SqlMapParserFactory.createSqlMapParser(configParser);
for (Resource mappingLocation : mappingLocations) {
try {
mapParser.parse(mappingLocation.getInputStream());
}
catch (NodeletException ex) {
throw new NestedIOException("Failed to parse mapping resource: " + mappingLocation, ex);
}
}
}
return client;
}
/**
* Apply the given iBATIS TransactionConfig to the SqlMapClient.
* <p>The default implementation casts to ExtendedSqlMapClient, retrieves the maximum
* number of concurrent transactions from the SqlMapExecutorDelegate, and sets
* an iBATIS TransactionManager with the given TransactionConfig.
* @param sqlMapClient the SqlMapClient to apply the TransactionConfig to
* @param transactionConfig the iBATIS TransactionConfig to apply
* @see com.ibatis.sqlmap.engine.impl.ExtendedSqlMapClient
* @see com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate#getMaxTransactions
* @see com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate#setTxManager
*/
protected void applyTransactionConfig(SqlMapClient sqlMapClient, TransactionConfig transactionConfig) {
if (!(sqlMapClient instanceof ExtendedSqlMapClient)) {
throw new IllegalArgumentException(
"Cannot set TransactionConfig with DataSource for SqlMapClient if not of type " +
"ExtendedSqlMapClient: " + sqlMapClient);
}
ExtendedSqlMapClient extendedClient = (ExtendedSqlMapClient) sqlMapClient;
transactionConfig.setMaximumConcurrentTransactions(extendedClient.getDelegate().getMaxTransactions());
extendedClient.getDelegate().setTxManager(new TransactionManager(transactionConfig));
}
public SqlMapClient getObject() {
return this.sqlMapClient;
}
public Class<? extends SqlMapClient> getObjectType() {
return (this.sqlMapClient != null ? this.sqlMapClient.getClass() : SqlMapClient.class);
}
public boolean isSingleton() {
return true;
}
/**
* Inner class to avoid hard-coded iBATIS 2.3.2 dependency (XmlParserState class).
*/
private static class SqlMapParserFactory {
public static SqlMapParser createSqlMapParser(SqlMapConfigParser configParser) {
// Ideally: XmlParserState state = configParser.getState();
// Should raise an enhancement request with iBATIS...
XmlParserState state = null;
try {
Field stateField = SqlMapConfigParser.class.getDeclaredField("state");
stateField.setAccessible(true);
state = (XmlParserState) stateField.get(configParser);
}
catch (Exception ex) {
throw new IllegalStateException("iBATIS 2.3.2 'state' field not found in SqlMapConfigParser class - " +
"please upgrade to IBATIS 2.3.2 or higher in order to use the new 'mappingLocations' feature. " + ex);
}
return new SqlMapParser(state);
}
}
}

View File

@@ -1,184 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.orm.ibatis;
import java.util.List;
import java.util.Map;
import com.ibatis.sqlmap.client.event.RowHandler;
import org.springframework.dao.DataAccessException;
/**
* Interface that specifies a basic set of iBATIS SqlMapClient operations,
* implemented by {@link SqlMapClientTemplate}. Not often used, but a useful
* option to enhance testability, as it can easily be mocked or stubbed.
*
* <p>Defines SqlMapClientTemplate's convenience methods that mirror
* the iBATIS {@link com.ibatis.sqlmap.client.SqlMapExecutor}'s execution
* methods. Users are strongly encouraged to read the iBATIS javadocs
* for details on the semantics of those methods.
*
* @author Juergen Hoeller
* @since 24.02.2004
* @see SqlMapClientTemplate
* @see com.ibatis.sqlmap.client.SqlMapClient
* @see com.ibatis.sqlmap.client.SqlMapExecutor
* @deprecated as of Spring 3.2, in favor of the native Spring support
* in the Mybatis follow-up project (http://code.google.com/p/mybatis/)
*/
@Deprecated
public interface SqlMapClientOperations {
/**
* @see com.ibatis.sqlmap.client.SqlMapExecutor#queryForObject(String)
* @throws org.springframework.dao.DataAccessException in case of errors
*/
Object queryForObject(String statementName) throws DataAccessException;
/**
* @see com.ibatis.sqlmap.client.SqlMapExecutor#queryForObject(String, Object)
* @throws org.springframework.dao.DataAccessException in case of errors
*/
Object queryForObject(String statementName, Object parameterObject)
throws DataAccessException;
/**
* @see com.ibatis.sqlmap.client.SqlMapExecutor#queryForObject(String, Object, Object)
* @throws org.springframework.dao.DataAccessException in case of errors
*/
Object queryForObject(String statementName, Object parameterObject, Object resultObject)
throws DataAccessException;
/**
* @see com.ibatis.sqlmap.client.SqlMapExecutor#queryForList(String)
* @throws org.springframework.dao.DataAccessException in case of errors
*/
List queryForList(String statementName) throws DataAccessException;
/**
* @see com.ibatis.sqlmap.client.SqlMapExecutor#queryForList(String, Object)
* @throws org.springframework.dao.DataAccessException in case of errors
*/
List queryForList(String statementName, Object parameterObject)
throws DataAccessException;
/**
* @see com.ibatis.sqlmap.client.SqlMapExecutor#queryForList(String, int, int)
* @throws org.springframework.dao.DataAccessException in case of errors
*/
List queryForList(String statementName, int skipResults, int maxResults)
throws DataAccessException;
/**
* @see com.ibatis.sqlmap.client.SqlMapExecutor#queryForList(String, Object, int, int)
* @throws org.springframework.dao.DataAccessException in case of errors
*/
List queryForList(String statementName, Object parameterObject, int skipResults, int maxResults)
throws DataAccessException;
/**
* @see com.ibatis.sqlmap.client.SqlMapExecutor#queryWithRowHandler(String, RowHandler)
* @throws org.springframework.dao.DataAccessException in case of errors
*/
void queryWithRowHandler(String statementName, RowHandler rowHandler)
throws DataAccessException;
/**
* @see com.ibatis.sqlmap.client.SqlMapExecutor#queryWithRowHandler(String, Object, RowHandler)
* @throws org.springframework.dao.DataAccessException in case of errors
*/
void queryWithRowHandler(String statementName, Object parameterObject, RowHandler rowHandler)
throws DataAccessException;
/**
* @see com.ibatis.sqlmap.client.SqlMapExecutor#queryForMap(String, Object, String)
* @throws org.springframework.dao.DataAccessException in case of errors
*/
Map queryForMap(String statementName, Object parameterObject, String keyProperty)
throws DataAccessException;
/**
* @see com.ibatis.sqlmap.client.SqlMapExecutor#queryForMap(String, Object, String, String)
* @throws org.springframework.dao.DataAccessException in case of errors
*/
Map queryForMap(String statementName, Object parameterObject, String keyProperty, String valueProperty)
throws DataAccessException;
/**
* @see com.ibatis.sqlmap.client.SqlMapExecutor#insert(String)
* @throws org.springframework.dao.DataAccessException in case of errors
*/
Object insert(String statementName) throws DataAccessException;
/**
* @see com.ibatis.sqlmap.client.SqlMapExecutor#insert(String, Object)
* @throws org.springframework.dao.DataAccessException in case of errors
*/
Object insert(String statementName, Object parameterObject) throws DataAccessException;
/**
* @see com.ibatis.sqlmap.client.SqlMapExecutor#update(String)
* @throws org.springframework.dao.DataAccessException in case of errors
*/
int update(String statementName) throws DataAccessException;
/**
* @see com.ibatis.sqlmap.client.SqlMapExecutor#update(String, Object)
* @throws org.springframework.dao.DataAccessException in case of errors
*/
int update(String statementName, Object parameterObject) throws DataAccessException;
/**
* Convenience method provided by Spring: execute an update operation
* with an automatic check that the update affected the given required
* number of rows.
* @param statementName the name of the mapped statement
* @param parameterObject the parameter object
* @param requiredRowsAffected the number of rows that the update is
* required to affect
* @throws org.springframework.dao.DataAccessException in case of errors
*/
void update(String statementName, Object parameterObject, int requiredRowsAffected)
throws DataAccessException;
/**
* @see com.ibatis.sqlmap.client.SqlMapExecutor#delete(String)
* @throws org.springframework.dao.DataAccessException in case of errors
*/
int delete(String statementName) throws DataAccessException;
/**
* @see com.ibatis.sqlmap.client.SqlMapExecutor#delete(String, Object)
* @throws org.springframework.dao.DataAccessException in case of errors
*/
int delete(String statementName, Object parameterObject) throws DataAccessException;
/**
* Convenience method provided by Spring: execute a delete operation
* with an automatic check that the delete affected the given required
* number of rows.
* @param statementName the name of the mapped statement
* @param parameterObject the parameter object
* @param requiredRowsAffected the number of rows that the delete is
* required to affect
* @throws org.springframework.dao.DataAccessException in case of errors
*/
void delete(String statementName, Object parameterObject, int requiredRowsAffected)
throws DataAccessException;
}

View File

@@ -1,422 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.orm.ibatis;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapExecutor;
import com.ibatis.sqlmap.client.SqlMapSession;
import com.ibatis.sqlmap.client.event.RowHandler;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.jdbc.JdbcUpdateAffectedIncorrectNumberOfRowsException;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
import org.springframework.jdbc.support.JdbcAccessor;
import org.springframework.util.Assert;
/**
* Helper class that simplifies data access via the iBATIS
* {@link com.ibatis.sqlmap.client.SqlMapClient} API, converting checked
* SQLExceptions into unchecked DataAccessExceptions, following the
* {@code org.springframework.dao} exception hierarchy.
* Uses the same {@link org.springframework.jdbc.support.SQLExceptionTranslator}
* mechanism as {@link org.springframework.jdbc.core.JdbcTemplate}.
*
* <p>The main method of this class executes a callback that implements a
* data access action. Furthermore, this class provides numerous convenience
* methods that mirror {@link com.ibatis.sqlmap.client.SqlMapExecutor}'s
* execution methods.
*
* <p>It is generally recommended to use the convenience methods on this template
* for plain query/insert/update/delete operations. However, for more complex
* operations like batch updates, a custom SqlMapClientCallback must be implemented,
* usually as anonymous inner class. For example:
*
* <pre class="code">
* getSqlMapClientTemplate().execute(new SqlMapClientCallback() {
* public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
* executor.startBatch();
* executor.update("insertSomething", "myParamValue");
* executor.update("insertSomethingElse", "myOtherParamValue");
* executor.executeBatch();
* return null;
* }
* });</pre>
*
* The template needs a SqlMapClient to work on, passed in via the "sqlMapClient"
* property. A Spring context typically uses a {@link SqlMapClientFactoryBean}
* to build the SqlMapClient. The template an additionally be configured with a
* DataSource for fetching Connections, although this is not necessary if a
* DataSource is specified for the SqlMapClient itself (typically through
* SqlMapClientFactoryBean's "dataSource" property).
*
* @author Juergen Hoeller
* @since 24.02.2004
* @see #execute
* @see #setSqlMapClient
* @see #setDataSource
* @see #setExceptionTranslator
* @see SqlMapClientFactoryBean#setDataSource
* @see com.ibatis.sqlmap.client.SqlMapClient#getDataSource
* @see com.ibatis.sqlmap.client.SqlMapExecutor
* @deprecated as of Spring 3.2, in favor of the native Spring support
* in the Mybatis follow-up project (http://code.google.com/p/mybatis/)
*/
@Deprecated
public class SqlMapClientTemplate extends JdbcAccessor implements SqlMapClientOperations {
private SqlMapClient sqlMapClient;
/**
* Create a new SqlMapClientTemplate.
*/
public SqlMapClientTemplate() {
}
/**
* Create a new SqlMapTemplate.
* @param sqlMapClient iBATIS SqlMapClient that defines the mapped statements
*/
public SqlMapClientTemplate(SqlMapClient sqlMapClient) {
setSqlMapClient(sqlMapClient);
afterPropertiesSet();
}
/**
* Create a new SqlMapTemplate.
* @param dataSource JDBC DataSource to obtain connections from
* @param sqlMapClient iBATIS SqlMapClient that defines the mapped statements
*/
public SqlMapClientTemplate(DataSource dataSource, SqlMapClient sqlMapClient) {
setDataSource(dataSource);
setSqlMapClient(sqlMapClient);
afterPropertiesSet();
}
/**
* Set the iBATIS Database Layer SqlMapClient that defines the mapped statements.
*/
public void setSqlMapClient(SqlMapClient sqlMapClient) {
this.sqlMapClient = sqlMapClient;
}
/**
* Return the iBATIS Database Layer SqlMapClient that this template works with.
*/
public SqlMapClient getSqlMapClient() {
return this.sqlMapClient;
}
/**
* If no DataSource specified, use SqlMapClient's DataSource.
* @see com.ibatis.sqlmap.client.SqlMapClient#getDataSource()
*/
@Override
public DataSource getDataSource() {
DataSource ds = super.getDataSource();
return (ds != null ? ds : this.sqlMapClient.getDataSource());
}
@Override
public void afterPropertiesSet() {
if (this.sqlMapClient == null) {
throw new IllegalArgumentException("Property 'sqlMapClient' is required");
}
super.afterPropertiesSet();
}
/**
* Execute the given data access action on a SqlMapExecutor.
* @param action callback object that specifies the data access action
* @return a result object returned by the action, or {@code null}
* @throws DataAccessException in case of SQL Maps errors
*/
public <T> T execute(SqlMapClientCallback<T> action) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
Assert.notNull(this.sqlMapClient, "No SqlMapClient specified");
// We always need to use a SqlMapSession, as we need to pass a Spring-managed
// Connection (potentially transactional) in. This shouldn't be necessary if
// we run against a TransactionAwareDataSourceProxy underneath, but unfortunately
// we still need it to make iBATIS batch execution work properly: If iBATIS
// doesn't recognize an existing transaction, it automatically executes the
// batch for every single statement...
SqlMapSession session = this.sqlMapClient.openSession();
if (logger.isDebugEnabled()) {
logger.debug("Opened SqlMapSession [" + session + "] for iBATIS operation");
}
Connection ibatisCon = null;
try {
Connection springCon = null;
DataSource dataSource = getDataSource();
boolean transactionAware = (dataSource instanceof TransactionAwareDataSourceProxy);
// Obtain JDBC Connection to operate on...
try {
ibatisCon = session.getCurrentConnection();
if (ibatisCon == null) {
springCon = (transactionAware ?
dataSource.getConnection() : DataSourceUtils.doGetConnection(dataSource));
session.setUserConnection(springCon);
if (logger.isDebugEnabled()) {
logger.debug("Obtained JDBC Connection [" + springCon + "] for iBATIS operation");
}
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Reusing JDBC Connection [" + ibatisCon + "] for iBATIS operation");
}
}
}
catch (SQLException ex) {
throw new CannotGetJdbcConnectionException("Could not get JDBC Connection", ex);
}
// Execute given callback...
try {
return action.doInSqlMapClient(session);
}
catch (SQLException ex) {
throw getExceptionTranslator().translate("SqlMapClient operation", null, ex);
}
finally {
try {
if (springCon != null) {
if (transactionAware) {
springCon.close();
}
else {
DataSourceUtils.doReleaseConnection(springCon, dataSource);
}
}
}
catch (Throwable ex) {
logger.debug("Could not close JDBC Connection", ex);
}
}
// Processing finished - potentially session still to be closed.
}
finally {
// Only close SqlMapSession if we know we've actually opened it
// at the present level.
if (ibatisCon == null) {
session.close();
}
}
}
/**
* Execute the given data access action on a SqlMapExecutor,
* expecting a List result.
* @param action callback object that specifies the data access action
* @return the List result
* @throws DataAccessException in case of SQL Maps errors
* @deprecated as of Spring 3.0 - not really needed anymore with generic
* {@link #execute} method
*/
@Deprecated
public List executeWithListResult(SqlMapClientCallback<List> action) throws DataAccessException {
return execute(action);
}
/**
* Execute the given data access action on a SqlMapExecutor,
* expecting a Map result.
* @param action callback object that specifies the data access action
* @return the Map result
* @throws DataAccessException in case of SQL Maps errors
* @deprecated as of Spring 3.0 - not really needed anymore with generic
* {@link #execute} method
*/
@Deprecated
public Map executeWithMapResult(SqlMapClientCallback<Map> action) throws DataAccessException {
return execute(action);
}
public Object queryForObject(String statementName) throws DataAccessException {
return queryForObject(statementName, null);
}
public Object queryForObject(final String statementName, final Object parameterObject)
throws DataAccessException {
return execute(new SqlMapClientCallback<Object>() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return executor.queryForObject(statementName, parameterObject);
}
});
}
public Object queryForObject(
final String statementName, final Object parameterObject, final Object resultObject)
throws DataAccessException {
return execute(new SqlMapClientCallback<Object>() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return executor.queryForObject(statementName, parameterObject, resultObject);
}
});
}
public List queryForList(String statementName) throws DataAccessException {
return queryForList(statementName, null);
}
public List queryForList(final String statementName, final Object parameterObject)
throws DataAccessException {
return execute(new SqlMapClientCallback<List>() {
public List doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return executor.queryForList(statementName, parameterObject);
}
});
}
public List queryForList(String statementName, int skipResults, int maxResults)
throws DataAccessException {
return queryForList(statementName, null, skipResults, maxResults);
}
public List queryForList(
final String statementName, final Object parameterObject, final int skipResults, final int maxResults)
throws DataAccessException {
return execute(new SqlMapClientCallback<List>() {
public List doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return executor.queryForList(statementName, parameterObject, skipResults, maxResults);
}
});
}
public void queryWithRowHandler(String statementName, RowHandler rowHandler)
throws DataAccessException {
queryWithRowHandler(statementName, null, rowHandler);
}
public void queryWithRowHandler(
final String statementName, final Object parameterObject, final RowHandler rowHandler)
throws DataAccessException {
execute(new SqlMapClientCallback<Object>() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
executor.queryWithRowHandler(statementName, parameterObject, rowHandler);
return null;
}
});
}
public Map queryForMap(
final String statementName, final Object parameterObject, final String keyProperty)
throws DataAccessException {
return execute(new SqlMapClientCallback<Map>() {
public Map doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return executor.queryForMap(statementName, parameterObject, keyProperty);
}
});
}
public Map queryForMap(
final String statementName, final Object parameterObject, final String keyProperty, final String valueProperty)
throws DataAccessException {
return execute(new SqlMapClientCallback<Map>() {
public Map doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return executor.queryForMap(statementName, parameterObject, keyProperty, valueProperty);
}
});
}
public Object insert(String statementName) throws DataAccessException {
return insert(statementName, null);
}
public Object insert(final String statementName, final Object parameterObject)
throws DataAccessException {
return execute(new SqlMapClientCallback<Object>() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return executor.insert(statementName, parameterObject);
}
});
}
public int update(String statementName) throws DataAccessException {
return update(statementName, null);
}
public int update(final String statementName, final Object parameterObject)
throws DataAccessException {
return execute(new SqlMapClientCallback<Integer>() {
public Integer doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return executor.update(statementName, parameterObject);
}
});
}
public void update(String statementName, Object parameterObject, int requiredRowsAffected)
throws DataAccessException {
int actualRowsAffected = update(statementName, parameterObject);
if (actualRowsAffected != requiredRowsAffected) {
throw new JdbcUpdateAffectedIncorrectNumberOfRowsException(
statementName, requiredRowsAffected, actualRowsAffected);
}
}
public int delete(String statementName) throws DataAccessException {
return delete(statementName, null);
}
public int delete(final String statementName, final Object parameterObject)
throws DataAccessException {
return execute(new SqlMapClientCallback<Integer>() {
public Integer doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return executor.delete(statementName, parameterObject);
}
});
}
public void delete(String statementName, Object parameterObject, int requiredRowsAffected)
throws DataAccessException {
int actualRowsAffected = delete(statementName, parameterObject);
if (actualRowsAffected != requiredRowsAffected) {
throw new JdbcUpdateAffectedIncorrectNumberOfRowsException(
statementName, requiredRowsAffected, actualRowsAffected);
}
}
}

View File

@@ -1,13 +0,0 @@
/**
*
* Package providing integration of
* <a href="http://ibatis.apache.org">iBATIS Database Layer</a>
* with Spring concepts.
*
* <p>Contains resource helper classes and template classes for
* data access with the iBATIS SqlMapClient API.
*
*/
package org.springframework.orm.ibatis;

View File

@@ -1,198 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.orm.ibatis.support;
import java.io.IOException;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.ibatis.sqlmap.engine.type.BaseTypeHandler;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.support.lob.LobCreator;
import org.springframework.jdbc.support.lob.LobHandler;
import org.springframework.orm.ibatis.SqlMapClientFactoryBean;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;
/**
* Abstract base class for iBATIS TypeHandler implementations that map to LOBs.
* Retrieves the LobHandler to use from SqlMapClientFactoryBean at config time.
*
* <p>For writing LOBs, an active Spring transaction synchronization is required,
* to be able to register a synchronization that closes the LobCreator.
*
* <p>Offers template methods for setting parameters and getting result values,
* passing in the LobHandler or LobCreator to use.
*
* @author Juergen Hoeller
* @since 1.1.5
* @see org.springframework.jdbc.support.lob.LobHandler
* @see org.springframework.jdbc.support.lob.LobCreator
* @see org.springframework.orm.ibatis.SqlMapClientFactoryBean#setLobHandler
* @deprecated as of Spring 3.2, in favor of the native Spring support
* in the Mybatis follow-up project (http://code.google.com/p/mybatis/)
*/
@Deprecated
public abstract class AbstractLobTypeHandler extends BaseTypeHandler {
/**
* Order value for TransactionSynchronization objects that clean up LobCreators.
* Return DataSourceUtils.#CONNECTION_SYNCHRONIZATION_ORDER - 100 to execute
* LobCreator cleanup before JDBC Connection cleanup, if any.
* @see org.springframework.jdbc.datasource.DataSourceUtils#CONNECTION_SYNCHRONIZATION_ORDER
*/
public static final int LOB_CREATOR_SYNCHRONIZATION_ORDER =
DataSourceUtils.CONNECTION_SYNCHRONIZATION_ORDER - 200;
private LobHandler lobHandler;
/**
* Constructor used by iBATIS: fetches config-time LobHandler from
* SqlMapClientFactoryBean.
* @see org.springframework.orm.ibatis.SqlMapClientFactoryBean#getConfigTimeLobHandler
*/
public AbstractLobTypeHandler() {
this(SqlMapClientFactoryBean.getConfigTimeLobHandler());
}
/**
* Constructor used for testing: takes an explicit LobHandler.
*/
protected AbstractLobTypeHandler(LobHandler lobHandler) {
if (lobHandler == null) {
throw new IllegalStateException("No LobHandler found for configuration - " +
"lobHandler property must be set on SqlMapClientFactoryBean");
}
this.lobHandler = lobHandler;
}
/**
* This implementation delegates to setParameterInternal,
* passing in a transaction-synchronized LobCreator for the
* LobHandler of this type.
* @see #setParameterInternal
*/
public final void setParameter(PreparedStatement ps, int i, Object parameter, String jdbcType)
throws SQLException {
if (!TransactionSynchronizationManager.isSynchronizationActive()) {
throw new IllegalStateException("Spring transaction synchronization needs to be active for " +
"setting values in iBATIS TypeHandlers that delegate to a Spring LobHandler");
}
final LobCreator lobCreator = this.lobHandler.getLobCreator();
try {
setParameterInternal(ps, i, parameter, jdbcType, lobCreator);
}
catch (IOException ex) {
throw new SQLException("I/O errors during LOB access: " + ex.getMessage());
}
TransactionSynchronizationManager.registerSynchronization(
new LobCreatorSynchronization(lobCreator));
}
/**
* This implementation delegates to the getResult version
* that takes a column index.
* @see #getResult(java.sql.ResultSet, String)
* @see java.sql.ResultSet#findColumn
*/
public final Object getResult(ResultSet rs, String columnName) throws SQLException {
return getResult(rs, rs.findColumn(columnName));
}
/**
* This implementation delegates to getResultInternal,
* passing in the LobHandler of this type.
* @see #getResultInternal
*/
public final Object getResult(ResultSet rs, int columnIndex) throws SQLException {
try {
return getResultInternal(rs, columnIndex, this.lobHandler);
}
catch (IOException ex) {
throw new SQLException(
"I/O errors during LOB access: " + ex.getClass().getName() + ": " + ex.getMessage());
}
}
/**
* This implementation always throws a SQLException:
* retrieving LOBs from a CallableStatement is not supported.
*/
public Object getResult(CallableStatement cs, int columnIndex) throws SQLException {
throw new SQLException("Retrieving LOBs from a CallableStatement is not supported");
}
/**
* Template method to set the given value on the given statement.
* @param ps the PreparedStatement to set on
* @param index the statement parameter index
* @param value the parameter value to set
* @param jdbcType the JDBC type of the parameter
* @param lobCreator the LobCreator to use
* @throws SQLException if thrown by JDBC methods
* @throws IOException if thrown by streaming methods
*/
protected abstract void setParameterInternal(
PreparedStatement ps, int index, Object value, String jdbcType, LobCreator lobCreator)
throws SQLException, IOException;
/**
* Template method to extract a value from the given result set.
* @param rs the ResultSet to extract from
* @param index the index in the ResultSet
* @param lobHandler the LobHandler to use
* @return the extracted value
* @throws SQLException if thrown by JDBC methods
* @throws IOException if thrown by streaming methods
*/
protected abstract Object getResultInternal(ResultSet rs, int index, LobHandler lobHandler)
throws SQLException, IOException;
/**
* Callback for resource cleanup at the end of a Spring transaction.
* Invokes LobCreator.close to clean up temporary LOBs that might have been created.
* @see org.springframework.jdbc.support.lob.LobCreator#close
*/
private static class LobCreatorSynchronization extends TransactionSynchronizationAdapter {
private final LobCreator lobCreator;
public LobCreatorSynchronization(LobCreator lobCreator) {
this.lobCreator = lobCreator;
}
@Override
public int getOrder() {
return LOB_CREATOR_SYNCHRONIZATION_ORDER;
}
@Override
public void beforeCompletion() {
this.lobCreator.close();
}
}
}

View File

@@ -1,77 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.orm.ibatis.support;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.support.lob.LobCreator;
import org.springframework.jdbc.support.lob.LobHandler;
/**
* iBATIS TypeHandler implementation for byte arrays that get mapped to BLOBs.
* Retrieves the LobHandler to use from SqlMapClientFactoryBean at config time.
*
* <p>Can also be defined in generic iBATIS mappings, as DefaultLobCreator will
* work with most JDBC-compliant database drivers. In this case, the field type
* does not have to be BLOB: For databases like MySQL and MS SQL Server, any
* large enough binary type will work.
*
* @author Juergen Hoeller
* @since 1.1.5
* @see org.springframework.orm.ibatis.SqlMapClientFactoryBean#setLobHandler
* @deprecated as of Spring 3.2, in favor of the native Spring support
* in the Mybatis follow-up project (http://code.google.com/p/mybatis/)
*/
@Deprecated
public class BlobByteArrayTypeHandler extends AbstractLobTypeHandler {
/**
* Constructor used by iBATIS: fetches config-time LobHandler from
* SqlMapClientFactoryBean.
* @see org.springframework.orm.ibatis.SqlMapClientFactoryBean#getConfigTimeLobHandler
*/
public BlobByteArrayTypeHandler() {
super();
}
/**
* Constructor used for testing: takes an explicit LobHandler.
*/
protected BlobByteArrayTypeHandler(LobHandler lobHandler) {
super(lobHandler);
}
@Override
protected void setParameterInternal(
PreparedStatement ps, int index, Object value, String jdbcType, LobCreator lobCreator)
throws SQLException {
lobCreator.setBlobAsBytes(ps, index, (byte[]) value);
}
@Override
protected Object getResultInternal(ResultSet rs, int index, LobHandler lobHandler)
throws SQLException {
return lobHandler.getBlobAsBytes(rs, index);
}
public Object valueOf(String s) {
return s.getBytes();
}
}

View File

@@ -1,113 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.orm.ibatis.support;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.support.lob.LobCreator;
import org.springframework.jdbc.support.lob.LobHandler;
/**
* iBATIS TypeHandler implementation for arbitrary objects that get serialized to BLOBs.
* Retrieves the LobHandler to use from SqlMapClientFactoryBean at config time.
*
* <p>Can also be defined in generic iBATIS mappings, as DefaultLobCreator will
* work with most JDBC-compliant database drivers. In this case, the field type
* does not have to be BLOB: For databases like MySQL and MS SQL Server, any
* large enough binary type will work.
*
* @author Juergen Hoeller
* @since 1.1.5
* @see org.springframework.orm.ibatis.SqlMapClientFactoryBean#setLobHandler
* @deprecated as of Spring 3.2, in favor of the native Spring support
* in the Mybatis follow-up project (http://code.google.com/p/mybatis/)
*/
@Deprecated
public class BlobSerializableTypeHandler extends AbstractLobTypeHandler {
/**
* Constructor used by iBATIS: fetches config-time LobHandler from
* SqlMapClientFactoryBean.
* @see org.springframework.orm.ibatis.SqlMapClientFactoryBean#getConfigTimeLobHandler
*/
public BlobSerializableTypeHandler() {
super();
}
/**
* Constructor used for testing: takes an explicit LobHandler.
*/
protected BlobSerializableTypeHandler(LobHandler lobHandler) {
super(lobHandler);
}
@Override
protected void setParameterInternal(
PreparedStatement ps, int index, Object value, String jdbcType, LobCreator lobCreator)
throws SQLException, IOException {
if (value != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
try {
oos.writeObject(value);
oos.flush();
lobCreator.setBlobAsBytes(ps, index, baos.toByteArray());
}
finally {
oos.close();
}
}
else {
lobCreator.setBlobAsBytes(ps, index, null);
}
}
@Override
protected Object getResultInternal(ResultSet rs, int index, LobHandler lobHandler)
throws SQLException, IOException {
InputStream is = lobHandler.getBlobAsBinaryStream(rs, index);
if (is != null) {
ObjectInputStream ois = new ObjectInputStream(is);
try {
return ois.readObject();
}
catch (ClassNotFoundException ex) {
throw new SQLException("Could not deserialize BLOB contents: " + ex.getMessage());
}
finally {
ois.close();
}
}
else {
return null;
}
}
public Object valueOf(String s) {
return s;
}
}

View File

@@ -1,80 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.orm.ibatis.support;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.support.lob.LobCreator;
import org.springframework.jdbc.support.lob.LobHandler;
/**
* iBATIS TypeHandler implementation for Strings that get mapped to CLOBs.
* Retrieves the LobHandler to use from SqlMapClientFactoryBean at config time.
*
* <p>Particularly useful for storing Strings with more than 4000 characters in an
* Oracle database (only possible via CLOBs), in combination with OracleLobHandler.
*
* <p>Can also be defined in generic iBATIS mappings, as DefaultLobCreator will
* work with most JDBC-compliant database drivers. In this case, the field type
* does not have to be BLOB: For databases like MySQL and MS SQL Server, any
* large enough binary type will work.
*
* @author Juergen Hoeller
* @since 1.1.5
* @see org.springframework.orm.ibatis.SqlMapClientFactoryBean#setLobHandler
* @deprecated as of Spring 3.2, in favor of the native Spring support
* in the Mybatis follow-up project (http://code.google.com/p/mybatis/)
*/
@Deprecated
public class ClobStringTypeHandler extends AbstractLobTypeHandler {
/**
* Constructor used by iBATIS: fetches config-time LobHandler from
* SqlMapClientFactoryBean.
* @see org.springframework.orm.ibatis.SqlMapClientFactoryBean#getConfigTimeLobHandler
*/
public ClobStringTypeHandler() {
super();
}
/**
* Constructor used for testing: takes an explicit LobHandler.
*/
protected ClobStringTypeHandler(LobHandler lobHandler) {
super(lobHandler);
}
@Override
protected void setParameterInternal(
PreparedStatement ps, int index, Object value, String jdbcType, LobCreator lobCreator)
throws SQLException {
lobCreator.setClobAsString(ps, index, (String) value);
}
@Override
protected Object getResultInternal(ResultSet rs, int index, LobHandler lobHandler)
throws SQLException {
return lobHandler.getClobAsString(rs, index);
}
public Object valueOf(String s) {
return s;
}
}

View File

@@ -1,116 +0,0 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.orm.ibatis.support;
import javax.sql.DataSource;
import com.ibatis.sqlmap.client.SqlMapClient;
import org.springframework.dao.support.DaoSupport;
import org.springframework.orm.ibatis.SqlMapClientTemplate;
import org.springframework.util.Assert;
/**
* Convenient super class for iBATIS SqlMapClient data access objects.
* Requires a SqlMapClient to be set, providing a SqlMapClientTemplate
* based on it to subclasses.
*
* <p>Instead of a plain SqlMapClient, you can also pass a preconfigured
* SqlMapClientTemplate instance in. This allows you to share your
* SqlMapClientTemplate configuration for all your DAOs, for example
* a custom SQLExceptionTranslator to use.
*
* @author Juergen Hoeller
* @since 24.02.2004
* @see #setSqlMapClient
* @see #setSqlMapClientTemplate
* @see org.springframework.orm.ibatis.SqlMapClientTemplate
* @see org.springframework.orm.ibatis.SqlMapClientTemplate#setExceptionTranslator
* @deprecated as of Spring 3.2, in favor of the native Spring support
* in the Mybatis follow-up project (http://code.google.com/p/mybatis/)
*/
@Deprecated
public abstract class SqlMapClientDaoSupport extends DaoSupport {
private SqlMapClientTemplate sqlMapClientTemplate = new SqlMapClientTemplate();
private boolean externalTemplate = false;
/**
* Set the JDBC DataSource to be used by this DAO.
* Not required: The SqlMapClient might carry a shared DataSource.
* @see #setSqlMapClient
*/
public final void setDataSource(DataSource dataSource) {
if (!this.externalTemplate) {
this.sqlMapClientTemplate.setDataSource(dataSource);
}
}
/**
* Return the JDBC DataSource used by this DAO.
*/
public final DataSource getDataSource() {
return this.sqlMapClientTemplate.getDataSource();
}
/**
* Set the iBATIS Database Layer SqlMapClient to work with.
* Either this or a "sqlMapClientTemplate" is required.
* @see #setSqlMapClientTemplate
*/
public final void setSqlMapClient(SqlMapClient sqlMapClient) {
if (!this.externalTemplate) {
this.sqlMapClientTemplate.setSqlMapClient(sqlMapClient);
}
}
/**
* Return the iBATIS Database Layer SqlMapClient that this template works with.
*/
public final SqlMapClient getSqlMapClient() {
return this.sqlMapClientTemplate.getSqlMapClient();
}
/**
* Set the SqlMapClientTemplate for this DAO explicitly,
* as an alternative to specifying a SqlMapClient.
* @see #setSqlMapClient
*/
public final void setSqlMapClientTemplate(SqlMapClientTemplate sqlMapClientTemplate) {
Assert.notNull(sqlMapClientTemplate, "SqlMapClientTemplate must not be null");
this.sqlMapClientTemplate = sqlMapClientTemplate;
this.externalTemplate = true;
}
/**
* Return the SqlMapClientTemplate for this DAO,
* pre-initialized with the SqlMapClient or set explicitly.
*/
public final SqlMapClientTemplate getSqlMapClientTemplate() {
return this.sqlMapClientTemplate;
}
@Override
protected final void checkDaoConfig() {
if (!this.externalTemplate) {
this.sqlMapClientTemplate.afterPropertiesSet();
}
}
}

View File

@@ -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;