diff --git a/src/main/java/org/mybatis/spring/batch/MyBatisCursorItemReader.java b/src/main/java/org/mybatis/spring/batch/MyBatisCursorItemReader.java index 495dcfed54..8bc0b3330c 100644 --- a/src/main/java/org/mybatis/spring/batch/MyBatisCursorItemReader.java +++ b/src/main/java/org/mybatis/spring/batch/MyBatisCursorItemReader.java @@ -21,6 +21,8 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import java.util.Optional; +import java.util.function.Supplier; import org.apache.ibatis.cursor.Cursor; import org.apache.ibatis.session.ExecutorType; @@ -41,6 +43,7 @@ public class MyBatisCursorItemReader extends AbstractItemCountingItemStreamIt private SqlSession sqlSession; private Map parameterValues; + private Supplier> parameterValuesSupplier; private Cursor cursor; private Iterator cursorIterator; @@ -65,6 +68,8 @@ protected void doOpen() throws Exception { parameters.putAll(parameterValues); } + Optional.ofNullable(parameterValuesSupplier).map(Supplier::get).ifPresent(parameters::putAll); + sqlSession = sqlSessionFactory.openSession(ExecutorType.SIMPLE); cursor = sqlSession.selectCursor(queryId, parameters); cursorIterator = cursor.iterator(); @@ -121,4 +126,16 @@ public void setQueryId(String queryId) { public void setParameterValues(Map parameterValues) { this.parameterValues = parameterValues; } + + /** + * The parameter supplier used to get parameter values for the query execution. + * + * @param parameterValuesSupplier + * the supplier used to get values keyed by the parameter named used in the query string. + * + * @since 2.1.0 + */ + public void setParameterValuesSupplier(Supplier> parameterValuesSupplier) { + this.parameterValuesSupplier = parameterValuesSupplier; + } } diff --git a/src/main/java/org/mybatis/spring/batch/MyBatisPagingItemReader.java b/src/main/java/org/mybatis/spring/batch/MyBatisPagingItemReader.java index 924d2fadc3..6c96b345dc 100644 --- a/src/main/java/org/mybatis/spring/batch/MyBatisPagingItemReader.java +++ b/src/main/java/org/mybatis/spring/batch/MyBatisPagingItemReader.java @@ -20,7 +20,9 @@ import java.util.HashMap; import java.util.Map; +import java.util.Optional; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.function.Supplier; import org.apache.ibatis.session.ExecutorType; import org.apache.ibatis.session.SqlSession; @@ -47,6 +49,8 @@ public class MyBatisPagingItemReader extends AbstractPagingItemReader { private Map parameterValues; + private Supplier> parameterValuesSupplier; + public MyBatisPagingItemReader() { setName(getShortName(MyBatisPagingItemReader.class)); } @@ -81,6 +85,18 @@ public void setParameterValues(Map parameterValues) { this.parameterValues = parameterValues; } + /** + * The parameter supplier used to get parameter values for the query execution. + * + * @param parameterValuesSupplier + * the supplier used to get values keyed by the parameter named used in the query string. + * + * @since 2.1.0 + */ + public void setParameterValuesSupplier(Supplier> parameterValuesSupplier) { + this.parameterValuesSupplier = parameterValuesSupplier; + } + /** * Check mandatory properties. * @@ -102,6 +118,7 @@ protected void doReadPage() { if (parameterValues != null) { parameters.putAll(parameterValues); } + Optional.ofNullable(parameterValuesSupplier).map(Supplier::get).ifPresent(parameters::putAll); parameters.put("_page", getPage()); parameters.put("_pagesize", getPageSize()); parameters.put("_skiprows", getPage() * getPageSize()); diff --git a/src/main/java/org/mybatis/spring/batch/builder/MyBatisCursorItemReaderBuilder.java b/src/main/java/org/mybatis/spring/batch/builder/MyBatisCursorItemReaderBuilder.java index de7785ba19..da81b4e227 100644 --- a/src/main/java/org/mybatis/spring/batch/builder/MyBatisCursorItemReaderBuilder.java +++ b/src/main/java/org/mybatis/spring/batch/builder/MyBatisCursorItemReaderBuilder.java @@ -17,6 +17,7 @@ import java.util.Map; import java.util.Optional; +import java.util.function.Supplier; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.batch.MyBatisCursorItemReader; @@ -35,6 +36,7 @@ public class MyBatisCursorItemReaderBuilder { private SqlSessionFactory sqlSessionFactory; private String queryId; private Map parameterValues; + private Supplier> parameterValuesSupplier; private Boolean saveState; private Integer maxItemCount; @@ -83,6 +85,24 @@ public MyBatisCursorItemReaderBuilder parameterValues(Map par return this; } + /** + * Set the parameter supplier to be used to get parameters for the query execution. + * + * @param parameterValuesSupplier + * the parameter supplier to be used to get parameters for the query execution + * + * @return this instance for method chaining + * + * @see MyBatisCursorItemReader#setParameterValuesSupplier(Supplier) + * + * @since 2.1.0 + */ + public MyBatisCursorItemReaderBuilder parameterValuesSupplier( + Supplier> parameterValuesSupplier) { + this.parameterValuesSupplier = parameterValuesSupplier; + return this; + } + /** * Configure if the state of the {@link org.springframework.batch.item.ItemStreamSupport} should be persisted within * the {@link org.springframework.batch.item.ExecutionContext} for restart purposes. @@ -124,6 +144,7 @@ public MyBatisCursorItemReader build() { reader.setSqlSessionFactory(this.sqlSessionFactory); reader.setQueryId(this.queryId); reader.setParameterValues(this.parameterValues); + reader.setParameterValuesSupplier(this.parameterValuesSupplier); Optional.ofNullable(this.saveState).ifPresent(reader::setSaveState); Optional.ofNullable(this.maxItemCount).ifPresent(reader::setMaxItemCount); return reader; diff --git a/src/main/java/org/mybatis/spring/batch/builder/MyBatisPagingItemReaderBuilder.java b/src/main/java/org/mybatis/spring/batch/builder/MyBatisPagingItemReaderBuilder.java index 1625bd1676..4428318c79 100644 --- a/src/main/java/org/mybatis/spring/batch/builder/MyBatisPagingItemReaderBuilder.java +++ b/src/main/java/org/mybatis/spring/batch/builder/MyBatisPagingItemReaderBuilder.java @@ -17,6 +17,7 @@ import java.util.Map; import java.util.Optional; +import java.util.function.Supplier; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.batch.MyBatisPagingItemReader; @@ -35,6 +36,7 @@ public class MyBatisPagingItemReaderBuilder { private SqlSessionFactory sqlSessionFactory; private String queryId; private Map parameterValues; + private Supplier> parameterValuesSupplier; private Integer pageSize; private Boolean saveState; private Integer maxItemCount; @@ -84,6 +86,24 @@ public MyBatisPagingItemReaderBuilder parameterValues(Map par return this; } + /** + * Set the parameter supplier to be used to get parameters for the query execution. + * + * @param parameterValuesSupplier + * the parameter supplier to be used to get parameters for the query execution + * + * @return this instance for method chaining + * + * @see MyBatisPagingItemReader#setParameterValuesSupplier(Supplier) + * + * @since 2.1.0 + */ + public MyBatisPagingItemReaderBuilder parameterValuesSupplier( + Supplier> parameterValuesSupplier) { + this.parameterValuesSupplier = parameterValuesSupplier; + return this; + } + /** * The number of records to request per page/query. Defaults to 10. Must be greater than zero. * @@ -140,6 +160,7 @@ public MyBatisPagingItemReader build() { reader.setSqlSessionFactory(this.sqlSessionFactory); reader.setQueryId(this.queryId); reader.setParameterValues(this.parameterValues); + reader.setParameterValuesSupplier(this.parameterValuesSupplier); Optional.ofNullable(this.pageSize).ifPresent(reader::setPageSize); Optional.ofNullable(this.saveState).ifPresent(reader::setSaveState); Optional.ofNullable(this.maxItemCount).ifPresent(reader::setMaxItemCount); diff --git a/src/test/java/org/mybatis/spring/batch/builder/MyBatisCursorItemReaderBuilderTest.java b/src/test/java/org/mybatis/spring/batch/builder/MyBatisCursorItemReaderBuilderTest.java index e434af0346..35363172b6 100644 --- a/src/test/java/org/mybatis/spring/batch/builder/MyBatisCursorItemReaderBuilderTest.java +++ b/src/test/java/org/mybatis/spring/batch/builder/MyBatisCursorItemReaderBuilderTest.java @@ -17,7 +17,9 @@ import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.apache.ibatis.cursor.Cursor; import org.apache.ibatis.session.ExecutorType; @@ -56,7 +58,10 @@ void setUp() { Mockito.when(this.sqlSessionFactory.openSession(ExecutorType.SIMPLE)).thenReturn(this.sqlSession); Mockito.when(this.cursor.iterator()).thenReturn(getFoos().iterator()); - Mockito.when(this.sqlSession.selectCursor("selectFoo", Collections.singletonMap("id", 1))).thenReturn(this.cursor); + Map parameters = new HashMap<>(); + parameters.put("id", 1); + parameters.put("name", "Doe"); + Mockito.when(this.sqlSession.selectCursor("selectFoo", parameters)).thenReturn(this.cursor); } @Test @@ -67,6 +72,7 @@ void testConfiguration() throws Exception { .sqlSessionFactory(this.sqlSessionFactory) .queryId("selectFoo") .parameterValues(Collections.singletonMap("id", 1)) + .parameterValuesSupplier(() -> Collections.singletonMap("name", "Doe")) .build(); // @formatter:on itemReader.afterPropertiesSet(); @@ -93,6 +99,7 @@ void testConfigurationSaveStateIsFalse() throws Exception { .sqlSessionFactory(this.sqlSessionFactory) .queryId("selectFoo") .parameterValues(Collections.singletonMap("id", 1)) + .parameterValuesSupplier(() -> Collections.singletonMap("name", "Doe")) .saveState(false) .build(); // @formatter:on @@ -118,6 +125,7 @@ void testConfigurationMaxItemCount() throws Exception { .sqlSessionFactory(this.sqlSessionFactory) .queryId("selectFoo") .parameterValues(Collections.singletonMap("id", 1)) + .parameterValuesSupplier(() -> Collections.singletonMap("name", "Doe")) .maxItemCount(2) .build(); // @formatter:on diff --git a/src/test/java/org/mybatis/spring/batch/builder/MyBatisPagingItemReaderBuilderTest.java b/src/test/java/org/mybatis/spring/batch/builder/MyBatisPagingItemReaderBuilderTest.java index 4ff74bae8b..b936ede448 100644 --- a/src/test/java/org/mybatis/spring/batch/builder/MyBatisPagingItemReaderBuilderTest.java +++ b/src/test/java/org/mybatis/spring/batch/builder/MyBatisPagingItemReaderBuilderTest.java @@ -67,6 +67,7 @@ void setUp() { Mockito.when(this.sqlSessionFactory.openSession(ExecutorType.BATCH)).thenReturn(this.sqlSession); Map parameters = new HashMap<>(); parameters.put("id", 1); + parameters.put("name", "Doe"); parameters.put("_page", 0); parameters.put("_pagesize", 10); parameters.put("_skiprows", 0); @@ -80,6 +81,7 @@ void testConfiguration() throws Exception { .sqlSessionFactory(this.sqlSessionFactory) .queryId("selectFoo") .parameterValues(Collections.singletonMap("id", 1)) + .parameterValuesSupplier(() -> Collections.singletonMap("name", "Doe")) .build(); // @formatter:on itemReader.afterPropertiesSet(); @@ -105,6 +107,7 @@ void testConfigurationSaveStateIsFalse() throws Exception { .sqlSessionFactory(this.sqlSessionFactory) .queryId("selectFoo") .parameterValues(Collections.singletonMap("id", 1)) + .parameterValuesSupplier(() -> Collections.singletonMap("name", "Doe")) .saveState(false) .build(); // @formatter:on @@ -128,6 +131,7 @@ void testConfigurationMaxItemCount() throws Exception { .sqlSessionFactory(this.sqlSessionFactory) .queryId("selectFoo") .parameterValues(Collections.singletonMap("id", 1)) + .parameterValuesSupplier(() -> Collections.singletonMap("name", "Doe")) .maxItemCount(2) .build(); // @formatter:on @@ -152,6 +156,7 @@ void testConfigurationPageSize() throws Exception { .sqlSessionFactory(this.sqlSessionFactory) .queryId("selectFoo") .parameterValues(Collections.singletonMap("id", 1)) + .parameterValuesSupplier(() -> Collections.singletonMap("name", "Doe")) .pageSize(2) .build(); // @formatter:on @@ -160,6 +165,7 @@ void testConfigurationPageSize() throws Exception { Map parameters = new HashMap<>(); parameters.put("id", 1); parameters.put("_page", 0); + parameters.put("name", "Doe"); parameters.put("_pagesize", 2); parameters.put("_skiprows", 0); Mockito.when(this.sqlSession.selectList("selectFoo", parameters)).thenReturn(getFoos());