BATCH-1460: fix paging queries in Derby and Oracle.
This commit is contained in:
@@ -108,7 +108,6 @@
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.derby</groupId>
|
||||
|
||||
@@ -109,6 +109,11 @@
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.derby</groupId>
|
||||
<artifactId>derby</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
|
||||
@@ -39,4 +39,15 @@ public class DerbyPagingQueryProvider extends SqlWindowingPagingQueryProvider {
|
||||
throw new InvalidDataAccessResourceUsageException("Apache Derby version " + version + " is not supported by this class, Only version 10.4.1.3 or later is supported");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getSubQueryAlias() {
|
||||
return "AS TMP_SUB ";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getOverClause() {
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,13 +17,14 @@
|
||||
package org.springframework.batch.item.database.support;
|
||||
|
||||
/**
|
||||
* Oracle implementation of a {@link org.springframework.batch.item.database.PagingQueryProvider} using
|
||||
* Oracle implementation of a
|
||||
* {@link org.springframework.batch.item.database.PagingQueryProvider} using
|
||||
* database specific features.
|
||||
*
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @since 2.0
|
||||
*/
|
||||
public class OraclePagingQueryProvider extends SqlWindowingPagingQueryProvider {
|
||||
public class OraclePagingQueryProvider extends AbstractSqlPagingQueryProvider {
|
||||
|
||||
@Override
|
||||
public String generateFirstPageQuery(int pageSize) {
|
||||
@@ -36,6 +37,15 @@ public class OraclePagingQueryProvider extends SqlWindowingPagingQueryProvider {
|
||||
return SqlPagingQueryUtils.generateRowNumSqlQuery(this, true, buildRowNumClause(pageSize));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateJumpToItemQuery(int itemIndex, int pageSize) {
|
||||
int page = itemIndex / pageSize;
|
||||
int offset = (page * pageSize);
|
||||
offset = offset==0 ? 1 : offset;
|
||||
return SqlPagingQueryUtils.generateRowNumSqlQuery(this, this.getSortKey() + " AS SORT_KEY", false,
|
||||
"ROWNUM = " + offset);
|
||||
}
|
||||
|
||||
private String buildRowNumClause(int pageSize) {
|
||||
return new StringBuilder().append("ROWNUM <= ").append(pageSize).toString();
|
||||
}
|
||||
|
||||
@@ -76,15 +76,32 @@ public class SqlPagingQueryUtils {
|
||||
*
|
||||
* @param provider {@link AbstractSqlPagingQueryProvider} providing the
|
||||
* implementation specifics
|
||||
* @param remainingPageQuery is this query for the ramining pages (true) as
|
||||
* @param remainingPageQuery is this query for the remaining pages (true) as
|
||||
* opposed to the first page (false)
|
||||
* @param rowNumClause the implementation specific row num clause to be used
|
||||
* @return the generated query
|
||||
*/
|
||||
public static String generateRowNumSqlQuery(AbstractSqlPagingQueryProvider provider, boolean remainingPageQuery,
|
||||
String rowNumClause) {
|
||||
|
||||
return generateRowNumSqlQuery(provider, provider.getSelectClause(), remainingPageQuery, rowNumClause);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate SQL query string using a ROW_NUM condition
|
||||
*
|
||||
* @param provider {@link AbstractSqlPagingQueryProvider} providing the
|
||||
* implementation specifics
|
||||
* @param remainingPageQuery is this query for the remaining pages (true) as
|
||||
* opposed to the first page (false)
|
||||
* @param rowNumClause the implementation specific row num clause to be used
|
||||
* @return the generated query
|
||||
*/
|
||||
public static String generateRowNumSqlQuery(AbstractSqlPagingQueryProvider provider, String selectClause, boolean remainingPageQuery,
|
||||
String rowNumClause) {
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.append("SELECT * FROM (SELECT ").append(provider.getSelectClause());
|
||||
sql.append("SELECT * FROM (SELECT ").append(selectClause);
|
||||
sql.append(" FROM ").append(provider.getFromClause());
|
||||
buildWhereClause(provider, remainingPageQuery, sql);
|
||||
sql.append(" ORDER BY ").append(provider.getSortKey());
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
package org.springframework.batch.item.database.support;
|
||||
|
||||
/**
|
||||
* Generic Paging Query Provider using standard SQL:2003 windowing functions. These features are supported by
|
||||
* DB2, Oracle, SQL Server 2005, Sybase and Apache Derby version 10.4.1.3
|
||||
*
|
||||
* Generic Paging Query Provider using standard SQL:2003 windowing functions.
|
||||
* These features are supported by DB2, Oracle, SQL Server 2005, Sybase and
|
||||
* Apache Derby version 10.4.1.3
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @since 2.0
|
||||
*/
|
||||
@@ -30,22 +31,25 @@ public class SqlWindowingPagingQueryProvider extends AbstractSqlPagingQueryProvi
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.append("SELECT * FROM ( ");
|
||||
sql.append("SELECT ").append(getSelectClause()).append(", ");
|
||||
sql.append("ROW_NUMBER() OVER (ORDER BY ").append(getSortKey());
|
||||
buildAscendingClause(sql);
|
||||
sql.append("ROW_NUMBER() OVER (").append(getOverClause());
|
||||
sql.append(") AS ROW_NUMBER");
|
||||
sql.append(" FROM ").append(getFromClause()).append(getWhereClause() == null ? "" : " WHERE " + getWhereClause());
|
||||
sql.append(") WHERE ROW_NUMBER <= ").append(pageSize);
|
||||
sql.append(" FROM ").append(getFromClause()).append(
|
||||
getWhereClause() == null ? "" : " WHERE " + getWhereClause());
|
||||
sql.append(") ").append(getSubQueryAlias()).append("WHERE ROW_NUMBER <= ").append(pageSize);
|
||||
|
||||
return sql.toString();
|
||||
}
|
||||
|
||||
protected Object getSubQueryAlias() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateRemainingPagesQuery(int pageSize) {
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.append("SELECT * FROM ( ");
|
||||
sql.append("SELECT ").append(getSelectClause()).append(", ");
|
||||
sql.append("ROW_NUMBER() OVER (ORDER BY ").append(getSortKey());
|
||||
buildAscendingClause(sql);
|
||||
sql.append("ROW_NUMBER() OVER (").append(getOverClause());
|
||||
sql.append(") AS ROW_NUMBER");
|
||||
sql.append(" FROM ").append(getFromClause());
|
||||
sql.append(" WHERE ");
|
||||
@@ -61,7 +65,7 @@ public class SqlWindowingPagingQueryProvider extends AbstractSqlPagingQueryProvi
|
||||
sql.append(" < ");
|
||||
}
|
||||
sql.append(getSortKeyPlaceHolder());
|
||||
sql.append(") WHERE ROW_NUMBER <= ").append(pageSize);
|
||||
sql.append(") ").append(getSubQueryAlias()).append("WHERE ROW_NUMBER <= ").append(pageSize);
|
||||
|
||||
return sql.toString();
|
||||
}
|
||||
@@ -70,28 +74,32 @@ public class SqlWindowingPagingQueryProvider extends AbstractSqlPagingQueryProvi
|
||||
public String generateJumpToItemQuery(int itemIndex, int pageSize) {
|
||||
int page = itemIndex / pageSize;
|
||||
int lastRowNum = (page * pageSize);
|
||||
if (lastRowNum<=0) {
|
||||
if (lastRowNum <= 0) {
|
||||
lastRowNum = 1;
|
||||
}
|
||||
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.append("SELECT SORT_KEY FROM ( ");
|
||||
sql.append("SELECT ").append(getSortKey()).append(" AS SORT_KEY, ");
|
||||
sql.append("ROW_NUMBER() OVER (ORDER BY ").append(getSortKey());
|
||||
buildAscendingClause(sql);
|
||||
sql.append("ROW_NUMBER() OVER (").append(getOverClause());
|
||||
sql.append(") AS ROW_NUMBER");
|
||||
sql.append(" FROM ").append(getFromClause()).append(getWhereClause() == null ? "" : " WHERE " + getWhereClause());
|
||||
sql.append(") WHERE ROW_NUMBER = ").append(lastRowNum);
|
||||
sql.append(" FROM ").append(getFromClause()).append(
|
||||
getWhereClause() == null ? "" : " WHERE " + getWhereClause());
|
||||
sql.append(") ").append(getSubQueryAlias()).append("WHERE ROW_NUMBER = ").append(lastRowNum);
|
||||
|
||||
return sql.toString();
|
||||
}
|
||||
|
||||
private void buildAscendingClause(StringBuilder sql) {
|
||||
protected String getOverClause() {
|
||||
return "ORDER BY " + getSortKey() + " " + getAscendingClause();
|
||||
}
|
||||
|
||||
private String getAscendingClause() {
|
||||
if (isAscending()) {
|
||||
sql.append(" ASC");
|
||||
return "ASC";
|
||||
}
|
||||
else {
|
||||
sql.append(" DESC");
|
||||
return "DESC";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,19 +15,21 @@
|
||||
*/
|
||||
package org.springframework.batch.item.database.support;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.Assert;
|
||||
import org.springframework.dao.InvalidDataAccessResourceUsageException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.Connection;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.springframework.dao.InvalidDataAccessResourceUsageException;
|
||||
|
||||
/**
|
||||
* @author Thomas Risberg
|
||||
@@ -69,7 +71,8 @@ public class DerbyPagingQueryProviderTests extends AbstractSqlPagingQueryProvide
|
||||
try {
|
||||
pagingQueryProvider.init(ds);
|
||||
fail();
|
||||
} catch (InvalidDataAccessResourceUsageException e) {
|
||||
}
|
||||
catch (InvalidDataAccessResourceUsageException e) {
|
||||
// expected
|
||||
}
|
||||
verify(ds);
|
||||
@@ -80,30 +83,55 @@ public class DerbyPagingQueryProviderTests extends AbstractSqlPagingQueryProvide
|
||||
@Test
|
||||
@Override
|
||||
public void testGenerateFirstPageQuery() {
|
||||
String sql = "SELECT * FROM ( SELECT id, name, age, ROW_NUMBER() OVER (ORDER BY id ASC) AS ROW_NUMBER FROM foo WHERE bar = 1) WHERE ROW_NUMBER <= 100";
|
||||
String sql = "SELECT * FROM ( SELECT id, name, age, ROW_NUMBER() OVER () AS ROW_NUMBER FROM foo WHERE bar = 1) AS TMP_SUB WHERE ROW_NUMBER <= 100";
|
||||
String s = pagingQueryProvider.generateFirstPageQuery(pageSize);
|
||||
Assert.assertEquals("", sql, s);
|
||||
}
|
||||
|
||||
@Test @Override
|
||||
@Test
|
||||
@Override
|
||||
public void testGenerateRemainingPagesQuery() {
|
||||
String sql = "SELECT * FROM ( SELECT id, name, age, ROW_NUMBER() OVER (ORDER BY id ASC) AS ROW_NUMBER FROM foo WHERE bar = 1 AND id > ?) WHERE ROW_NUMBER <= 100";
|
||||
String sql = "SELECT * FROM ( SELECT id, name, age, ROW_NUMBER() OVER () AS ROW_NUMBER FROM foo WHERE bar = 1 AND id > ?) AS TMP_SUB WHERE ROW_NUMBER <= 100";
|
||||
String s = pagingQueryProvider.generateRemainingPagesQuery(pageSize);
|
||||
Assert.assertEquals("", sql, s);
|
||||
}
|
||||
|
||||
@Test @Override
|
||||
@Test
|
||||
@Override
|
||||
public void testGenerateJumpToItemQuery() {
|
||||
String sql = "SELECT SORT_KEY FROM ( SELECT id AS SORT_KEY, ROW_NUMBER() OVER (ORDER BY id ASC) AS ROW_NUMBER FROM foo WHERE bar = 1) WHERE ROW_NUMBER = 100";
|
||||
String sql = "SELECT SORT_KEY FROM ( SELECT id AS SORT_KEY, ROW_NUMBER() OVER () AS ROW_NUMBER FROM foo WHERE bar = 1) AS TMP_SUB WHERE ROW_NUMBER = 100";
|
||||
String s = pagingQueryProvider.generateJumpToItemQuery(145, pageSize);
|
||||
Assert.assertEquals("", sql, s);
|
||||
}
|
||||
|
||||
@Test @Override
|
||||
@Test
|
||||
@Override
|
||||
public void testGenerateJumpToItemQueryForFirstPage() {
|
||||
String sql = "SELECT SORT_KEY FROM ( SELECT id AS SORT_KEY, ROW_NUMBER() OVER (ORDER BY id ASC) AS ROW_NUMBER FROM foo WHERE bar = 1) WHERE ROW_NUMBER = 1";
|
||||
String sql = "SELECT SORT_KEY FROM ( SELECT id AS SORT_KEY, ROW_NUMBER() OVER () AS ROW_NUMBER FROM foo WHERE bar = 1) AS TMP_SUB WHERE ROW_NUMBER = 1";
|
||||
String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
|
||||
Assert.assertEquals("", sql, s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Derby doesn't allow order by in the sub select (so it's pretty useless in
|
||||
* general for paging)
|
||||
*/
|
||||
@Test
|
||||
@Override
|
||||
public void testQueryContainsSortKey() {
|
||||
String s = pagingQueryProvider.generateFirstPageQuery(pageSize).toLowerCase();
|
||||
assertFalse("Wrong query: " + s, s.contains("id asc"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Derby doesn't allow order by in the sub select
|
||||
*/
|
||||
@Test
|
||||
@Override
|
||||
public void testQueryContainsSortKeyDesc() {
|
||||
pagingQueryProvider.setAscending(false);
|
||||
String s = pagingQueryProvider.generateFirstPageQuery(pageSize).toLowerCase();
|
||||
assertFalse("Wrong query: " + s, s.contains("id desc"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,14 +33,14 @@ public class OraclePagingQueryProviderTests extends AbstractSqlPagingQueryProvid
|
||||
|
||||
@Test @Override
|
||||
public void testGenerateJumpToItemQuery() {
|
||||
String sql = "SELECT SORT_KEY FROM ( SELECT id AS SORT_KEY, ROW_NUMBER() OVER (ORDER BY id ASC) AS ROW_NUMBER FROM foo WHERE bar = 1) WHERE ROW_NUMBER = 100";
|
||||
String sql = "SELECT * FROM (SELECT id AS SORT_KEY FROM foo WHERE bar = 1 ORDER BY id ASC) WHERE ROWNUM = 100";
|
||||
String s = pagingQueryProvider.generateJumpToItemQuery(145, pageSize);
|
||||
Assert.assertEquals("", sql, s);
|
||||
}
|
||||
|
||||
@Test @Override
|
||||
public void testGenerateJumpToItemQueryForFirstPage() {
|
||||
String sql = "SELECT SORT_KEY FROM ( SELECT id AS SORT_KEY, ROW_NUMBER() OVER (ORDER BY id ASC) AS ROW_NUMBER FROM foo WHERE bar = 1) WHERE ROW_NUMBER = 1";
|
||||
String sql = "SELECT * FROM (SELECT id AS SORT_KEY FROM foo WHERE bar = 1 ORDER BY id ASC) WHERE ROWNUM = 1";
|
||||
String s = pagingQueryProvider.generateJumpToItemQuery(45, pageSize);
|
||||
Assert.assertEquals("", sql, s);
|
||||
}
|
||||
|
||||
@@ -22,18 +22,26 @@ import javax.sql.DataSource;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class DatabaseTypeIntegrationTests {
|
||||
|
||||
|
||||
@Test
|
||||
public void testH2() throws Exception {
|
||||
DataSource dataSource = DatabaseTypeTestUtils.getDataSource(org.h2.Driver.class, "jdbc:h2:file:target/data/sample");
|
||||
DataSource dataSource = DatabaseTypeTestUtils.getDataSource(org.h2.Driver.class,
|
||||
"jdbc:h2:file:target/data/sample");
|
||||
assertEquals(DatabaseType.H2, DatabaseType.fromMetaData(dataSource));
|
||||
dataSource.getConnection();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDerby() throws Exception {
|
||||
DataSource dataSource = DatabaseTypeTestUtils.getDataSource(org.apache.derby.jdbc.EmbeddedDriver.class,
|
||||
"jdbc:derby:derby-home/test;create=true", "sa", "");
|
||||
assertEquals(DatabaseType.DERBY, DatabaseType.fromMetaData(dataSource));
|
||||
dataSource.getConnection();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -32,12 +32,18 @@ import org.apache.commons.dbcp.BasicDataSource;
|
||||
*/
|
||||
public class DatabaseTypeTestUtils {
|
||||
|
||||
public static DataSource getDataSource(Class<?> driver, String url) throws Exception {
|
||||
public static DataSource getDataSource(Class<?> driver, String url, String username, String password) throws Exception {
|
||||
BasicDataSource dataSource = new BasicDataSource();
|
||||
dataSource.setDriverClassName(driver.getName());
|
||||
dataSource.setUrl(url);
|
||||
dataSource.setUsername(username);
|
||||
dataSource.setPassword(password);
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
public static DataSource getDataSource(Class<?> driver, String url) throws Exception {
|
||||
return getDataSource(driver, url, null, null);
|
||||
}
|
||||
|
||||
public static DataSource getMockDataSource() throws Exception {
|
||||
return getMockDataSource(DatabaseType.HSQL.getProductName());
|
||||
|
||||
@@ -4,15 +4,13 @@ batch.jdbc.driver=org.apache.derby.jdbc.EmbeddedDriver
|
||||
batch.jdbc.url=jdbc:derby:derby-home/test;create=true
|
||||
batch.jdbc.user=sa
|
||||
batch.jdbc.password=
|
||||
batch.schema=
|
||||
batch.jndi.name=
|
||||
batch.naming.factory.initial=
|
||||
batch.naming.provider.url=
|
||||
batch.schema.script=/org/springframework/batch/core/schema-derby.sql
|
||||
batch.jdbc.testWhileIdle=false
|
||||
batch.jdbc.validationQuery=
|
||||
batch.drop.script=classpath:/org/springframework/batch/core/schema-drop-derby.sql
|
||||
batch.schema.script=classpath:/org/springframework/batch/core/schema-derby.sql
|
||||
batch.business.schema.script=business-schema-derby.sql
|
||||
batch.data.source.init=true
|
||||
batch.database.incrementer.class=org.springframework.jdbc.support.incrementer.DerbyMaxValueIncrementer
|
||||
batch.lob.handler.class=org.springframework.jdbc.support.lob.DefaultLobHandler
|
||||
|
||||
# Bean Properties for override
|
||||
# when not using sequences:
|
||||
incrementerParent.columnName=ID
|
||||
batch.database.incrementer.parent=columnIncrementerParent
|
||||
batch.grid.size=2
|
||||
batch.verify.cursor.position=false
|
||||
@@ -15,3 +15,4 @@ batch.data.source.init=true
|
||||
batch.database.incrementer.class=org.springframework.jdbc.support.incrementer.HsqlMaxValueIncrementer
|
||||
batch.database.incrementer.parent=columnIncrementerParent
|
||||
batch.grid.size=2
|
||||
batch.verify.cursor.position=true
|
||||
|
||||
@@ -13,3 +13,4 @@ batch.data.source.init=true
|
||||
batch.database.incrementer.class=org.springframework.jdbc.support.incrementer.MySQLMaxValueIncrementer
|
||||
batch.database.incrementer.parent=columnIncrementerParent
|
||||
batch.grid.size=50
|
||||
batch.verify.cursor.position=true
|
||||
|
||||
@@ -28,16 +28,17 @@
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
</bean>
|
||||
|
||||
<!-- Set up or detect a System property called "org.springframework.batch.support.SystemPropertyInitializer.ENVIRONMENT" used to construct a properties file on the classpath. The default is "hsql". -->
|
||||
<!-- Set up or detect a System property called "ENVIRONMENT" used to construct a properties file on the classpath. The default is "hsql". -->
|
||||
<bean id="environment"
|
||||
class="org.springframework.batch.support.SystemPropertyInitializer">
|
||||
<property name="defaultValue" value="hsql"/>
|
||||
<property name="keyName" value="ENVIRONMENT"/>
|
||||
</bean>
|
||||
|
||||
<!-- Use this to set additional properties on beans at run time -->
|
||||
<bean id="overrideProperties" class="org.springframework.beans.factory.config.PropertyOverrideConfigurer"
|
||||
depends-on="environment">
|
||||
<property name="location" value="classpath:batch-${org.springframework.batch.support.SystemPropertyInitializer.ENVIRONMENT}.properties" />
|
||||
<property name="location" value="classpath:batch-${ENVIRONMENT}.properties" />
|
||||
<!-- Allow system properties (-D) to override those from file -->
|
||||
<property name="localOverride" value="true" />
|
||||
<property name="properties">
|
||||
@@ -49,7 +50,7 @@
|
||||
|
||||
<bean id="placeholderProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
|
||||
depends-on="environment">
|
||||
<property name="location" value="classpath:batch-${org.springframework.batch.support.SystemPropertyInitializer.ENVIRONMENT}.properties" />
|
||||
<property name="location" value="classpath:batch-${ENVIRONMENT}.properties" />
|
||||
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
|
||||
<property name="ignoreUnresolvablePlaceholders" value="true" />
|
||||
<property name="order" value="1" />
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
<bean id="itemReaderForTest" class="org.springframework.batch.item.database.JdbcCursorItemReader" scope="prototype">
|
||||
<property name="dataSource" ref="dataSource"/>
|
||||
<property name="verifyCursorPosition" value="${batch.verify.cursor.position}"/>
|
||||
<property name="sql" value="select ID, NAME, CREDIT from CUSTOMER"/>
|
||||
<property name="rowMapper">
|
||||
<bean class="org.springframework.batch.sample.domain.trade.internal.CustomerCreditRowMapper"/>
|
||||
|
||||
Reference in New Issue
Block a user