Skip to content

Commit

Permalink
Merge pull request #861 from jeffgbutler/rework-spring-batch
Browse files Browse the repository at this point in the history
Improve Spring Batch Support
  • Loading branch information
jeffgbutler authored Oct 24, 2024
2 parents f3b0725 + cfb47bc commit d819167
Show file tree
Hide file tree
Showing 19 changed files with 386 additions and 258 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ worked to make these changes as minimal as possible.

**Potentially Breaking Changes:**

- If you use this library with MyBatis' Spring Batch integration, you will need to make changes as we have
refactored that support to be more flexible. Please see the
[Spring Batch](https://mybatis.org/mybatis-dynamic-sql/docs/springBatch.html) documentation page to see the new usage
details.
- If you have created any custom implementations of `SortSpecification`, you will need to update those
implementations due to a new rendering strategy for ORDER BY phrases. The old methods `isDescending` and `orderByName`
are removed in favor of a new method `renderForOrderBy`
Expand Down
2 changes: 2 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
<properties>
<java.version>17</java.version>
<java.release.version>17</java.release.version>
<java.test.version>17</java.test.version>
<java.test.release.version>17</java.test.release.version>
<junit.jupiter.version>5.11.3</junit.jupiter.version>
<spring.batch.version>5.1.2</spring.batch.version>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ private Optional<FragmentAndParameters> calculateLimitClause() {
}

private FragmentAndParameters renderLimitClause(Long limit) {
RenderedParameterInfo parameterInfo = renderingContext.calculateParameterInfo();
RenderedParameterInfo parameterInfo = renderingContext.calculateLimitParameterInfo();

return FragmentAndParameters.withFragment("limit " + parameterInfo.renderedPlaceHolder()) //$NON-NLS-1$
.withParameter(parameterInfo.parameterMapKey(), limit)
Expand Down
23 changes: 16 additions & 7 deletions src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,27 @@ private String nextMapKey() {
return renderingStrategy.formatParameterMapKey(sequence);
}

private String renderedPlaceHolder(String mapKey) {
return renderingStrategy.getFormattedJdbcPlaceholder(calculatedParameterName, mapKey);
}

private <T> String renderedPlaceHolder(String mapKey, BindableColumn<T> column) {
return column.renderingStrategy().orElse(renderingStrategy)
.getFormattedJdbcPlaceholder(column, calculatedParameterName, mapKey);
}

public RenderedParameterInfo calculateParameterInfo() {
String mapKey = nextMapKey();
return new RenderedParameterInfo(mapKey, renderedPlaceHolder(mapKey));
public RenderedParameterInfo calculateFetchFirstRowsParameterInfo() {
String mapKey = renderingStrategy.formatParameterMapKeyForFetchFirstRows(sequence);
return new RenderedParameterInfo(mapKey,
renderingStrategy.getFormattedJdbcPlaceholderForPagingParameters(calculatedParameterName, mapKey));
}

public RenderedParameterInfo calculateLimitParameterInfo() {
String mapKey = renderingStrategy.formatParameterMapKeyForLimit(sequence);
return new RenderedParameterInfo(mapKey,
renderingStrategy.getFormattedJdbcPlaceholderForPagingParameters(calculatedParameterName, mapKey));
}

public RenderedParameterInfo calculateOffsetParameterInfo() {
String mapKey = renderingStrategy.formatParameterMapKeyForOffset(sequence);
return new RenderedParameterInfo(mapKey,
renderingStrategy.getFormattedJdbcPlaceholderForPagingParameters(calculatedParameterName, mapKey));
}

public <T> RenderedParameterInfo calculateParameterInfo(BindableColumn<T> column) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,55 @@
public abstract class RenderingStrategy {
public static final String DEFAULT_PARAMETER_PREFIX = "parameters"; //$NON-NLS-1$

/**
* Generate a unique key that can be used to place a parameter value in the parameter map.
*
* @param sequence a sequence for calculating a unique value
* @return a key used to place the parameter value in the parameter map
*/
public String formatParameterMapKey(AtomicInteger sequence) {
return "p" + sequence.getAndIncrement(); //$NON-NLS-1$
}

/**
* Return a parameter map key intended as a parameter for a fetch first query.
*
* <p>By default, this parameter is treated the same as any other. This method is a hook to support
* MyBatis Spring Batch.
*
* @param sequence a sequence for calculating a unique value
* @return a key used to place the parameter value in the parameter map
*/
public String formatParameterMapKeyForFetchFirstRows(AtomicInteger sequence) {
return formatParameterMapKey(sequence);
}

/**
* Return a parameter map key intended as a parameter for a limit query.
*
* <p>By default, this parameter is treated the same as any other. This method is a hook to support
* MyBatis Spring Batch.
*
* @param sequence a sequence for calculating a unique value
* @return a key used to place the parameter value in the parameter map
*/
public String formatParameterMapKeyForLimit(AtomicInteger sequence) {
return formatParameterMapKey(sequence);
}

/**
* Return a parameter map key intended as a parameter for a query offset.
*
* <p>By default, this parameter is treated the same as any other. This method is a hook to support
* MyBatis Spring Batch.
*
* @param sequence a sequence for calculating a unique value
* @return a key used to place the parameter value in the parameter map
*/
public String formatParameterMapKeyForOffset(AtomicInteger sequence) {
return formatParameterMapKey(sequence);
}

/**
* This method generates a binding for a parameter to a placeholder in a generated SQL statement.
*
Expand Down Expand Up @@ -78,6 +123,23 @@ public String formatParameterMapKey(AtomicInteger sequence) {
*/
public abstract String getFormattedJdbcPlaceholder(String prefix, String parameterName);

/**
* This method generates a binding for a parameter to a placeholder in a generated SQL statement.
*
* <p>This method is used to generate bindings for limit, offset, and fetch first parameters. By default, these
* parameters are treated the same as any other. This method supports MyBatis Spring Batch integration where the
* parameter keys have predefined values and need special handling.
*
* @param prefix parameter prefix used for locating the parameters in a SQL provider object. Typically, will be
* {@link RenderingStrategy#DEFAULT_PARAMETER_PREFIX}. This is ignored for Spring.
* @param parameterName name of the parameter. Typically generated by calling
* {@link RenderingStrategy#formatParameterMapKey(AtomicInteger)}
* @return the generated binding
*/
public String getFormattedJdbcPlaceholderForPagingParameters(String prefix, String parameterName) {
return getFormattedJdbcPlaceholder(prefix, parameterName);
}

/**
* This method generates a binding for a parameter to a placeholder in a row based insert statement.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,30 +51,30 @@ private FragmentAndParameters renderFetchFirstRowsOnly() {
}

private FragmentAndParameters renderFetchFirstRowsOnly(Long fetchFirstRows) {
RenderedParameterInfo parameterInfo = renderingContext.calculateParameterInfo();
RenderedParameterInfo fetchFirstParameterInfo = renderingContext.calculateFetchFirstRowsParameterInfo();
return FragmentAndParameters
.withFragment("fetch first " + parameterInfo.renderedPlaceHolder() //$NON-NLS-1$
.withFragment("fetch first " + fetchFirstParameterInfo.renderedPlaceHolder() //$NON-NLS-1$
+ " rows only") //$NON-NLS-1$
.withParameter(parameterInfo.parameterMapKey(), fetchFirstRows)
.withParameter(fetchFirstParameterInfo.parameterMapKey(), fetchFirstRows)
.build();
}

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

private FragmentAndParameters renderOffsetAndFetchFirstRows(Long offset, Long fetchFirstRows) {
RenderedParameterInfo parameterInfo1 = renderingContext.calculateParameterInfo();
RenderedParameterInfo parameterInfo2 = renderingContext.calculateParameterInfo();
return FragmentAndParameters.withFragment("offset " + parameterInfo1.renderedPlaceHolder() //$NON-NLS-1$
+ " rows fetch first " + parameterInfo2.renderedPlaceHolder() //$NON-NLS-1$
RenderedParameterInfo offsetParameterInfo = renderingContext.calculateOffsetParameterInfo();
RenderedParameterInfo fetchFirstParameterInfo = renderingContext.calculateFetchFirstRowsParameterInfo();
return FragmentAndParameters.withFragment("offset " + offsetParameterInfo.renderedPlaceHolder() //$NON-NLS-1$
+ " rows fetch first " + fetchFirstParameterInfo.renderedPlaceHolder() //$NON-NLS-1$
+ " rows only") //$NON-NLS-1$
.withParameter(parameterInfo1.parameterMapKey(), offset)
.withParameter(parameterInfo2.parameterMapKey(), fetchFirstRows)
.withParameter(offsetParameterInfo.parameterMapKey(), offset)
.withParameter(fetchFirstParameterInfo.parameterMapKey(), fetchFirstRows)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,19 @@ public FragmentAndParameters render() {
}

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

private FragmentAndParameters renderLimitAndOffset(Long offset) {
RenderedParameterInfo parameterInfo1 = renderingContext.calculateParameterInfo();
RenderedParameterInfo parameterInfo2 = renderingContext.calculateParameterInfo();
return FragmentAndParameters.withFragment("limit " + parameterInfo1.renderedPlaceHolder() //$NON-NLS-1$
+ " offset " + parameterInfo2.renderedPlaceHolder()) //$NON-NLS-1$
.withParameter(parameterInfo1.parameterMapKey(), limit)
.withParameter(parameterInfo2.parameterMapKey(), offset)
RenderedParameterInfo limitParameterInfo = renderingContext.calculateLimitParameterInfo();
RenderedParameterInfo offsetParameterInfo = renderingContext.calculateOffsetParameterInfo();
return FragmentAndParameters.withFragment("limit " + limitParameterInfo.renderedPlaceHolder() //$NON-NLS-1$
+ " offset " + offsetParameterInfo.renderedPlaceHolder()) //$NON-NLS-1$
.withParameter(limitParameterInfo.parameterMapKey(), limit)
.withParameter(offsetParameterInfo.parameterMapKey(), offset)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ private Optional<FragmentAndParameters> calculateLimitClause() {
}

private FragmentAndParameters renderLimitClause(Long limit) {
RenderedParameterInfo parameterInfo = renderingContext.calculateParameterInfo();
RenderedParameterInfo parameterInfo = renderingContext.calculateLimitParameterInfo();

return FragmentAndParameters.withFragment("limit " + parameterInfo.renderedPlaceHolder()) //$NON-NLS-1$
.withParameter(parameterInfo.parameterMapKey(), limit)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright 2016-2024 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
*
* https://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.mybatis.dynamic.sql.util.springbatch;

import java.util.concurrent.atomic.AtomicInteger;

import org.mybatis.dynamic.sql.render.MyBatis3RenderingStrategy;

/**
* This rendering strategy should be used for MyBatis3 statements using the
* MyBatisPagingItemReader supplied by mybatis-spring integration
* (<a href="http://www.mybatis.org/spring/">http://www.mybatis.org/spring/</a>).
*/
public class SpringBatchPagingItemReaderRenderingStrategy extends MyBatis3RenderingStrategy {

@Override
public String getFormattedJdbcPlaceholderForPagingParameters(String prefix, String parameterName) {
return "#{" //$NON-NLS-1$
+ parameterName
+ "}"; //$NON-NLS-1$
}

@Override
public String formatParameterMapKeyForFetchFirstRows(AtomicInteger sequence) {
return "_pagesize"; //$NON-NLS-1$
}

@Override
public String formatParameterMapKeyForLimit(AtomicInteger sequence) {
return "_pagesize"; //$NON-NLS-1$
}

@Override
public String formatParameterMapKeyForOffset(AtomicInteger sequence) {
return "_skiprows"; //$NON-NLS-1$
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,9 @@

import java.util.Map;

import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;

public class SpringBatchProviderAdapter {

public String select(Map<String, Object> parameterValues) {
SelectStatementProvider selectStatement =
(SelectStatementProvider) parameterValues.get(SpringBatchUtility.PARAMETER_KEY);
return selectStatement.getSelectStatement();
return (String) parameterValues.get(SpringBatchUtility.PARAMETER_KEY);
}
}
Loading

0 comments on commit d819167

Please sign in to comment.