Skip to content

Commit 79cf53a

Browse files
committed
make MyBatisCursorItemReader & MyBatisPagingItemReader support lazy/dynamic query parameter
1 parent 26d492c commit 79cf53a

File tree

6 files changed

+85
-1
lines changed

6 files changed

+85
-1
lines changed

src/main/java/org/mybatis/spring/batch/MyBatisCursorItemReader.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.HashMap;
2222
import java.util.Iterator;
2323
import java.util.Map;
24+
import java.util.function.Supplier;
2425

2526
import org.apache.ibatis.cursor.Cursor;
2627
import org.apache.ibatis.session.ExecutorType;
@@ -41,6 +42,7 @@ public class MyBatisCursorItemReader<T> extends AbstractItemCountingItemStreamIt
4142
private SqlSession sqlSession;
4243

4344
private Map<String, Object> parameterValues;
45+
private Supplier<Map<String, Object>> parameterSupplier;
4446

4547
private Cursor<T> cursor;
4648
private Iterator<T> cursorIterator;
@@ -65,6 +67,11 @@ protected void doOpen() throws Exception {
6567
parameters.putAll(parameterValues);
6668
}
6769

70+
Map<String, Object> dynamicParameters;
71+
if (parameterSupplier != null && (dynamicParameters = parameterSupplier.get()) != null) {
72+
parameters.putAll(dynamicParameters);
73+
}
74+
6875
sqlSession = sqlSessionFactory.openSession(ExecutorType.SIMPLE);
6976
cursor = sqlSession.selectCursor(queryId, parameters);
7077
cursorIterator = cursor.iterator();
@@ -121,4 +128,14 @@ public void setQueryId(String queryId) {
121128
public void setParameterValues(Map<String, Object> parameterValues) {
122129
this.parameterValues = parameterValues;
123130
}
131+
132+
/**
133+
* The parameter supplier used to get parameter values for the query execution.
134+
*
135+
* @param parameterSupplier
136+
* the supplier used to get values keyed by the parameter named used in the query string.
137+
*/
138+
public void setParameterSupplier(Supplier<Map<String, Object>> parameterSupplier) {
139+
this.parameterSupplier = parameterSupplier;
140+
}
124141
}

src/main/java/org/mybatis/spring/batch/MyBatisPagingItemReader.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.HashMap;
2222
import java.util.Map;
2323
import java.util.concurrent.CopyOnWriteArrayList;
24+
import java.util.function.Supplier;
2425

