SqlMapClientFactoryBean
* Copyright 2002-2005 the original author or authors.
package org.springframework.orm.ibatis;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;
import javax.sql.DataSource;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
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.io.Resource;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
import org.springframework.jdbc.support.lob.LobHandler;
/**
* FactoryBean that creates an iBATIS Database Layer SqlMapClient as singleton
* in the current bean factory, possibly for use with SqlMapClientTemplate.
*
* <p>Allows to specify 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.
*
* @author Juergen Hoeller
* @since 24.02.2004
* @see #setConfigLocation
* @see #setDataSource
* @see SqlMapClientTemplate#setSqlMapClient
* @see SqlMapClientTemplate#setDataSource
*/
public class SqlMapClientFactoryBean implements FactoryBean, InitializingBean {
private static ThreadLocal configTimeLobHandlerHolder = new ThreadLocal();
/**
* 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 (LobHandler) configTimeLobHandlerHolder.get();
}
private Resource configLocation;
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".
*/
public void setConfigLocation(Resource configLocation) {
this.configLocation = configLocation;
}
/**
* Set optional properties to be passed into the SqlMapClientBuilder, as
* alternative to a <code><properties></code> 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.Reader, 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
* @see SqlMapClientTemplate#queryForPaginatedList
*/
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</code>.
* <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.configLocation == null) {
throw new IllegalArgumentException("configLocation is required");
}
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 {
// Build the SqlMapClient.
InputStream is = this.configLocation.getInputStream();
this.sqlMapClient = (this.sqlMapClientProperties != null) ?
SqlMapClientBuilder.buildSqlMapClient(new InputStreamReader(is), this.sqlMapClientProperties) :
SqlMapClientBuilder.buildSqlMapClient(new InputStreamReader(is));
// 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.set(null);
}
}
}
/**
* Apply the given iBATIS TransactionConfig to the SqlMapClient.
* <p>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 (!(this.sqlMapClient instanceof ExtendedSqlMapClient)) {
throw new IllegalArgumentException(
"Cannot set TransactionConfig with DataSource for SqlMapClient if not of type " +
"ExtendedSqlMapClient: " + this.sqlMapClient);
}
ExtendedSqlMapClient extendedClient = (ExtendedSqlMapClient) this.sqlMapClient;
transactionConfig.setMaximumConcurrentTransactions(extendedClient.getDelegate().getMaxTransactions());
extendedClient.getDelegate().setTxManager(new TransactionManager(transactionConfig));
}
public Object getObject() {
return this.sqlMapClient;
}
public Class getObjectType() {
return (this.sqlMapClient != null ? this.sqlMapClient.getClass() : SqlMapClient.class);
}
public boolean isSingleton() {
return true;
}
}
SqlMapClientDaoSupport
* Copyright 2002-2005 the original author or authors.
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;
/**
* 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
*/
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) {
this.sqlMapClientTemplate.setDataSource(dataSource);
}
/**
* Return the JDBC DataSource used by this DAO.
*/
public final DataSource getDataSource() {
return (this.sqlMapClientTemplate != null ? this.sqlMapClientTemplate.getDataSource() : null);
}
/**
* Set the iBATIS Database Layer SqlMapClient to work with.
* Either this or a "sqlMapClientTemplate" is required.
* @see #setSqlMapClientTemplate
*/
public final void setSqlMapClient(SqlMapClient sqlMapClient) {
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) {
if (sqlMapClientTemplate == null) {
throw new IllegalArgumentException("Cannot set sqlMapClientTemplate to 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 sqlMapClientTemplate;
}
protected final void checkDaoConfig() {
if (!this.externalTemplate) {
this.sqlMapClientTemplate.afterPropertiesSet();
}
}
}
SqlMapClientTemplate
* Copyright 2002-2005 the original author or authors.
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.common.util.PaginatedList;
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 com.ibatis.sqlmap.engine.impl.ExtendedSqlMapClient;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.jdbc.JdbcUpdateAffectedIncorrectNumberOfRowsException;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.support.JdbcAccessor;
import org.springframework.util.Assert;
/**
* Helper class that simplifies data access via the SqlMapClient API of iBATIS
* SQL Maps, and converts checked SQLExceptions into unchecked DataAccessExceptions,
* following the <code>org.springframework.dao</code> exception hierarchy.
* Uses the same SQLExceptionTranslator mechanism as 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 SqlMapExecutor's execution methods. See the
* SqlMapExecutor javadocs for details on those 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>
* 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. Can additionally be configured with a DataSource for fetching Connections,
* although this is not necessary if a DataSource is specified for the SqlMapClient itself.
*
* @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.SqlMapSession
* @see com.ibatis.sqlmap.client.SqlMapExecutor
*/
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 sqlMapClient;
}
/**
* If no DataSource specified, use SqlMapClient's DataSource.
* @see com.ibatis.sqlmap.client.SqlMapClient#getDataSource
*/
public DataSource getDataSource() {
DataSource ds = super.getDataSource();
return (ds != null ? ds : this.sqlMapClient.getDataSource());
}
public void afterPropertiesSet() {
if (this.sqlMapClient == null) {
throw new IllegalArgumentException("sqlMapClient is required");
}
super.afterPropertiesSet();
}
/**
* Execute the given data access action on a SqlMapSession.
* @param action callback object that specifies the data access action
* @return a result object returned by the action, or <code>null</code>
* @throws DataAccessException in case of SQL Maps errors
*/
public Object execute(SqlMapClientCallback action) throws DataAccessException {
Assert.notNull(this.sqlMapClient, "No SqlMapClient specified");
// We always needs 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();
try {
Connection con = DataSourceUtils.getConnection(getDataSource());
try {
session.setUserConnection(con);
return action.doInSqlMapClient(session);
}
catch (SQLException ex) {
throw getExceptionTranslator().translate("SqlMapClient operation", null, ex);
}
finally {
DataSourceUtils.releaseConnection(con, getDataSource());
}
}
finally {
session.close();
}
}
/**
* Execute the given data access action on a SqlMapSession,
* 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
*/
public List executeWithListResult(SqlMapClientCallback action) throws DataAccessException {
return (List) execute(action);
}
/**
* Execute the given data access action on a SqlMapSession,
* 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
*/
public Map executeWithMapResult(SqlMapClientCallback action) throws DataAccessException {
return (Map) execute(action);
}
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(final String statementName, final Object parameterObject)
throws DataAccessException {
return executeWithListResult(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return executor.queryForList(statementName, parameterObject);
}
});
}
public List queryForList(
final String statementName, final Object parameterObject, final int skipResults, final int maxResults)
throws DataAccessException {
return executeWithListResult(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return executor.queryForList(statementName, parameterObject, skipResults, maxResults);
}
});
}
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 PaginatedList queryForPaginatedList(
final String statementName, final Object parameterObject, final int pageSize)
throws DataAccessException {
// throw exception if lazy loading will not work
if (this.sqlMapClient instanceof ExtendedSqlMapClient &&
((ExtendedSqlMapClient) this.sqlMapClient).getDelegate().getTxManager() == null) {
throw new InvalidDataAccessApiUsageException(
"SqlMapClient needs to have DataSource to allow for lazy loading" +
" - specify SqlMapClientFactoryBean's 'dataSource' property");
}
return (PaginatedList) execute(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return executor.queryForPaginatedList(statementName, parameterObject, pageSize);
}
});
}
public Map queryForMap(
final String statementName, final Object parameterObject, final String keyProperty)
throws DataAccessException {
return executeWithMapResult(new SqlMapClientCallback() {
public Object 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 executeWithMapResult(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return executor.queryForMap(statementName, parameterObject, keyProperty, valueProperty);
}
});
}
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(final String statementName, final Object parameterObject)
throws DataAccessException {
Integer result = (Integer) execute(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return new Integer(executor.update(statementName, parameterObject));
}
});
return result.intValue();
}
public int delete(final String statementName, final Object parameterObject)
throws DataAccessException {
Integer result = (Integer) execute(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return new Integer(executor.delete(statementName, parameterObject));
}
});
return result.intValue();
}
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 void delete(String statementName, Object parameterObject, int requiredRowsAffected)
throws DataAccessException {
int actualRowsAffected = delete(statementName, parameterObject);
if (actualRowsAffected != requiredRowsAffected) {
throw new JdbcUpdateAffectedIncorrectNumberOfRowsException(
statementName, requiredRowsAffected, actualRowsAffected);
}
}
}