Helper class that simplifies data access via the iBATIS
API, converting checked
SQLExceptions into unchecked DataAccessExceptions, following the
The main method of this class executes a callback that implements a
data access action. Furthermore, this class provides numerous convenience
methods that mirror com.ibatis.sqlmap.client.SqlMapExecutor 's
execution methods.
It is generally recommended to use the convenience methods on this template
for plain query/insert/update/delete operations. However, for more complex
operations like batch updates, a custom SqlMapClientCallback must be implemented,
usually as anonymous inner class. For example:
The template needs a SqlMapClient to work on, passed in via the "sqlMapClient"
property. A Spring context typically uses a
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).
| Method from org.springframework.orm.ibatis.SqlMapClientTemplate Detail: |
public void afterPropertiesSet() {
if (this.sqlMapClient == null) {
throw new IllegalArgumentException("Property 'sqlMapClient' is required");
}
if (this.sqlMapClient instanceof ExtendedSqlMapClient) {
// Check whether iBATIS lazy loading is available, that is,
// whether a DataSource was specified on the SqlMapClient itself.
this.lazyLoadingAvailable = (((ExtendedSqlMapClient) this.sqlMapClient).getDelegate().getTxManager() != null);
}
super.afterPropertiesSet();
}
|
public int delete(String statementName) throws DataAccessException {
return delete(statementName, null);
}
|
public int delete(String statementName,
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 delete(String statementName,
Object parameterObject,
int requiredRowsAffected) throws DataAccessException {
int actualRowsAffected = delete(statementName, parameterObject);
if (actualRowsAffected != requiredRowsAffected) {
throw new JdbcUpdateAffectedIncorrectNumberOfRowsException(
statementName, requiredRowsAffected, actualRowsAffected);
}
}
|
public Object execute(SqlMapClientCallback action) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
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();
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. |
public List executeWithListResult(SqlMapClientCallback action) throws DataAccessException {
return (List) execute(action);
}
Execute the given data access action on a SqlMapExecutor,
expecting a List result. |
public Map executeWithMapResult(SqlMapClientCallback action) throws DataAccessException {
return (Map) execute(action);
}
Execute the given data access action on a SqlMapExecutor,
expecting a Map result. |
public DataSource getDataSource() {
DataSource ds = super.getDataSource();
return (ds != null ? ds : this.sqlMapClient.getDataSource());
}
If no DataSource specified, use SqlMapClient's DataSource. |
public SqlMapClient getSqlMapClient() {
return this.sqlMapClient;
}
Return the iBATIS Database Layer SqlMapClient that this template works with. |
public Object insert(String statementName) throws DataAccessException {
return insert(statementName, null);
}
|
public Object insert(String statementName,
Object parameterObject) throws DataAccessException {
return execute(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return executor.insert(statementName, parameterObject);
}
});
}
|
public List queryForList(String statementName) throws DataAccessException {
return queryForList(statementName, null);
}
|
public List queryForList(String statementName,
Object parameterObject) throws DataAccessException {
return executeWithListResult(new SqlMapClientCallback() {
public Object 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(String statementName,
Object parameterObject,
int skipResults,
int maxResults) throws DataAccessException {
return executeWithListResult(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return executor.queryForList(statementName, parameterObject, skipResults, maxResults);
}
});
}
|
public Map queryForMap(String statementName,
Object parameterObject,
String keyProperty) throws DataAccessException {
return executeWithMapResult(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return executor.queryForMap(statementName, parameterObject, keyProperty);
}
});
}
|
public Map queryForMap(String statementName,
Object parameterObject,
String keyProperty,
String valueProperty) throws DataAccessException {
return executeWithMapResult(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return executor.queryForMap(statementName, parameterObject, keyProperty, valueProperty);
}
});
}
|
public Object queryForObject(String statementName) throws DataAccessException {
return queryForObject(statementName, null);
}
|
public Object queryForObject(String statementName,
Object parameterObject) throws DataAccessException {
return execute(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return executor.queryForObject(statementName, parameterObject);
}
});
}
|
public Object queryForObject(String statementName,
Object parameterObject,
Object resultObject) throws DataAccessException {
return execute(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return executor.queryForObject(statementName, parameterObject, resultObject);
}
});
}
|
public PaginatedList queryForPaginatedList(String statementName,
int pageSize) throws DataAccessException {
return queryForPaginatedList(statementName, null, pageSize);
} Deprecated! as - of iBATIS 2.3.0
|
public PaginatedList queryForPaginatedList(String statementName,
Object parameterObject,
int pageSize) throws DataAccessException {
// Throw exception if lazy loading will not work.
if (!this.lazyLoadingAvailable) {
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);
}
});
} Deprecated! as - of iBATIS 2.3.0
|
public void queryWithRowHandler(String statementName,
RowHandler rowHandler) throws DataAccessException {
queryWithRowHandler(statementName, null, rowHandler);
}
|
public void queryWithRowHandler(String statementName,
Object parameterObject,
RowHandler rowHandler) throws DataAccessException {
execute(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
executor.queryWithRowHandler(statementName, parameterObject, rowHandler);
return null;
}
});
}
|
public void setSqlMapClient(SqlMapClient sqlMapClient) {
this.sqlMapClient = sqlMapClient;
}
Set the iBATIS Database Layer SqlMapClient that defines the mapped statements. |
public int update(String statementName) throws DataAccessException {
return update(statementName, null);
}
|
public int update(String statementName,
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 void update(String statementName,
Object parameterObject,
int requiredRowsAffected) throws DataAccessException {
int actualRowsAffected = update(statementName, parameterObject);
if (actualRowsAffected != requiredRowsAffected) {
throw new JdbcUpdateAffectedIncorrectNumberOfRowsException(
statementName, requiredRowsAffected, actualRowsAffected);
}
}
|