Skip to content

Commit d1890e3

Browse files
committed
Reuse existing infrastructure for SpEL processing.
Original pull request #229 See #619
1 parent 9abaa5a commit d1890e3

File tree

3 files changed

+10
-787
lines changed

3 files changed

+10
-787
lines changed

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java

Lines changed: 10 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@
2929
import org.springframework.data.jdbc.core.convert.JdbcColumnTypes;
3030
import org.springframework.data.jdbc.core.convert.JdbcConverter;
3131
import org.springframework.data.jdbc.core.mapping.JdbcValue;
32-
import org.springframework.data.jdbc.repository.query.parameter.ParameterBindingParser;
33-
import org.springframework.data.jdbc.repository.query.parameter.ParameterBindings.Metadata;
34-
import org.springframework.data.jdbc.repository.query.parameter.ParameterBindings.ParameterBinding;
3532
import org.springframework.data.jdbc.support.JdbcUtil;
3633
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
3734
import org.springframework.data.relational.repository.query.RelationalParameterAccessor;
@@ -41,16 +38,12 @@
4138
import org.springframework.data.repository.query.Parameters;
4239
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
4340
import org.springframework.data.repository.query.ResultProcessor;
41+
import org.springframework.data.repository.query.SpelEvaluator;
4442
import org.springframework.data.repository.query.SpelQueryContext;
45-
import org.springframework.expression.EvaluationContext;
46-
import org.springframework.expression.Expression;
47-
import org.springframework.expression.ExpressionParser;
48-
import org.springframework.expression.spel.standard.SpelExpressionParser;
4943
import org.springframework.jdbc.core.ResultSetExtractor;
5044
import org.springframework.jdbc.core.RowMapper;
5145
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
5246
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
53-
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
5447
import org.springframework.lang.Nullable;
5548
import org.springframework.util.Assert;
5649
import org.springframework.util.ClassUtils;
@@ -130,16 +123,6 @@ public StringBasedJdbcQuery(JdbcQueryMethod queryMethod, NamedParameterJdbcOpera
130123
@Override
131124
public Object execute(Object[] objects) {
132125

133-
// List<ParameterBinding> parameterBindings = new ArrayList<>();
134-
// SpelQueryContext queryContext = SpelQueryContext.of((counter, expression) -> {
135-
//
136-
// String parameterName = String.format("__synthetic_%d__", counter);
137-
// parameterBindings.add(new ParameterBinding(parameterName, expression));
138-
// return parameterName;
139-
// }, String::concat);
140-
//
141-
// SpelQueryContext.SpelExtractor parsed = queryContext.parse(query);
142-
143126
RelationalParameterAccessor accessor = new RelationalParametersParameterAccessor(getQueryMethod(), objects);
144127
ResultProcessor processor = getQueryMethod().getResultProcessor().withDynamicProjection(accessor);
145128
ResultProcessingConverter converter = new ResultProcessingConverter(processor, this.converter.getMappingContext(),
@@ -153,51 +136,28 @@ public Object execute(Object[] objects) {
153136
determineResultSetExtractor(rowMapper), //
154137
rowMapper);
155138

156-
Metadata queryMeta = new Metadata();
139+
MapSqlParameterSource parameterMap = this.bindParameters(accessor);
157140

158141
String query = determineQuery();
159142

160143
if (ObjectUtils.isEmpty(query)) {
161144
throw new IllegalStateException(String.format("No query specified on %s", queryMethod.getName()));
162145
}
163-
List<ParameterBinding> bindings = new ArrayList<>();
164-
165-
query = ParameterBindingParser.INSTANCE.parseParameterBindingsOfQueryIntoBindingsAndReturnCleanedQuery(query,
166-
bindings, queryMeta);
167146

168-
SqlParameterSource parameterMap = this.bindParameters(accessor);
169-
extendParametersFromSpELEvaluation((MapSqlParameterSource) parameterMap, bindings, objects);
170-
return queryExecution.execute(query, parameterMap);
147+
return queryExecution.execute(processSpelExpressions(objects, parameterMap, query), parameterMap);
171148
}
172149

173-
/**
174-
* Extend the {@link MapSqlParameterSource} by evaluating each detected SpEL parameter in the original query. This is
175-
* basically a simple variant of Spring Data JPA's SPeL implementation.
176-
*
177-
* @param parameterMap
178-
* @param bindings
179-
* @param values
180-
*/
181-
void extendParametersFromSpELEvaluation(MapSqlParameterSource parameterMap, List<ParameterBinding> bindings,
182-
Object[] values) {
183-
184-
if (bindings.size() == 0) {
185-
return;
186-
}
150+
private String processSpelExpressions(Object[] objects, MapSqlParameterSource parameterMap, String query) {
187151

188-
ExpressionParser parser = new SpelExpressionParser();
152+
SpelQueryContext.EvaluatingSpelQueryContext queryContext = SpelQueryContext
153+
.of((counter, expression) -> String.format("__$synthetic$__%d", counter + 1), String::concat)
154+
.withEvaluationContextProvider(evaluationContextProvider);
189155

190-
bindings.forEach(binding -> {
191-
if (!binding.isExpression()) {
192-
return;
193-
}
156+
SpelEvaluator spelEvaluator = queryContext.parse(query, queryMethod.getParameters());
194157

195-
Expression expression = parser.parseExpression(binding.getExpression());
196-
EvaluationContext context = evaluationContextProvider.getEvaluationContext(this.queryMethod.getParameters(),
197-
values);
158+
spelEvaluator.evaluate(objects).forEach(parameterMap::addValue);
198159

199-
parameterMap.addValue(binding.getName(), expression.getValue(context, Object.class));
200-
});
160+
return spelEvaluator.getQueryString();
201161
}
202162

203163
@Override

0 commit comments

Comments
 (0)