Skip to content

Commit 528dfe6

Browse files
committed
Refactor Spring Batch support for more flexibility
The prior support was limited to limit and offset queries.
1 parent 6a63771 commit 528dfe6

11 files changed

+94
-158
lines changed

src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,18 @@ private <T> String renderedPlaceHolder(String mapKey, BindableColumn<T> column)
6666
.getFormattedJdbcPlaceholder(column, calculatedParameterName, mapKey);
6767
}
6868

69+
public RenderedParameterInfo calculateLimitParameterInfo() {
70+
String mapKey = renderingStrategy.formatParameterMapKeyForLimit(sequence);
71+
return new RenderedParameterInfo(mapKey,
72+
renderingStrategy.getFormattedJdbcPlaceholderForLimitOrOffset(calculatedParameterName, mapKey));
73+
}
74+
75+
public RenderedParameterInfo calculateOffsetParameterInfo() {
76+
String mapKey = renderingStrategy.formatParameterMapKeyForOffset(sequence);
77+
return new RenderedParameterInfo(mapKey,
78+
renderingStrategy.getFormattedJdbcPlaceholderForLimitOrOffset(calculatedParameterName, mapKey));
79+
}
80+
6981
public RenderedParameterInfo calculateParameterInfo() {
7082
String mapKey = nextMapKey();
7183
return new RenderedParameterInfo(mapKey, renderedPlaceHolder(mapKey));

src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ public String formatParameterMapKey(AtomicInteger sequence) {
4040
return "p" + sequence.getAndIncrement(); //$NON-NLS-1$
4141
}
4242

43+
public String formatParameterMapKeyForLimit(AtomicInteger sequence) {
44+
return formatParameterMapKey(sequence);
45+
}
46+
47+
public String formatParameterMapKeyForOffset(AtomicInteger sequence) {
48+
return formatParameterMapKey(sequence);
49+
}
50+
4351
/**
4452
* This method generates a binding for a parameter to a placeholder in a generated SQL statement.
4553
*
@@ -78,6 +86,10 @@ public String formatParameterMapKey(AtomicInteger sequence) {
7886
*/
7987
public abstract String getFormattedJdbcPlaceholder(String prefix, String parameterName);
8088

89+
public String getFormattedJdbcPlaceholderForLimitOrOffset(String prefix, String parameterName) {
90+
return getFormattedJdbcPlaceholder(prefix, parameterName);
91+
}
92+
8193
/**
8294
* This method generates a binding for a parameter to a placeholder in a row based insert statement.
8395
*

src/main/java/org/mybatis/dynamic/sql/select/render/FetchFirstPagingModelRenderer.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,30 +51,30 @@ private FragmentAndParameters renderFetchFirstRowsOnly() {
5151
}
5252

5353
private FragmentAndParameters renderFetchFirstRowsOnly(Long fetchFirstRows) {
54-
RenderedParameterInfo parameterInfo = renderingContext.calculateParameterInfo();
54+
RenderedParameterInfo limitParameterInfo = renderingContext.calculateLimitParameterInfo();
5555
return FragmentAndParameters
56-
.withFragment("fetch first " + parameterInfo.renderedPlaceHolder() //$NON-NLS-1$
56+
.withFragment("fetch first " + limitParameterInfo.renderedPlaceHolder() //$NON-NLS-1$
5757
+ " rows only") //$NON-NLS-1$
58-
.withParameter(parameterInfo.parameterMapKey(), fetchFirstRows)
58+
.withParameter(limitParameterInfo.parameterMapKey(), fetchFirstRows)
5959
.build();
6060
}
6161

6262
private FragmentAndParameters renderOffsetOnly(Long offset) {
63-
RenderedParameterInfo parameterInfo = renderingContext.calculateParameterInfo();
64-
return FragmentAndParameters.withFragment("offset " + parameterInfo.renderedPlaceHolder() //$NON-NLS-1$
63+
RenderedParameterInfo offsetParameterInfo = renderingContext.calculateOffsetParameterInfo();
64+
return FragmentAndParameters.withFragment("offset " + offsetParameterInfo.renderedPlaceHolder() //$NON-NLS-1$
6565
+ " rows") //$NON-NLS-1$
66-
.withParameter(parameterInfo.parameterMapKey(), offset)
66+
.withParameter(offsetParameterInfo.parameterMapKey(), offset)
6767
.build();
6868
}
6969

7070
private FragmentAndParameters renderOffsetAndFetchFirstRows(Long offset, Long fetchFirstRows) {
71-
RenderedParameterInfo parameterInfo1 = renderingContext.calculateParameterInfo();
72-
RenderedParameterInfo parameterInfo2 = renderingContext.calculateParameterInfo();
73-
return FragmentAndParameters.withFragment("offset " + parameterInfo1.renderedPlaceHolder() //$NON-NLS-1$
74-
+ " rows fetch first " + parameterInfo2.renderedPlaceHolder() //$NON-NLS-1$
71+
RenderedParameterInfo offsetParameterInfo = renderingContext.calculateOffsetParameterInfo();
72+
RenderedParameterInfo limitParameterInfo = renderingContext.calculateParameterInfo();
73+
return FragmentAndParameters.withFragment("offset " + offsetParameterInfo.renderedPlaceHolder() //$NON-NLS-1$
74+
+ " rows fetch first " + limitParameterInfo.renderedPlaceHolder() //$NON-NLS-1$
7575
+ " rows only") //$NON-NLS-1$
76-
.withParameter(parameterInfo1.parameterMapKey(), offset)
77-
.withParameter(parameterInfo2.parameterMapKey(), fetchFirstRows)
76+
.withParameter(offsetParameterInfo.parameterMapKey(), offset)
77+
.withParameter(limitParameterInfo.parameterMapKey(), fetchFirstRows)
7878
.build();
7979
}
8080
}

src/main/java/org/mybatis/dynamic/sql/select/render/LimitAndOffsetPagingModelRenderer.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,19 @@ public FragmentAndParameters render() {
4040
}
4141

4242
private FragmentAndParameters renderLimitOnly() {
43-
RenderedParameterInfo parameterInfo = renderingContext.calculateParameterInfo();
44-
return FragmentAndParameters.withFragment("limit " + parameterInfo.renderedPlaceHolder()) //$NON-NLS-1$
45-
.withParameter(parameterInfo.parameterMapKey(), limit)
43+
RenderedParameterInfo limitParameterInfo = renderingContext.calculateLimitParameterInfo();
44+
return FragmentAndParameters.withFragment("limit " + limitParameterInfo.renderedPlaceHolder()) //$NON-NLS-1$
45+
.withParameter(limitParameterInfo.parameterMapKey(), limit)
4646
.build();
4747
}
4848

4949
private FragmentAndParameters renderLimitAndOffset(Long offset) {
50-
RenderedParameterInfo parameterInfo1 = renderingContext.calculateParameterInfo();
51-
RenderedParameterInfo parameterInfo2 = renderingContext.calculateParameterInfo();
52-
return FragmentAndParameters.withFragment("limit " + parameterInfo1.renderedPlaceHolder() //$NON-NLS-1$
53-
+ " offset " + parameterInfo2.renderedPlaceHolder()) //$NON-NLS-1$
54-
.withParameter(parameterInfo1.parameterMapKey(), limit)
55-
.withParameter(parameterInfo2.parameterMapKey(), offset)
50+
RenderedParameterInfo limitParameterInfo = renderingContext.calculateLimitParameterInfo();
51+
RenderedParameterInfo offsetParameterInfo = renderingContext.calculateOffsetParameterInfo();
52+
return FragmentAndParameters.withFragment("limit " + limitParameterInfo.renderedPlaceHolder() //$NON-NLS-1$
53+
+ " offset " + offsetParameterInfo.renderedPlaceHolder()) //$NON-NLS-1$
54+
.withParameter(limitParameterInfo.parameterMapKey(), limit)
55+
.withParameter(offsetParameterInfo.parameterMapKey(), offset)
5656
.build();
5757
}
5858
}

src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchCursorReaderSelectModel.java

Lines changed: 0 additions & 32 deletions
This file was deleted.

src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchReaderRenderingStrategy.java renamed to src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingItemReaderRenderingStrategy.java

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,31 @@
1515
*/
1616
package org.mybatis.dynamic.sql.util.springbatch;
1717

18-
import org.mybatis.dynamic.sql.BindableColumn;
18+
import java.util.concurrent.atomic.AtomicInteger;
19+
1920
import org.mybatis.dynamic.sql.render.MyBatis3RenderingStrategy;
2021

2122
/**
22-
* This rendering strategy should be used for MyBatis3 statements using one of the
23-
* Spring batch readers supplied by mybatis-spring integration (http://www.mybatis.org/spring/).
24-
* Those readers are MyBatisPagingItemReader and MyBatisCursorItemReader.
23+
* This rendering strategy should be used for MyBatis3 statements using the
24+
* MyBatisPagingItemReader supplied by mybatis-spring integration (http://www.mybatis.org/spring/).
2525
*
2626
*/
27-
public class SpringBatchReaderRenderingStrategy extends MyBatis3RenderingStrategy {
27+
public class SpringBatchPagingItemReaderRenderingStrategy extends MyBatis3RenderingStrategy {
28+
29+
@Override
30+
public String getFormattedJdbcPlaceholderForLimitOrOffset(String prefix, String parameterName) {
31+
return "#{" //$NON-NLS-1$
32+
+ parameterName
33+
+ "}"; //$NON-NLS-1$
34+
}
35+
36+
@Override
37+
public String formatParameterMapKeyForLimit(AtomicInteger sequence) {
38+
return "_pagesize"; //$NON-NLS-1$
39+
}
2840

2941
@Override
30-
public String getFormattedJdbcPlaceholder(BindableColumn<?> column, String prefix, String parameterName) {
31-
String newPrefix = SpringBatchUtility.PARAMETER_KEY + "." + prefix; //$NON-NLS-1$
32-
return super.getFormattedJdbcPlaceholder(column, newPrefix, parameterName);
42+
public String formatParameterMapKeyForOffset(AtomicInteger sequence) {
43+
return "_skiprows"; //$NON-NLS-1$
3344
}
3445
}

src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingReaderSelectModel.java

Lines changed: 0 additions & 59 deletions
This file was deleted.

src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchProviderAdapter.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,9 @@
1717

1818
import java.util.Map;
1919

20-
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
21-
2220
public class SpringBatchProviderAdapter {
2321

2422
public String select(Map<String, Object> parameterValues) {
25-
SelectStatementProvider selectStatement =
26-
(SelectStatementProvider) parameterValues.get(SpringBatchUtility.PARAMETER_KEY);
27-
return selectStatement.getSelectStatement();
23+
return (String) parameterValues.get(SpringBatchUtility.PARAMETER_KEY);
2824
}
2925
}

src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchUtility.java

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,48 +18,39 @@
1818
import java.util.HashMap;
1919
import java.util.Map;
2020

21-
import org.mybatis.dynamic.sql.BasicColumn;
2221
import org.mybatis.dynamic.sql.render.RenderingStrategy;
23-
import org.mybatis.dynamic.sql.select.QueryExpressionDSL;
24-
import org.mybatis.dynamic.sql.select.SelectDSL;
2522
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
2623

2724
public class SpringBatchUtility {
2825
private SpringBatchUtility() {}
2926

30-
public static final String PARAMETER_KEY = "mybatis3_dsql_query"; //$NON-NLS-1$
31-
32-
public static final RenderingStrategy SPRING_BATCH_READER_RENDERING_STRATEGY =
33-
new SpringBatchReaderRenderingStrategy();
34-
35-
public static Map<String, Object> toParameterValues(SelectStatementProvider selectStatement) {
36-
Map<String, Object> parameterValues = new HashMap<>();
37-
parameterValues.put(PARAMETER_KEY, selectStatement);
38-
return parameterValues;
39-
}
27+
static final String PARAMETER_KEY = "mybatis3_dsql_query"; //$NON-NLS-1$
4028

4129
/**
42-
* Select builder that renders in a manner appropriate for the MyBatisPagingItemReader.
43-
*
44-
* <p><b>Important</b> rendered SQL will contain LIMIT and OFFSET clauses in the SELECT statement. If your database
45-
* (Oracle) does not support LIMIT and OFFSET, the queries will fail.
30+
* Constant for use in a query intended for use with the MyBatisPagingItemReader.
31+
* This value will not be used in the query at runtime because MyBatis Spring integration
32+
* will supply a value for _skiprows.
4633
*
47-
* @param selectList a column list for the SELECT statement
48-
* @return FromGatherer used to continue a SELECT statement
34+
* <p>See <a href="https://mybatis.org/spring/batch.html">https://mybatis.org/spring/batch.html</a> for details.
4935
*/
50-
public static QueryExpressionDSL.FromGatherer<SpringBatchPagingReaderSelectModel> selectForPaging(
51-
BasicColumn... selectList) {
52-
return SelectDSL.select(SpringBatchPagingReaderSelectModel::new, selectList);
53-
}
36+
public static final long MYBATIS_SPRING_BATCH_SKIPROWS = -437L;
5437

5538
/**
56-
* Select builder that renders in a manner appropriate for the MyBatisCursorItemReader.
39+
* Constant for use in a query intended for use with the MyBatisPagingItemReader.
40+
* This value will not be used in the query at runtime because MyBatis Spring integration
41+
* will supply a value for _pagesize.
5742
*
58-
* @param selectList a column list for the SELECT statement
59-
* @return FromGatherer used to continue a SELECT statement
43+
* <p>See <a href="https://mybatis.org/spring/batch.html">https://mybatis.org/spring/batch.html</a> for details.
6044
*/
61-
public static QueryExpressionDSL.FromGatherer<SpringBatchCursorReaderSelectModel> selectForCursor(
62-
BasicColumn... selectList) {
63-
return SelectDSL.select(SpringBatchCursorReaderSelectModel::new, selectList);
45+
public static final long MYBATIS_SPRING_BATCH_PAGESIZE = -439L;
46+
47+
public static final RenderingStrategy SPRING_BATCH_PAGING_ITEM_READER_RENDERING_STRATEGY =
48+
new SpringBatchPagingItemReaderRenderingStrategy();
49+
50+
public static Map<String, Object> toParameterValues(SelectStatementProvider selectStatement) {
51+
Map<String, Object> parameterValues = new HashMap<>();
52+
parameterValues.put(PARAMETER_KEY, selectStatement.getSelectStatement());
53+
parameterValues.put("parameters", selectStatement.getParameters()); //$NON-NLS-1$
54+
return parameterValues;
6455
}
6556
}

src/test/java/examples/springbatch/cursor/CursorReaderBatchConfiguration.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@
1818
import static examples.springbatch.mapper.PersonDynamicSqlSupport.lastName;
1919
import static examples.springbatch.mapper.PersonDynamicSqlSupport.person;
2020
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
21+
import static org.mybatis.dynamic.sql.SqlBuilder.select;
2122

2223
import javax.sql.DataSource;
2324

2425
import org.apache.ibatis.session.SqlSessionFactory;
26+
import org.mybatis.dynamic.sql.render.RenderingStrategies;
2527
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
2628
import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider;
2729
import org.mybatis.dynamic.sql.util.springbatch.SpringBatchUtility;
@@ -89,11 +91,11 @@ public PlatformTransactionManager transactionManager(DataSource dataSource) {
8991

9092
@Bean
9193
public MyBatisCursorItemReader<PersonRecord> reader(SqlSessionFactory sqlSessionFactory) {
92-
SelectStatementProvider selectStatement = SpringBatchUtility.selectForCursor(person.allColumns())
94+
SelectStatementProvider selectStatement = select(person.allColumns())
9395
.from(person)
9496
.where(lastName, isEqualTo("flintstone"))
9597
.build()
96-
.render();
98+
.render(RenderingStrategies.MYBATIS3);
9799

98100
MyBatisCursorItemReader<PersonRecord> reader = new MyBatisCursorItemReader<>();
99101
reader.setQueryId(PersonMapper.class.getName() + ".selectMany");

src/test/java/examples/springbatch/paging/PagingReaderBatchConfiguration.java

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

1818
import static examples.springbatch.mapper.PersonDynamicSqlSupport.*;
1919
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
20+
import static org.mybatis.dynamic.sql.SqlBuilder.select;
2021

2122
import javax.sql.DataSource;
2223

@@ -88,12 +89,14 @@ public PlatformTransactionManager transactionManager(DataSource dataSource) {
8889

8990
@Bean
9091
public MyBatisPagingItemReader<PersonRecord> reader(SqlSessionFactory sqlSessionFactory) {
91-
SelectStatementProvider selectStatement = SpringBatchUtility.selectForPaging(person.allColumns())
92+
SelectStatementProvider selectStatement = select(person.allColumns())
9293
.from(person)
9394
.where(forPagingTest, isEqualTo(true))
9495
.orderBy(id)
96+
.limit(SpringBatchUtility.MYBATIS_SPRING_BATCH_PAGESIZE)
97+
.offset(SpringBatchUtility.MYBATIS_SPRING_BATCH_SKIPROWS)
9598
.build()
96-
.render();
99+
.render(SpringBatchUtility.SPRING_BATCH_PAGING_ITEM_READER_RENDERING_STRATEGY);
97100

98101
MyBatisPagingItemReader<PersonRecord> reader = new MyBatisPagingItemReader<>();
99102
reader.setQueryId(PersonMapper.class.getName() + ".selectMany");

0 commit comments

Comments
 (0)