Removed iBatis based components

This commit removes the iBatis based ItemReaders and ItemWriter.  They
were depricated in the 3.0 line in favor of the MyBatis natively
provided ItemReader and ItemWriter implementations.  This removes those
depricated components.

Resolves BATCH-2591
This commit is contained in:
Michael Minella
2017-05-03 10:00:41 -05:00
parent 910efb25e7
commit b3e8d3ea87
21 changed files with 0 additions and 1449 deletions

View File

@@ -75,7 +75,6 @@ allprojects {
hibernateVersion = '5.2.2.Final'
hibernateValidatorVersion = '5.3.0.CR1'
hsqldbVersion = '2.3.3'
ibatisVersion = '2.3.4.726'
jackson2Version = "2.8.6" //?
javaMailVersion = '1.5.6'
javaxBatchApiVersion = '1.0'
@@ -341,7 +340,6 @@ project('spring-batch-infrastructure') {
}
optional "org.hibernate:hibernate-validator:$hibernateValidatorVersion"
optional "javax.transaction:javax.transaction-api:$javaxTransactionVersion"
optional "org.apache.ibatis:ibatis-sqlmap:$ibatisVersion"
optional "javax.mail:javax.mail-api:$javaMailVersion"
optional "javax.batch:javax.batch-api:$javaxBatchApiVersion"
compile("org.springframework:spring-oxm:$springVersion") { dep ->
@@ -461,7 +459,6 @@ project('spring-batch-infrastructure-tests') {
testCompile "org.mockito:mockito-core:$mockitoVersion"
optional "org.slf4j:slf4j-log4j12:$slf4jVersion"
optional "org.apache.ibatis:ibatis-sqlmap:$ibatisVersion"
compile("org.hibernate:hibernate-core:$hibernateVersion") { dep ->
optional dep
exclude group: 'org.jboss.spec.javax.transaction', module: 'jboss-transaction-api_1.1_spec'
@@ -573,7 +570,6 @@ project('spring-batch-samples') {
exclude group: 'org.jboss.spec.javax.transaction', module: 'jboss-transaction-api_1.1_spec'
}
compile "javax.transaction:javax.transaction-api:$javaxTransactionVersion"
compile "org.apache.ibatis:ibatis-sqlmap:$ibatisVersion"
compile "org.springframework:spring-aop:$springVersion"
compile("org.springframework:spring-oxm:$springVersion") {
exclude group: 'commons-lang', module: 'commons-lang'

View File

@@ -268,15 +268,6 @@
<profiles>
</profiles>
</configSet>
<configSet>
<name><![CDATA[ibatis]]></name>
<allowBeanDefinitionOverriding>true</allowBeanDefinitionOverriding>
<incomplete>false</incomplete>
<configs>
</configs>
<profiles>
</profiles>
</configSet>
<configSet>
<name><![CDATA[partition]]></name>
<allowBeanDefinitionOverriding>true</allowBeanDefinitionOverriding>

View File

@@ -1,176 +0,0 @@
/*
* Copyright 2010-2014 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.batch.item.database;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Executors;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.item.sample.Foo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.jdbc.JdbcTestUtils;
import org.springframework.util.Assert;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "JdbcPagingItemReaderCommonTests-context.xml")
@SuppressWarnings("deprecation")
public class IbatisPagingItemReaderAsyncTests {
/**
* The number of items to read
*/
private static final int ITEM_COUNT = 1000;
/**
* The number of threads to create
*/
private static final int THREAD_COUNT = 10;
private static Log logger = LogFactory.getLog(IbatisPagingItemReaderAsyncTests.class);
@Autowired
private DataSource dataSource;
private int maxId;
@Before
public void init() {
Assert.notNull(dataSource);
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
maxId = jdbcTemplate.queryForObject("SELECT MAX(ID) from T_FOOS", Integer.class);
for (int i = ITEM_COUNT; i > maxId; i--) {
jdbcTemplate.update("INSERT into T_FOOS (ID,NAME,VALUE) values (?, ?, ?)", i, "foo" + i, i);
}
assertEquals(ITEM_COUNT, JdbcTestUtils.countRowsInTable(jdbcTemplate, "T_FOOS"));
}
@After
public void destroy() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.update("DELETE from T_FOOS where ID>?", maxId);
}
@Test
public void testAsyncReader() throws Throwable {
List<Throwable> throwables = new ArrayList<Throwable>();
int max = 10;
for (int i = 0; i < max; i++) {
try {
logger.info("Testing asynch reader, iteration="+i);
doTest();
}
catch (Throwable e) {
throwables.add(e);
}
}
if (!throwables.isEmpty()) {
throw new IllegalStateException(String.format("Failed %d out of %d", throwables.size(), max), throwables
.get(0));
}
}
/**
* @throws Exception
* @throws InterruptedException
* @throws ExecutionException
*/
private void doTest() throws Exception, InterruptedException, ExecutionException {
final IbatisPagingItemReader<Foo> reader = getItemReader();
reader.setDataSource(dataSource);
CompletionService<List<Foo>> completionService = new ExecutorCompletionService<List<Foo>>(Executors
.newFixedThreadPool(THREAD_COUNT));
for (int i = 0; i < THREAD_COUNT; i++) {
completionService.submit(new Callable<List<Foo>>() {
@Override
public List<Foo> call() throws Exception {
List<Foo> list = new ArrayList<Foo>();
Foo next = null;
do {
next = reader.read();
Thread.sleep(10L); // try to make it fairer
logger.debug("Reading item: " + next);
if (next != null) {
list.add(next);
}
} while (next != null);
return list;
}
});
}
int count = 0;
Set<Foo> results = new HashSet<Foo>();
for (int i = 0; i < THREAD_COUNT; i++) {
List<Foo> items = completionService.take().get();
count += items.size();
logger.debug("Finished items count: " + items.size());
logger.debug("Finished items: " + items);
assertNotNull(items);
results.addAll(items);
}
assertEquals(ITEM_COUNT, count);
assertEquals(ITEM_COUNT, results.size());
reader.close();
}
private IbatisPagingItemReader<Foo> getItemReader() throws Exception {
SqlMapClient sqlMapClient = createSqlMapClient();
IbatisPagingItemReader<Foo> reader = new IbatisPagingItemReader<Foo>();
if ("postgres".equals(System.getProperty("ENVIRONMENT"))) {
reader.setQueryId("getPagedFoosPostgres");
} else if ("oracle".equals(System.getProperty("ENVIRONMENT"))) {
reader.setQueryId("getPagedFoosOracle");
} else {
reader.setQueryId("getPagedFoos");
}
reader.setPageSize(2);
reader.setSqlMapClient(sqlMapClient);
reader.setSaveState(true);
reader.afterPropertiesSet();
return reader;
}
private SqlMapClient createSqlMapClient() throws Exception {
return SqlMapClientBuilder.buildSqlMapClient(new ClassPathResource("ibatis-config.xml", getClass()).getInputStream());
}
}

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<!-- lazy loading is enabled by default, but it is emphasized here - if it was set
to false, input source would load all data into memory! -->
<settings lazyLoadingEnabled="true"/>
<sqlMap resource="org/springframework/batch/item/database/ibatis-foo.xml" />
</sqlMapConfig>

View File

@@ -1,57 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="Foo">
<resultMap id="fooResult" class="org.springframework.batch.item.sample.Foo">
<result property="id" column="ID" />
<result property="name" column="NAME" />
<result property="value" column="VALUE" />
</resultMap>
<select id="getAllFooIds" resultClass="int">
select ID from T_FOOS
</select>
<select id="getFooById" parameterClass="int" resultMap="fooResult">
select ID, NAME, VALUE from T_FOOS where ID = #value#
</select>
<select id="getAllFoos" resultMap="fooResult">
select ID, NAME, VALUE from T_FOOS
</select>
<select id="getPagedFoos" resultMap="fooResult">
select LIMIT #_skiprows# #_pagesize# ID, NAME, VALUE from T_FOOS order by ID
</select>
<select id="getPagedFoosPostgres" resultMap="fooResult">
select ID, NAME, VALUE from T_FOOS order by ID LIMIT #_pagesize# OFFSET #_skiprows#
</select>
<select id="getPagedFoosOracle" resultMap="fooResult">
select * from (select ID, NAME, VALUE, ROWNUM as tmp from T_FOOS order by ID) where tmp &gt; #_skiprows# and tmp&lt;=(#_skiprows#+#_pagesize#)
</select>
<select id="getAllFooIdsRestart" resultClass="int">
select ID from T_FOOS where ID > #id#
</select>
<select id="getNoFoos" resultMap="fooResult">
select ID, NAME, VALUE from T_FOOS where ID = -1
</select>
<insert id="insertFoo" parameterClass="org.springframework.batch.item.sample.Foo">
insert INTO T_WRITE_FOOS (ID, NAME, VALUE) VALUES (#id#, #name#, #value#)
</insert>
<update id="updateFoo" parameterClass="org.springframework.batch.item.sample.Foo">
update T_WRITE_FOOS set NAME = #name#, VALUE = #value# where ID = #id#
</update>
<delete id="deleteFoo" parameterClass="org.springframework.batch.item.sample.Foo">
delete from T_WRITE_FOOS where ID = #id#
</delete>
</sqlMap>

View File

@@ -1,226 +0,0 @@
/*
* Copyright 2006-2014 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.batch.item.database;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapSession;
import com.ibatis.sqlmap.engine.execution.BatchException;
import com.ibatis.sqlmap.engine.execution.BatchResult;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.dao.InvalidDataAccessResourceUsageException;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator;
import org.springframework.jdbc.support.SQLExceptionTranslator;
import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;
import org.springframework.util.Assert;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
/**
* {@link ItemWriter} that uses the batching features from
* SqlMapClient to execute a batch of statements for all items
* provided.<br>
*
* The user must provide an iBATIS statement id that points to the SQL statement defined
* in the iBATIS SqlMap configuration.<br>
*
* It is expected that {@link #write(List)} is called inside a transaction.<br>
*
* The writer is thread-safe after its properties are set (normal singleton
* behavior), so it can be used to write in multiple concurrent transactions.<br>
*
* <em>Note:</em> This reader was refactored as part of Spring Batch 3.0 to use the iBatis
* APIs directly instead of using Spring's SqlMapClientTemplate as part of the upgrade to
* support Spring 4.
*
* @author Thomas Risberg
* @author Michael Minella
* @since 2.0
* @deprecated as of Spring Batch 3.0, in favor of the native Spring Batch support
* in the MyBatis follow-up project (http://mybatis.github.io/spring/)
*/
@Deprecated
public class IbatisBatchItemWriter<T> implements ItemWriter<T>, InitializingBean {
protected static final Log logger = LogFactory.getLog(IbatisBatchItemWriter.class);
private String statementId;
private boolean assertUpdates = true;
private SqlMapClient sqlMapClient;
private DataSource dataSource;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
/**
* Public setter for the flag that determines whether an assertion is made
* that all items cause at least one row to be updated.
*
* @param assertUpdates the flag to set. Defaults to true;
*/
public void setAssertUpdates(boolean assertUpdates) {
this.assertUpdates = assertUpdates;
}
/**
* Public setter for {@link SqlMapClient} for injection purposes.
*
* @param sqlMapClient the SqlMapClient
*/
public void setSqlMapClient(SqlMapClient sqlMapClient) {
this.sqlMapClient = sqlMapClient;
}
/**
* Public setter for the statement id identifying the statement in the SqlMap
* configuration file.
*
* @param statementId the id for the statement
*/
public void setStatementId(String statementId) {
this.statementId = statementId;
}
/**
* Check mandatory properties - there must be an SqlMapClient and a statementId.
*/
@Override
public void afterPropertiesSet() {
Assert.notNull(sqlMapClient, "A SqlMapClient is required.");
Assert.notNull(statementId, "A statementId is required.");
}
/* (non-Javadoc)
* @see org.springframework.batch.item.ItemWriter#write(java.util.List)
*/
@Override
public void write(final List<? extends T> items) {
if (!items.isEmpty()) {
if (logger.isDebugEnabled()) {
logger.debug("Executing batch with " + items.size() + " items.");
}
List<BatchResult> results = execute(items);
if (assertUpdates) {
if (results.size() != 1) {
throw new InvalidDataAccessResourceUsageException("Batch execution returned invalid results. " +
"Expected 1 but number of BatchResult objects returned was " + results.size());
}
int[] updateCounts = results.get(0).getUpdateCounts();
for (int i = 0; i < updateCounts.length; i++) {
int value = updateCounts[i];
if (value == 0) {
throw new EmptyResultDataAccessException("Item " + i + " of " + updateCounts.length
+ " did not update any rows: [" + items.get(i) + "]", 1);
}
}
}
}
}
@SuppressWarnings("unchecked")
private List<BatchResult> execute(final List<? extends T> items) {
// 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;
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 {
session.startBatch();
for (T item : items) {
session.update(statementId, item);
}
try {
return session.executeBatchDetailed();
} catch (BatchException e) {
throw e.getBatchUpdateException();
}
}
catch (SQLException ex) {
SQLExceptionTranslator sqlStateSQLExceptionTranslator;
if(dataSource != null) {
sqlStateSQLExceptionTranslator = new SQLStateSQLExceptionTranslator();
} else {
sqlStateSQLExceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(dataSource);
}
throw sqlStateSQLExceptionTranslator.translate("SqlMapClient operation", null, 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();
}
}
}
}

View File

@@ -1,243 +0,0 @@
/*
* Copyright 2006-2014 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.batch.item.database;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapSession;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator;
import org.springframework.jdbc.support.SQLExceptionTranslator;
import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* <p>
* {@link org.springframework.batch.item.ItemReader} for reading database
* records using iBATIS in a paging fashion.
* </p>
*
* <p>
* It executes the query specified as the {@link #setQueryId(String)} to
* retrieve requested data. The query is executed using paged requests of a size
* specified in {@link #setPageSize(int)}. Additional pages are requested when
* needed as {@link #read()} method is called, returning an object corresponding
* to current position. Some standard query parameters are provided by the
* reader and the SQL in the named query must use some or all of these parameters
* (depending on the SQL variant) to construct a result set of the required
* size. The parameters are:</p>
* <ul>
* <li><code>_page</code>: the page number to be read (starting at 0)</li>
* <li><code>_pagesize</code>: the size of the pages, i.e. the number of rows to
* return</li>
* <li><code>_skiprows</code>: the product of <code>_page</code> and
* <code>_pagesize</code></li>
* </ul>
* <p>
* Failure to write the correct platform-specific SQL often results in an
* infinite loop in the reader because it keeps asking for the next page and
* gets the same result set over and over.
* </p>
*
* <p>
* The performance of the paging depends on the iBATIS implementation.
* Setting a fairly large page size and using a commit interval that matches the
* page size should provide better performance.
* </p>
*
* <p>
* The implementation is thread-safe in between calls to
* {@link #open(ExecutionContext)}, but remember to use
* <code>saveState=false</code> if used in a multi-threaded client (no restart
* available).
* </p>
*
* <p><em>Note:</em> This reader was refactored as part of Spring Batch 3.0 to use the iBatis
* APIs directly instead of using Spring's SqlMapClientTemplate as part of the upgrade to
* support Spring 4.</p>
* @author Thomas Risberg
* @author Dave Syer
* @author Michael Minella
* @since 2.0
* @deprecated as of Spring Batch 3.0, in favor of the native Spring Batch support
* in the MyBatis follow-up project (http://mybatis.github.io/spring/)
*/
@Deprecated
public class IbatisPagingItemReader<T> extends AbstractPagingItemReader<T> {
private SqlMapClient sqlMapClient;
private String queryId;
private Map<String, Object> parameterValues;
private DataSource dataSource;
public IbatisPagingItemReader() {
setName(ClassUtils.getShortName(IbatisPagingItemReader.class));
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void setSqlMapClient(SqlMapClient sqlMapClient) {
this.sqlMapClient = sqlMapClient;
}
public void setQueryId(String queryId) {
this.queryId = queryId;
}
/**
* The parameter values to be used for the query execution.
*
* @param parameterValues the values keyed by the parameter named used in
* the query string.
*/
public void setParameterValues(Map<String, Object> parameterValues) {
this.parameterValues = parameterValues;
}
/**
* Check mandatory properties.
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
@Override
public void afterPropertiesSet() throws Exception {
super.afterPropertiesSet();
Assert.notNull(sqlMapClient);
Assert.notNull(queryId);
}
@Override
protected void doReadPage() {
Map<String, Object> parameters = new HashMap<String, Object>();
if (parameterValues != null) {
parameters.putAll(parameterValues);
}
parameters.put("_page", getPage());
parameters.put("_pagesize", getPageSize());
parameters.put("_skiprows", getPage() * getPageSize());
if (results == null) {
results = new CopyOnWriteArrayList<T>();
}
else {
results.clear();
}
results.addAll(execute(parameters));
}
@SuppressWarnings("unchecked")
private List<T> execute(Map<String, Object> parameters) {
// 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;
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 session.queryForList(queryId, parameters);
}
catch (SQLException ex) {
SQLExceptionTranslator sqlStateSQLExceptionTranslator;
if(dataSource != null) {
sqlStateSQLExceptionTranslator = new SQLStateSQLExceptionTranslator();
} else {
sqlStateSQLExceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(dataSource);
}
throw sqlStateSQLExceptionTranslator.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();
}
}
}
@Override
protected void doJumpToPage(int itemIndex) {
}
}

View File

@@ -1,196 +0,0 @@
/*
* Copyright 2006-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.batch.item.database;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Collections;
import java.util.List;
import javax.sql.DataSource;
import org.junit.Before;
import org.junit.Test;
import org.springframework.dao.EmptyResultDataAccessException;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapSession;
import com.ibatis.sqlmap.engine.execution.BatchResult;
/**
* @author Thomas Risberg
* @author Will Schipp
*/
@SuppressWarnings("deprecation")
public class IbatisBatchItemWriterTests {
private IbatisBatchItemWriter<Foo> writer = new IbatisBatchItemWriter<Foo>();
private DataSource ds;
private SqlMapClient smc;
private String statementId = "updateFoo";
@SuppressWarnings("unused")
private class Foo {
private Long id;
private String bar;
public Foo(String bar) {
this.id = 1L;
this.bar = bar;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getBar() {
return bar;
}
public void setBar(String bar) {
this.bar = bar;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Foo)) {
return false;
}
Foo compare = (Foo) obj;
if (this.bar.equals(compare.getBar())) {
return true;
}
return false;
}
@Override
public int hashCode() {
return bar.hashCode();
}
}
@Before
public void setUp() throws Exception {
smc = mock(SqlMapClient.class);
ds = mock(DataSource.class);
writer.setStatementId(statementId);
writer.setSqlMapClient(smc);
writer.setDataSource(ds);
writer.afterPropertiesSet();
}
/**
* Test method for
* {@link org.springframework.batch.item.database.JdbcBatchItemWriter#afterPropertiesSet()}
* .
* @throws Exception
*/
@Test
public void testAfterPropertiesSet() throws Exception {
writer = new IbatisBatchItemWriter<Foo>();
try {
writer.afterPropertiesSet();
fail("Expected IllegalArgumentException");
}
catch (IllegalArgumentException e) {
// expected
String message = e.getMessage();
assertTrue("Message does not contain 'SqlMapClient'.", message.indexOf("SqlMapClient") >= 0);
}
writer.setSqlMapClient(smc);
try {
writer.afterPropertiesSet();
fail("Expected IllegalArgumentException");
}
catch (IllegalArgumentException e) {
// expected
String message = e.getMessage();
assertTrue("Message does not contain 'statementId'.", message.indexOf("statementId") >= 0);
}
writer.setStatementId("statementId");
writer.afterPropertiesSet();
}
@Test
public void testWriteAndFlush() throws Exception {
SqlMapSession sms = mock(SqlMapSession.class);
when(smc.openSession()).thenReturn(sms);
sms.close();
when(sms.getCurrentConnection()).thenReturn(null);
sms.setUserConnection(null);
sms.startBatch();
when(sms.update("updateFoo", new Foo("bar"))).thenReturn(-2);
List<BatchResult> results = Collections.singletonList(new BatchResult("updateFoo", "update foo"));
results.get(0).setUpdateCounts(new int[] {1});
when(sms.executeBatchDetailed()).thenReturn(results);
writer.write(Collections.singletonList(new Foo("bar")));
}
@Test
public void testWriteAndFlushWithEmptyUpdate() throws Exception {
SqlMapSession sms = mock(SqlMapSession.class);
when(smc.openSession()).thenReturn(sms);
sms.close();
when(sms.getCurrentConnection()).thenReturn(null);
sms.setUserConnection(null);
sms.startBatch();
when(sms.update("updateFoo", new Foo("bar"))).thenReturn(1);
List<BatchResult> results = Collections.singletonList(new BatchResult("updateFoo", "update foo"));
results.get(0).setUpdateCounts(new int[] {0});
when(sms.executeBatchDetailed()).thenReturn(results);
try {
writer.write(Collections.singletonList(new Foo("bar")));
fail("Expected EmptyResultDataAccessException");
}
catch (EmptyResultDataAccessException e) {
// expected
String message = e.getMessage();
assertTrue("Wrong message: " + message, message.indexOf("did not update") >= 0);
}
}
@Test
public void testWriteAndFlushWithFailure() throws Exception {
final RuntimeException ex = new RuntimeException("ERROR");
SqlMapSession sms = mock(SqlMapSession.class);
when(smc.openSession()).thenReturn(sms);
sms.close();
when(sms.getCurrentConnection()).thenReturn(null);
sms.setUserConnection(null);
sms.startBatch();
when(sms.update("updateFoo", new Foo("bar"))).thenThrow(ex);
try {
writer.write(Collections.singletonList(new Foo("bar")));
fail("Expected RuntimeException");
}
catch (RuntimeException e) {
assertEquals("ERROR", e.getMessage());
}
}
}

View File

@@ -1,167 +0,0 @@
/*
* Copyright 2009-2014 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.batch.item.database;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Executors;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.item.sample.Foo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.jdbc.JdbcTestUtils;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "JdbcPagingItemReaderCommonTests-context.xml")
@SuppressWarnings("deprecation")
public class IbatisPagingItemReaderAsyncTests {
/**
* The number of items to read
*/
private static final int ITEM_COUNT = 10;
/**
* The number of threads to create
*/
private static final int THREAD_COUNT = 3;
private static Log logger = LogFactory.getLog(IbatisPagingItemReaderAsyncTests.class);
@Autowired
private DataSource dataSource;
private int maxId;
@Before
public void init() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
maxId = jdbcTemplate.queryForObject("SELECT MAX(ID) from T_FOOS", Integer.class);
for (int i = maxId + 1; i <= ITEM_COUNT; i++) {
jdbcTemplate.update("INSERT into T_FOOS (ID,NAME,VALUE) values (?, ?, ?)", i, "foo" + i, i);
}
assertEquals(ITEM_COUNT, JdbcTestUtils.countRowsInTable(jdbcTemplate, "T_FOOS"));
}
@After
public void destroy() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.update("DELETE from T_FOOS where ID>?", maxId);
}
@Test
public void testAsyncReader() throws Throwable {
List<Throwable> throwables = new ArrayList<Throwable>();
int max = 10;
for (int i = 0; i < max; i++) {
try {
doTest();
}
catch (Throwable e) {
throwables.add(e);
}
}
if (!throwables.isEmpty()) {
throw new IllegalStateException(String.format("Failed %d out of %d", throwables.size(), max), throwables
.get(0));
}
}
/**
* @throws Exception
* @throws InterruptedException
* @throws ExecutionException
*/
private void doTest() throws Exception, InterruptedException, ExecutionException {
final IbatisPagingItemReader<Foo> reader = getItemReader();
CompletionService<List<Foo>> completionService = new ExecutorCompletionService<List<Foo>>(Executors
.newFixedThreadPool(THREAD_COUNT));
for (int i = 0; i < THREAD_COUNT; i++) {
completionService.submit(new Callable<List<Foo>>() {
@Override
public List<Foo> call() throws Exception {
List<Foo> list = new ArrayList<Foo>();
Foo next = null;
do {
next = reader.read();
Thread.sleep(10L); // try to make it fairer
logger.debug("Reading item: " + next);
if (next != null) {
list.add(next);
}
} while (next != null);
return list;
}
});
}
int count = 0;
Set<Foo> results = new HashSet<Foo>();
for (int i = 0; i < THREAD_COUNT; i++) {
List<Foo> items = completionService.take().get();
count += items.size();
logger.debug("Finished items count: " + items.size());
logger.debug("Finished items: " + items);
assertNotNull(items);
results.addAll(items);
}
assertEquals(ITEM_COUNT, count);
assertEquals(ITEM_COUNT, results.size());
reader.close();
}
private IbatisPagingItemReader<Foo> getItemReader() throws Exception {
SqlMapClient sqlMapClient = createSqlMapClient();
IbatisPagingItemReader<Foo> reader = new IbatisPagingItemReader<Foo>();
reader.setQueryId("getPagedFoos");
reader.setPageSize(2);
reader.setSqlMapClient(sqlMapClient);
reader.setSaveState(true);
reader.setDataSource(dataSource);
reader.afterPropertiesSet();
return reader;
}
private SqlMapClient createSqlMapClient() throws Exception {
return SqlMapClientBuilder.buildSqlMapClient(new ClassPathResource("ibatis-config.xml", getClass()).getInputStream());
}
}

View File

@@ -1,63 +0,0 @@
/*
* Copyright 2008-2014 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.batch.item.database;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.sample.Foo;
import org.springframework.core.io.ClassPathResource;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
@RunWith(JUnit4.class)
@SuppressWarnings("deprecation")
public class IbatisPagingItemReaderCommonTests extends AbstractDatabaseItemStreamItemReaderTests {
@Override
protected ItemReader<Foo> getItemReader() throws Exception {
SqlMapClient sqlMapClient = createSqlMapClient();
IbatisPagingItemReader<Foo> reader = new IbatisPagingItemReader<Foo>();
reader.setQueryId("getPagedFoos");
reader.setPageSize(2);
reader.setSqlMapClient(sqlMapClient);
reader.setDataSource(getDataSource());
reader.setSaveState(true);
reader.afterPropertiesSet();
return reader;
}
private SqlMapClient createSqlMapClient() throws Exception {
return SqlMapClientBuilder.buildSqlMapClient(new ClassPathResource("ibatis-config.xml", getClass()).getInputStream());
}
@Override
protected void pointToEmptyInput(ItemReader<Foo> tested) throws Exception {
IbatisPagingItemReader<Foo> reader = (IbatisPagingItemReader<Foo>) tested;
reader.close();
reader.setQueryId("getNoFoos");
reader.afterPropertiesSet();
reader.open(new ExecutionContext());
}
}

View File

@@ -1,54 +0,0 @@
/*
* Copyright 2008-2014 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.batch.item.database;
import java.util.Collections;
import org.junit.runner.RunWith;
import org.springframework.batch.item.sample.Foo;
import org.springframework.core.io.ClassPathResource;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/org/springframework/batch/item/database/data-source-context.xml")
public class IbatisPagingItemReaderParameterTests extends AbstractPagingItemReaderParameterTests {
@Override
@SuppressWarnings("deprecation")
protected AbstractPagingItemReader<Foo> getItemReader() throws Exception {
SqlMapClient sqlMapClient = createSqlMapClient();
IbatisPagingItemReader<Foo> reader = new IbatisPagingItemReader<Foo>();
reader.setQueryId("getPagedFoosLimitAndUp");
reader.setParameterValues(Collections.<String, Object>singletonMap("limit", 2));
reader.setSqlMapClient(sqlMapClient);
reader.setDataSource(dataSource);
reader.setSaveState(true);
reader.afterPropertiesSet();
return reader;
}
private SqlMapClient createSqlMapClient() throws Exception {
SqlMapClient client = SqlMapClientBuilder.buildSqlMapClient(new ClassPathResource("ibatis-config.xml", getClass()).getInputStream());
return client;
}
}

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<!-- lazy loading is enabled by default, but it is emphasized here - if it was set
to false, input source would load all data into memory! -->
<settings lazyLoadingEnabled="true"/>
<sqlMap resource="org/springframework/batch/item/database/ibatis-foo.xml" />
</sqlMapConfig>

View File

@@ -1,57 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="Foo">
<resultMap id="fooResult" class="org.springframework.batch.item.sample.Foo">
<result property="id" column="ID" />
<result property="name" column="NAME" />
<result property="value" column="VALUE" />
</resultMap>
<select id="getAllFooIds" resultClass="int">
select ID from T_FOOS
</select>
<select id="getFooById" parameterClass="int" resultMap="fooResult">
select ID, NAME, VALUE from T_FOOS where ID = #value#
</select>
<select id="getAllFoos" resultMap="fooResult">
select ID, NAME, VALUE from T_FOOS
</select>
<select id="getPagedFoos" resultMap="fooResult">
select LIMIT #_skiprows# #_pagesize# ID, NAME, VALUE from T_FOOS order by ID
</select>
<select id="getPagedFoosLimitAndUp" resultMap="fooResult">
select LIMIT #_skiprows# #_pagesize# ID, NAME, VALUE from T_FOOS where VALUE >= #limit# order by ID
</select>
<select id="getFoosLimitAndUp" resultMap="fooResult">
select ID, NAME, VALUE from T_FOOS where VALUE >= #limit#
</select>
<select id="getAllFooIdsRestart" resultClass="int">
select ID from T_FOOS where ID > #id#
</select>
<select id="getNoFoos" resultMap="fooResult">
select ID, NAME, VALUE from T_FOOS where ID = -1
</select>
<insert id="insertFoo" parameterClass="org.springframework.batch.item.sample.Foo">
insert INTO T_WRITE_FOOS (ID, NAME, VALUE) VALUES (#id#, #name#, #value#)
</insert>
<update id="updateFoo" parameterClass="org.springframework.batch.item.sample.Foo">
update T_WRITE_FOOS set NAME = #name#, VALUE = #value# where ID = #id#
</update>
<delete id="deleteFoo" parameterClass="org.springframework.batch.item.sample.Foo">
delete from T_WRITE_FOOS where ID = #id#
</delete>
</sqlMap>

View File

@@ -43,7 +43,6 @@
<config>src/main/resources/jobs/iosample/hibernate.xml</config>
<config>src/main/resources/jobs/hibernateJob.xml</config>
<config>src/main/resources/jobs/iosample/jpa.xml</config>
<config>src/main/resources/jobs/iosample/ibatis.xml</config>
<config>src/test/resources/org/springframework/batch/sample/domain/trade/internal/JdbcCustomerDebitDaoTests-context.xml</config>
<config>src/main/resources/jobs/loopFlowSample.xml</config>
<config>src/test/resources/org/springframework/batch/sample/common/StagingItemReaderTests-context.xml</config>
@@ -429,19 +428,6 @@
<profiles>
</profiles>
</configSet>
<configSet>
<name><![CDATA[ibatis]]></name>
<allowBeanDefinitionOverriding>true</allowBeanDefinitionOverriding>
<incomplete>false</incomplete>
<configs>
<config>src/main/resources/data-source-context.xml</config>
<config>src/main/resources/simple-job-launcher-context.xml</config>
<config>src/main/resources/org/springframework/batch/sample/config/common-context.xml</config>
<config>src/main/resources/jobs/iosample/ibatis.xml</config>
</configs>
<profiles>
</profiles>
</configSet>
<configSet>
<name><![CDATA[partition]]></name>
<allowBeanDefinitionOverriding>true</allowBeanDefinitionOverriding>

View File

@@ -51,7 +51,6 @@ Job/Feature | delimited input | fixed-length input | xml input |
:-------------------------- | :-------------: | :----------------: | :-------: | :-------------: | :-------------: | :--------------: | :-----------------: | :--------: | :-------: | :------------: | :--------: | :----------:
delimited | x | | | | | | | x | | | |
[fixedLength](#fixedLength) | | x | | | | | | | x | | |
[ibatis](#ibatis) | | | | | x | | | | | | x |
[hibernate](#hibernate) | | | | | x | | | | | | x |
[jdbcCursor](#jdbcCursor) | | | | | x | | | | | | x |
jpa | | | | x | | | | | | | x |
@@ -521,12 +520,6 @@ The output reliability and robustness are improved by the use of
need to take control of it so that the skip and retry features
provided by Spring Batch can work effectively.
### [Ibatis Sample](id:ibatis)
The goal of this sample is to show the use of Ibatis as a query
mapping tool. Its features are similar to the Hibernate sample, but
it uses Ibatis to drive its input and output.
### [Infinite Loop Sample](id:infiniteLoop)
This sample has a single step that is an infinite loop, reading and

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<sqlMap resource="ibatis-customer-credit.xml"/>
</sqlMapConfig>

View File

@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="Customer">
<resultMap id="result" class="org.springframework.batch.sample.domain.trade.CustomerCredit">
<result property="name" column="NAME" />
<result property="credit" column="CREDIT" />
</resultMap>
<select id="getAllCustomerCreditIds" resultClass="int">
select ID from CUSTOMER
</select>
<select id="getAllCustomerCredits" resultMap="result">
select ID, NAME, CREDIT from CUSTOMER
</select>
<select id="getCustomerCreditById" parameterClass="int" resultMap="result">
select NAME, CREDIT from CUSTOMER where ID = #value#
</select>
<update id="updateCredit" parameterClass="org.springframework.batch.sample.domain.trade.CustomerCredit" >
update CUSTOMER set CREDIT = #credit# where NAME = #name#
</update>
</sqlMap>

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="itemReader"
class="org.springframework.batch.item.database.IbatisPagingItemReader">
<property name="queryId" value="getAllCustomerCredits" />
<property name="sqlMapClient" ref="sqlMapClient" />
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="itemWriter"
class="org.springframework.batch.item.database.IbatisBatchItemWriter">
<property name="statementId" value="updateCredit" />
<property name="sqlMapClient" ref="sqlMapClient" />
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="sqlMapClient" class="com.ibatis.sqlmap.client.SqlMapClientBuilder" factory-method="buildSqlMapClient">
<constructor-arg value="ibatis-config.xml"/>
</bean>
</beans>

View File

@@ -1,33 +0,0 @@
/*
* Copyright 2008-2009 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.batch.sample.iosample;
import org.junit.runner.RunWith;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.sample.domain.trade.CustomerCredit;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/jobs/iosample/ibatis.xml")
public class IbatisFunctionalTests extends AbstractIoSampleTests {
@Override
protected void pointReaderToOutput(ItemReader<CustomerCredit> reader) {
// no-op
}
}

View File

@@ -73,15 +73,6 @@
<entry align="left">Reads from a paginated HQL query</entry>
</row>
<row>
<entry align="left">IbatisPagingItemReader</entry>
<entry align="left">Reads via iBATIS based on a query. Pages
through the rows so that large datasets can be read without
running out of memory. See HOWTO - Read from a Database. This
ItemReader is now deprecated as of Spring Batch 3.0.</entry>
</row>
<row>
<entry align="left">ItemReaderAdapter</entry>
@@ -236,13 +227,6 @@
to another item writer to do the actual writing.</entry>
</row>
<row>
<entry align="left">IbatisBatchItemWriter</entry>
<entry align="left">Writes items in a batch using the iBatis API's
directly. This ItemWriter is deprecated as of Spring Batch 3.0.</entry>
</row>
<row>
<entry align="left">ItemWriterAdapter</entry>

View File

@@ -2270,53 +2270,6 @@ itemReader.close(executionContext);</programlisting>
entities read from the database for each query execution.</para>
</section>
<section id="IbatisPagingItemReader">
<title>IbatisPagingItemReader</title>
<note>This reader is deprecated as of Spring Batch 3.0.</note>
<para>If you use IBATIS for your data access then you can use the
<classname>IbatisPagingItemReader</classname> which, as the name
indicates, is an implementation of a paging
<classname>ItemReader</classname>. IBATIS doesn't have direct support
for reading rows in pages but by providing a couple of standard
variables you can add paging support to your IBATIS queries.</para>
<para>Here is an example of a configuration for a
<classname>IbatisPagingItemReader</classname> reading CustomerCredits
as in the examples above:</para>
<programlisting language="xml">&lt;bean id="itemReader" class="org.spr...IbatisPagingItemReader"&gt;
&lt;property name="sqlMapClient" ref="sqlMapClient"/&gt;
&lt;property name="queryId" value="getPagedCustomerCredits"/&gt;
&lt;property name="pageSize" value="1000"/&gt;
&lt;/bean&gt;</programlisting>
<para>The <classname>IbatisPagingItemReader</classname> configuration
above references an IBATIS query called "getPagedCustomerCredits".
Here is an example of what that query should look like for
MySQL.</para>
<programlisting language="xml">&lt;select id="getPagedCustomerCredits" resultMap="customerCreditResult"&gt;
select id, name, credit from customer order by id asc LIMIT #_skiprows#, #_pagesize#
&lt;/select&gt;</programlisting>
<para>The <classname>_skiprows</classname> and
<classname>_pagesize</classname> variables are provided by the
<classname>IbatisPagingItemReader</classname> and there is also a
<classname>_page</classname> variable that can be used if necessary.
The syntax for the paging queries varies with the database used. Here
is an example for Oracle (unfortunately we need to use CDATA for some
operators since this belongs in an XML document):</para>
<programlisting language="xml">&lt;select id="getPagedCustomerCredits" resultMap="customerCreditResult"&gt;
select * from (
select * from (
select t.id, t.name, t.credit, ROWNUM ROWNUM_ from customer t order by id
)) where ROWNUM_ &lt;![CDATA[ &gt; ]]&gt; ( #_page# * #_pagesize# )
) where ROWNUM &lt;![CDATA[ &lt;= ]]&gt; #_pagesize#
&lt;/select&gt;</programlisting>
</section>
</section>
<section id="databaseItemWriters">