spring-ibatis 主要ソース

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>&lt;properties&gt;</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);
		}
	}

}
スポンサーリンク
google 6948682462
google 6948682462

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク
google 6948682462