2526
import org.apache.ibatis.session.ExecutorType;
2627
import org.apache.ibatis.session.SqlSession;
@@ -47,6 +48,8 @@ public class MyBatisPagingItemReader<T> extends AbstractPagingItemReader<T> {
4748

4849
private Map<String, Object> parameterValues;
4950

51+
private Supplier<Map<String, Object>> parameterSupplier;
52+
5053
public MyBatisPagingItemReader() {
5154
setName(getShortName(MyBatisPagingItemReader.class));
5255
}
@@ -81,6 +84,16 @@ public void setParameterValues(Map<String, Object> parameterValues) {
8184
this.parameterValues = parameterValues;
8285
}
8386

87+
/**
88+
* The parameter supplier used to get parameter values for the query execution.
89+
*
90+
* @param parameterSupplier
91+
* the supplier used to get values keyed by the parameter named used in the query string.
92+
*/
93+
public void setParameterSupplier(Supplier<Map<String, Object>> parameterSupplier) {
94+
this.parameterSupplier = parameterSupplier;
95+
}
96+
8497
/**
8598
* Check mandatory properties.
8699
*
@@ -102,6 +115,10 @@ protected void doReadPage() {
102115
if (parameterValues != null) {
103116
parameters.putAll(parameterValues);
104117
}
118+
Map<String, Object> dynamicParameters;
119+
if (parameterSupplier != null && (dynamicParameters = parameterSupplier.get()) != null) {
120+
parameters.putAll(dynamicParameters);
121+
}
105122
parameters.put("_page", getPage());
106123
parameters.put("_pagesize", getPageSize());
107124
parameters.put("_skiprows", getPage() * getPageSize());

src/main/java/org/mybatis/spring/batch/builder/MyBatisCursorItemReaderBuilder.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.util.Map;
1919
import java.util.Optional;
20+
import java.util.function.Supplier;
2021

2122
import org.apache.ibatis.session.SqlSessionFactory;
2223
import org.mybatis.spring.batch.MyBatisCursorItemReader;
@@ -35,6 +36,7 @@ public class MyBatisCursorItemReaderBuilder<T> {
3536
private SqlSessionFactory sqlSessionFactory;
3637
private String queryId;
3738
private Map<String, Object> parameterValues;
39+
private Supplier<Map<String, Object>> parameterSupplier;
3840
private Boolean saveState;
3941
private Integer maxItemCount;
4042

@@ -83,6 +85,21 @@ public MyBatisCursorItemReaderBuilder<T> parameterValues(Map<String, Object> par
8385
return this;
8486
}
8587

88+
/**
89+
* Set the parameter supplier to be used to get parameters for the query execution.
90+
*
91+
* @param parameterSupplier
92+
* the parameter supplier to be used to get parameters for the query execution
93+
*
94+
* @return this instance for method chaining
95+
*
96+
* @see MyBatisCursorItemReader#setParameterSupplier(Supplier)
97+
*/
98+
public MyBatisCursorItemReaderBuilder<T> parameterSupplier(Supplier<Map<String, Object>> parameterSupplier) {
99+
this.parameterSupplier = parameterSupplier;
100+
return this;
101+
}
102+
86103
/**
87104
* Configure if the state of the {@link org.springframework.batch.item.ItemStreamSupport} should be persisted within
88105
* the {@link org.springframework.batch.item.ExecutionContext} for restart purposes.
@@ -124,6 +141,7 @@ public MyBatisCursorItemReader<T> build() {
124141
reader.setSqlSessionFactory(this.sqlSessionFactory);
125142
reader.setQueryId(this.queryId);
126143
reader.setParameterValues(this.parameterValues);
144+
reader.setParameterSupplier(this.parameterSupplier);
127145
Optional.ofNullable(this.saveState).ifPresent(reader::setSaveState);
128146
Optional.ofNullable(this.maxItemCount).ifPresent(reader::setMaxItemCount);
129147
return reader;

src/main/java/org/mybatis/spring/batch/builder/MyBatisPagingItemReaderBuilder.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.util.Map;
1919
import java.util.Optional;
20+
import java.util.function.Supplier;
2021

2122
import org.apache.ibatis.session.SqlSessionFactory;
2223
import org.mybatis.spring.batch.MyBatisPagingItemReader;
@@ -35,6 +36,7 @@ public class MyBatisPagingItemReaderBuilder<T> {
3536
private SqlSessionFactory sqlSessionFactory;
3637
private String queryId;
3738
private Map<String, Object> parameterValues;
39+
private Supplier<Map<String, Object>> parameterSupplier;
3840
private Integer pageSize;
3941
private Boolean saveState;
4042
private Integer maxItemCount;
@@ -84,6 +86,21 @@ public MyBatisPagingItemReaderBuilder<T> parameterValues(Map<String, Object> par
8486
return this;
8587
}
8688

89+
/**
90+
* Set the parameter supplier to be used to get parameters for the query execution.
91+
*
92+
* @param parameterSupplier
93+
* the parameter supplier to be used to get parameters for the query execution
94+
*
95+
* @return this instance for method chaining
96+
*
97+
* @see MyBatisPagingItemReader#setParameterSupplier(Supplier)
98+
*/
99+
public MyBatisPagingItemReaderBuilder<T> parameterSupplier(Supplier<Map<String, Object>> parameterSupplier) {
100+
this.parameterSupplier = parameterSupplier;
101+
return this;
102+
}
103+
87104
/**
88105
* The number of records to request per page/query. Defaults to 10. Must be greater than zero.
89106
*
@@ -140,6 +157,7 @@ public MyBatisPagingItemReader<T> build() {
140157
reader.setSqlSessionFactory(this.sqlSessionFactory);
141158
reader.setQueryId(this.queryId);
142159
reader.setParameterValues(this.parameterValues);
160+
reader.setParameterSupplier(this.parameterSupplier);
143161
Optional.ofNullable(this.pageSize).ifPresent(reader::setPageSize);
144162
Optional.ofNullable(this.saveState).ifPresent(reader::setSaveState);
145163
Optional.ofNullable(this.maxItemCount).ifPresent(reader::setMaxItemCount);

src/test/java/org/mybatis/spring/batch/builder/MyBatisCursorItemReaderBuilderTest.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717

1818
import java.util.Arrays;
1919
import java.util.Collections;
20+
import java.util.HashMap;
2021
import java.util.List;
22+
import java.util.Map;
2123

2224
import org.apache.ibatis.cursor.Cursor;
2325
import org.apache.ibatis.session.ExecutorType;
@@ -56,7 +58,10 @@ void setUp() {
5658

5759
Mockito.when(this.sqlSessionFactory.openSession(ExecutorType.SIMPLE)).thenReturn(this.sqlSession);
5860
Mockito.when(this.cursor.iterator()).thenReturn(getFoos().iterator());
59-
Mockito.when(this.sqlSession.selectCursor("selectFoo", Collections.singletonMap("id", 1))).thenReturn(this.cursor);
61+
Map<String, Object> parameters = new HashMap<>();
62+
parameters.put("id", 1);
63+
parameters.put("name", "Doe");
64+
Mockito.when(this.sqlSession.selectCursor("selectFoo", parameters)).thenReturn(this.cursor);
6065
}
6166

6267
@Test
@@ -67,6 +72,7 @@ void testConfiguration() throws Exception {
6772
.sqlSessionFactory(this.sqlSessionFactory)
6873
.queryId("selectFoo")
6974
.parameterValues(Collections.singletonMap("id", 1))
75+
.parameterSupplier(() -> Collections.singletonMap("name", "Doe"))
7076
.build();
7177
// @formatter:on
7278
itemReader.afterPropertiesSet();
@@ -93,6 +99,7 @@ void testConfigurationSaveStateIsFalse() throws Exception {
9399
.sqlSessionFactory(this.sqlSessionFactory)
94100
.queryId("selectFoo")
95101
.parameterValues(Collections.singletonMap("id", 1))
102+
.parameterSupplier(() -> Collections.singletonMap("name", "Doe"))
96103
.saveState(false)
97104
.build();
98105
// @formatter:on
@@ -118,6 +125,7 @@ void testConfigurationMaxItemCount() throws Exception {
118125
.sqlSessionFactory(this.sqlSessionFactory)
119126
.queryId("selectFoo")
120127
.parameterValues(Collections.singletonMap("id", 1))
128+
.parameterSupplier(() -> Collections.singletonMap("name", "Doe"))
121129
.maxItemCount(2)
122130
.build();
123131
// @formatter:on

src/test/java/org/mybatis/spring/batch/builder/MyBatisPagingItemReaderBuilderTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ void setUp() {
6767
Mockito.when(this.sqlSessionFactory.openSession(ExecutorType.BATCH)).thenReturn(this.sqlSession);
6868
Map<String, Object> parameters = new HashMap<>();
6969
parameters.put("id", 1);
70+
parameters.put("name", "Doe");
7071
parameters.put("_page", 0);
7172
parameters.put("_pagesize", 10);
7273
parameters.put("_skiprows", 0);
@@ -80,6 +81,7 @@ void testConfiguration() throws Exception {
8081
.sqlSessionFactory(this.sqlSessionFactory)
8182
.queryId("selectFoo")
8283
.parameterValues(Collections.singletonMap("id", 1))
84+
.parameterSupplier(() -> Collections.singletonMap("name", "Doe"))
8385
.build();
8486
// @formatter:on
8587
itemReader.afterPropertiesSet();
@@ -105,6 +107,7 @@ void testConfigurationSaveStateIsFalse() throws Exception {
105107
.sqlSessionFactory(this.sqlSessionFactory)
106108
.queryId("selectFoo")
107109
.parameterValues(Collections.singletonMap("id", 1))
110+
.parameterSupplier(() -> Collections.singletonMap("name", "Doe"))
108111
.saveState(false)
109112
.build();
110113
// @formatter:on
@@ -128,6 +131,7 @@ void testConfigurationMaxItemCount() throws Exception {
128131
.sqlSessionFactory(this.sqlSessionFactory)
129132
.queryId("selectFoo")
130133
.parameterValues(Collections.singletonMap("id", 1))
134+
.parameterSupplier(() -> Collections.singletonMap("name", "Doe"))
131135
.maxItemCount(2)
132136
.build();
133137
// @formatter:on
@@ -152,6 +156,7 @@ void testConfigurationPageSize() throws Exception {
152156
.sqlSessionFactory(this.sqlSessionFactory)
153157
.queryId("selectFoo")
154158
.parameterValues(Collections.singletonMap("id", 1))
159+
.parameterSupplier(() -> Collections.singletonMap("name", "Doe"))
155160
.pageSize(2)
156161
.build();
157162
// @formatter:on
@@ -160,6 +165,7 @@ void testConfigurationPageSize() throws Exception {
160165
Map<String, Object> parameters = new HashMap<>();
161166
parameters.put("id", 1);
162167
parameters.put("_page", 0);
168+
parameters.put("name", "Doe");
163169
parameters.put("_pagesize", 2);
164170
parameters.put("_skiprows", 0);
165171
Mockito.when(this.sqlSession.selectList("selectFoo", parameters)).thenReturn(getFoos());

0 commit comments

Comments
 (0)