20
20
import java .lang .reflect .Array ;
21
21
import java .lang .reflect .Constructor ;
22
22
import java .sql .SQLType ;
23
- import java .util .AbstractMap ;
24
23
import java .util .ArrayList ;
25
24
import java .util .Collection ;
26
25
import java .util .LinkedHashMap ;
27
26
import java .util .List ;
28
- import java .util .Map ;
29
27
import java .util .function .Function ;
30
28
import java .util .function .Supplier ;
31
29
32
30
import org .springframework .beans .BeanInstantiationException ;
33
31
import org .springframework .beans .BeanUtils ;
34
32
import org .springframework .beans .factory .BeanFactory ;
33
+ import org .springframework .core .env .StandardEnvironment ;
35
34
import org .springframework .data .expression .ValueEvaluationContext ;
36
35
import org .springframework .data .expression .ValueExpressionParser ;
37
36
import org .springframework .data .jdbc .core .convert .JdbcColumnTypes ;
51
50
import org .springframework .data .repository .query .ValueExpressionQueryRewriter ;
52
51
import org .springframework .data .util .Lazy ;
53
52
import org .springframework .data .util .TypeInformation ;
54
- import org .springframework .expression .spel .standard .SpelExpressionParser ;
55
53
import org .springframework .jdbc .core .ResultSetExtractor ;
56
54
import org .springframework .jdbc .core .RowMapper ;
57
55
import org .springframework .jdbc .core .namedparam .MapSqlParameterSource ;
74
72
* @author Chirag Tailor
75
73
* @author Christopher Klein
76
74
* @author Mikhail Polivakha
75
+ * @author Marcin Grzejszczak
77
76
* @since 2.0
78
77
*/
79
78
public class StringBasedJdbcQuery extends AbstractJdbcQuery {
@@ -82,13 +81,11 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
82
81
private final JdbcConverter converter ;
83
82
private final RowMapperFactory rowMapperFactory ;
84
83
private final ValueExpressionQueryRewriter .ParsedQuery parsedQuery ;
85
- private final boolean containsSpelExpressions ;
86
84
private final String query ;
87
85
88
86
private final CachedRowMapperFactory cachedRowMapperFactory ;
89
87
private final CachedResultSetExtractorFactory cachedResultSetExtractorFactory ;
90
88
private final ValueExpressionDelegate delegate ;
91
- private final List <Map .Entry <String , String >> parameterBindings ;
92
89
93
90
/**
94
91
* Creates a new {@link StringBasedJdbcQuery} for the given {@link JdbcQueryMethod}, {@link RelationalMappingContext}
@@ -186,17 +183,11 @@ public StringBasedJdbcQuery(String query, JdbcQueryMethod queryMethod, NamedPara
186
183
this .cachedResultSetExtractorFactory = new CachedResultSetExtractorFactory (
187
184
this .cachedRowMapperFactory ::getRowMapper );
188
185
189
- this .parameterBindings = new ArrayList <>();
190
-
191
- ValueExpressionQueryRewriter rewriter = ValueExpressionQueryRewriter .of (delegate , (counter , expression ) -> {
192
- String newName = String .format ("__$synthetic$__%d" , counter + 1 );
193
- parameterBindings .add (new AbstractMap .SimpleEntry <>(newName , expression ));
194
- return newName ;
195
- }, String ::concat );
186
+ ValueExpressionQueryRewriter rewriter = ValueExpressionQueryRewriter .of (delegate ,
187
+ (counter , expression ) -> String .format ("__$synthetic$__%d" , counter + 1 ), String ::concat );
196
188
197
189
this .query = query ;
198
190
this .parsedQuery = rewriter .parse (this .query );
199
- this .containsSpelExpressions = !this .parsedQuery .getQueryString ().equals (this .query );
200
191
this .delegate = delegate ;
201
192
}
202
193
@@ -217,9 +208,10 @@ public StringBasedJdbcQuery(String query, JdbcQueryMethod queryMethod, NamedPara
217
208
public StringBasedJdbcQuery (String query , JdbcQueryMethod queryMethod , NamedParameterJdbcOperations operations ,
218
209
RowMapperFactory rowMapperFactory , JdbcConverter converter ,
219
210
QueryMethodEvaluationContextProvider evaluationContextProvider ) {
220
- this (query , queryMethod , operations , rowMapperFactory , converter , new CachingValueExpressionDelegate (new QueryMethodValueEvaluationContextAccessor (null ,
221
- rootObject -> evaluationContextProvider .getEvaluationContext (queryMethod .getParameters (), new Object [] { rootObject })), ValueExpressionParser .create (
222
- SpelExpressionParser ::new )));
211
+ this (query , queryMethod , operations , rowMapperFactory , converter , new CachingValueExpressionDelegate (
212
+ new QueryMethodValueEvaluationContextAccessor (new StandardEnvironment (), rootObject -> evaluationContextProvider
213
+ .getEvaluationContext (queryMethod .getParameters (), new Object [] { rootObject })),
214
+ ValueExpressionParser .create ()));
223
215
}
224
216
225
217
@ Override
@@ -231,18 +223,22 @@ public Object execute(Object[] objects) {
231
223
JdbcQueryExecution <?> queryExecution = createJdbcQueryExecution (accessor , processor );
232
224
MapSqlParameterSource parameterMap = this .bindParameters (accessor );
233
225
234
- return queryExecution .execute (processSpelExpressions (objects , accessor .getBindableParameters (), parameterMap ), parameterMap );
226
+ return queryExecution .execute (evaluateExpressions (objects , accessor .getBindableParameters (), parameterMap ),
227
+ parameterMap );
235
228
}
236
229
237
- private String processSpelExpressions (Object [] objects , Parameters <?, ?> bindableParameters , MapSqlParameterSource parameterMap ) {
230
+ private String evaluateExpressions (Object [] objects , Parameters <?, ?> bindableParameters ,
231
+ MapSqlParameterSource parameterMap ) {
232
+
233
+ if (parsedQuery .hasParameterBindings ()) {
238
234
239
- if (containsSpelExpressions ) {
240
235
ValueEvaluationContext evaluationContext = delegate .createValueContextProvider (bindableParameters )
241
236
.getEvaluationContext (objects );
242
- for (Map .Entry <String , String > entry : parameterBindings ) {
243
- parameterMap .addValue (
244
- entry .getKey (), delegate .parse (entry .getValue ()).evaluate (evaluationContext ));
245
- }
237
+
238
+ parsedQuery .getParameterMap ().forEach ((paramName , valueExpression ) -> {
239
+ parameterMap .addValue (paramName , valueExpression .evaluate (evaluationContext ));
240
+ });
241
+
246
242
return parsedQuery .getQueryString ();
247
243
}
248
244
@@ -254,13 +250,12 @@ private JdbcQueryExecution<?> createJdbcQueryExecution(RelationalParameterAccess
254
250
255
251
if (getQueryMethod ().isModifyingQuery ()) {
256
252
return createModifyingQueryExecutor ();
257
- } else {
253
+ }
258
254
259
- Supplier <RowMapper <?>> rowMapper = () -> determineRowMapper (processor , accessor .findDynamicProjection () != null );
260
- ResultSetExtractor <Object > resultSetExtractor = determineResultSetExtractor (rowMapper );
255
+ Supplier <RowMapper <?>> rowMapper = () -> determineRowMapper (processor , accessor .findDynamicProjection () != null );
256
+ ResultSetExtractor <Object > resultSetExtractor = determineResultSetExtractor (rowMapper );
261
257
262
- return createReadingQueryExecution (resultSetExtractor , rowMapper );
263
- }
258
+ return createReadingQueryExecution (resultSetExtractor , rowMapper );
264
259
}
265
260
266
261
private MapSqlParameterSource bindParameters (RelationalParameterAccessor accessor ) {
0 commit comments