Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Spring Batch Support #861

Merged
merged 10 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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