Skip to content

Commit 4f38c5b

Browse files
committed
Merge branch '6.2.x'
2 parents 13b09e6 + dd6eede commit 4f38c5b

File tree

7 files changed

+164
-209
lines changed

7 files changed

+164
-209
lines changed

spring-r2dbc/src/main/java/org/springframework/r2dbc/core/NamedParameterUtils.java

+61-55
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -49,6 +49,7 @@
4949
* @author Juergen Hoeller
5050
* @author Mark Paluch
5151
* @author Anton Naydenov
52+
* @author Sam Brannen
5253
* @since 5.3
5354
*/
5455
abstract class NamedParameterUtils {
@@ -512,37 +513,75 @@ private static class ExpandedQuery implements PreparedOperation<String> {
512513

513514
private final BindParameterSource parameterSource;
514515

516+
515517
ExpandedQuery(String expandedSql, NamedParameters parameters, BindParameterSource parameterSource) {
516518
this.expandedSql = expandedSql;
517519
this.parameters = parameters;
518520
this.parameterSource = parameterSource;
519521
}
520522

521-
@SuppressWarnings({"rawtypes", "unchecked"})
522-
public void bind(BindTarget target, String identifier, Parameter parameter) {
523-
List<BindMarker> bindMarkers = getBindMarkers(identifier);
523+
524+
@Override
525+
public String toQuery() {
526+
return this.expandedSql;
527+
}
528+
529+
@Override
530+
public String getSource() {
531+
return this.expandedSql;
532+
}
533+
534+
@Override
535+
public void bindTo(BindTarget target) {
536+
for (String namedParameter : this.parameterSource.getParameterNames()) {
537+
Parameter parameter = this.parameterSource.getValue(namedParameter);
538+
if (parameter.getValue() == null) {
539+
bindNull(target, namedParameter, parameter);
540+
}
541+
else {
542+
bind(target, namedParameter, parameter);
543+
}
544+
}
545+
}
546+
547+
private void bindNull(BindTarget target, String identifier, Parameter parameter) {
548+
List<List<BindMarker>> bindMarkers = getBindMarkers(identifier);
549+
if (bindMarkers == null) {
550+
target.bind(identifier, parameter);
551+
return;
552+
}
553+
for (List<BindMarker> outer : bindMarkers) {
554+
for (BindMarker bindMarker : outer) {
555+
bindMarker.bind(target, parameter);
556+
}
557+
}
558+
}
559+
560+
private void bind(BindTarget target, String identifier, Parameter parameter) {
561+
List<List<BindMarker>> bindMarkers = getBindMarkers(identifier);
524562
if (bindMarkers == null) {
525563
target.bind(identifier, parameter);
526564
return;
527565
}
528-
if (parameter.getValue() instanceof Collection collection) {
529-
Iterator<Object> iterator = collection.iterator();
530-
Iterator<BindMarker> markers = bindMarkers.iterator();
531-
while (iterator.hasNext()) {
532-
Object valueToBind = iterator.next();
533-
if (valueToBind instanceof Object[] objects) {
534-
for (Object object : objects) {
535-
bind(target, markers, object);
566+
567+
for (List<BindMarker> outer : bindMarkers) {
568+
if (parameter.getValue() instanceof Collection<?> collection) {
569+
Iterator<BindMarker> markers = outer.iterator();
570+
for (Object valueToBind : collection) {
571+
if (valueToBind instanceof Object[] objects) {
572+
for (Object object : objects) {
573+
bind(target, markers, object);
574+
}
575+
}
576+
else {
577+
bind(target, markers, valueToBind);
536578
}
537-
}
538-
else {
539-
bind(target, markers, valueToBind);
540579
}
541580
}
542-
}
543-
else {
544-
for (BindMarker bindMarker : bindMarkers) {
545-
bindMarker.bind(target, parameter);
581+
else {
582+
for (BindMarker bindMarker : outer) {
583+
bindMarker.bind(target, parameter);
584+
}
546585
}
547586
}
548587
}
@@ -554,51 +593,18 @@ private void bind(BindTarget target, Iterator<BindMarker> markers, Object valueT
554593
markers.next().bind(target, valueToBind);
555594
}
556595

557-
public void bindNull(BindTarget target, String identifier, Parameter parameter) {
558-
List<BindMarker> bindMarkers = getBindMarkers(identifier);
559-
if (bindMarkers == null) {
560-
target.bind(identifier, parameter);
561-
return;
562-
}
563-
for (BindMarker bindMarker : bindMarkers) {
564-
bindMarker.bind(target, parameter);
565-
}
566-
}
567-
568-
@Nullable List<BindMarker> getBindMarkers(String identifier) {
596+
private @Nullable List<List<BindMarker>> getBindMarkers(String identifier) {
569597
List<NamedParameters.NamedParameter> parameters = this.parameters.getMarker(identifier);
570598
if (parameters == null) {
571599
return null;
572600
}
573-
List<BindMarker> markers = new ArrayList<>();
601+
List<List<BindMarker>> markers = new ArrayList<>();
574602
for (NamedParameters.NamedParameter parameter : parameters) {
575-
markers.addAll(parameter.placeholders);
603+
markers.add(new ArrayList<>(parameter.placeholders));
576604
}
577605
return markers;
578606
}
579607

580-
@Override
581-
public String getSource() {
582-
return this.expandedSql;
583-
}
584-
585-
@Override
586-
public void bindTo(BindTarget target) {
587-
for (String namedParameter : this.parameterSource.getParameterNames()) {
588-
Parameter parameter = this.parameterSource.getValue(namedParameter);
589-
if (parameter.getValue() == null) {
590-
bindNull(target, namedParameter, parameter);
591-
}
592-
else {
593-
bind(target, namedParameter, parameter);
594-
}
595-
}
596-
}
597-
598-
@Override
599-
public String toQuery() {
600-
return this.expandedSql;
601-
}
602608
}
603609

604610
}

spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/AnonymousBindMarkers.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,8 +19,9 @@
1919
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
2020

2121
/**
22-
* Anonymous, index-based bind marker using a static placeholder.
23-
* Instances are bound by the ordinal position ordered by the appearance of
22+
* Anonymous, index-based bind markers that use a static placeholder.
23+
*
24+
* <p>Instances are bound by the ordinal position ordered by the appearance of
2425
* the placeholder. This implementation creates indexed bind markers using
2526
* an anonymous placeholder that correlates with an index.
2627
*
@@ -46,7 +47,7 @@ class AnonymousBindMarkers implements BindMarkers {
4647

4748

4849
/**
49-
* Create a new {@link AnonymousBindMarkers} instance given {@code placeholder}.
50+
* Create a new {@link AnonymousBindMarkers} instance for the given {@code placeholder}.
5051
* @param placeholder parameter bind marker
5152
*/
5253
AnonymousBindMarkers(String placeholder) {

spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarker.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,7 +20,8 @@
2020

2121
/**
2222
* A bind marker represents a single bindable parameter within a query.
23-
* Bind markers are dialect-specific and provide a
23+
*
24+
* <p>Bind markers are dialect-specific and provide a
2425
* {@link #getPlaceholder() placeholder} that is used in the actual query.
2526
*
2627
* @author Mark Paluch
@@ -37,7 +38,8 @@ public interface BindMarker {
3738
String getPlaceholder();
3839

3940
/**
40-
* Bind the given {@code value} to the {@link Statement} using the underlying binding strategy.
41+
* Bind the given {@code value} to the {@link Statement} using the underlying
42+
* binding strategy.
4143
* @param bindTarget the target to bind the value to
4244
* @param value the actual value (must not be {@code null};
4345
* use {@link #bindNull(BindTarget, Class)} for {@code null} values)
@@ -46,7 +48,8 @@ public interface BindMarker {
4648
void bind(BindTarget bindTarget, Object value);
4749

4850
/**
49-
* Bind a {@code null} value to the {@link Statement} using the underlying binding strategy.
51+
* Bind a {@code null} value to the {@link Statement} using the underlying
52+
* binding strategy.
5053
* @param bindTarget the target to bind the value to
5154
* @param valueType the value type (must not be {@code null})
5255
* @see Statement#bindNull

spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarkers.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,10 +20,10 @@
2020
* Bind markers represent placeholders in SQL queries for substitution
2121
* for an actual parameter. Using bind markers allows creating safe queries
2222
* so query strings are not required to contain escaped values but rather
23-
* the driver encodes parameter in the appropriate representation.
23+
* the driver encodes the parameter in the appropriate representation.
2424
*
2525
* <p>{@link BindMarkers} is stateful and can be only used for a single binding
26-
* pass of one or more parameters. It maintains bind indexes/bind parameter names.
26+
* pass of one or more parameters. It maintains bind indexes or bind parameter names.
2727
*
2828
* @author Mark Paluch
2929
* @since 5.3
@@ -41,7 +41,7 @@ public interface BindMarkers {
4141

4242
/**
4343
* Create a new {@link BindMarker} that accepts a {@code hint}.
44-
* Implementations are allowed to consider/ignore/filter
44+
* <p>Implementations are allowed to consider/ignore/filter
4545
* the name hint to create more expressive bind markers.
4646
* @param hint an optional name hint that can be used as part of the bind marker
4747
* @return a new {@link BindMarker}

spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/BindMarkersFactoryResolver.java

+19-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -30,8 +30,8 @@
3030

3131
/**
3232
* Resolves a {@link BindMarkersFactory} from a {@link ConnectionFactory} using
33-
* {@link BindMarkerFactoryProvider}. Dialect resolution uses Spring's
34-
* {@link SpringFactoriesLoader spring.factories} to determine available extensions.
33+
* a {@link BindMarkerFactoryProvider}. Dialect resolution uses Spring's
34+
* {@link SpringFactoriesLoader spring.factories} file to determine available extensions.
3535
*
3636
* @author Mark Paluch
3737
* @since 5.3
@@ -45,8 +45,8 @@ public final class BindMarkersFactoryResolver {
4545

4646

4747
/**
48-
* Retrieve a {@link BindMarkersFactory} by inspecting {@link ConnectionFactory}
49-
* and its metadata.
48+
* Retrieve a {@link BindMarkersFactory} by inspecting the supplied
49+
* {@link ConnectionFactory} and its metadata.
5050
* @param connectionFactory the connection factory to inspect
5151
* @return the resolved {@link BindMarkersFactory}
5252
* @throws NoBindMarkersFactoryException if no {@link BindMarkersFactory} can be resolved
@@ -69,26 +69,29 @@ private BindMarkersFactoryResolver() {
6969

7070

7171
/**
72-
* SPI to extend Spring's default R2DBC BindMarkersFactory discovery mechanism.
73-
* Implementations of this interface are discovered through Spring's
72+
* SPI to extend Spring's default R2DBC {@link BindMarkersFactory} discovery
73+
* mechanism.
74+
*
75+
* <p>Implementations of this interface are discovered through Spring's
7476
* {@link SpringFactoriesLoader} mechanism.
77+
*
7578
* @see SpringFactoriesLoader
7679
*/
7780
@FunctionalInterface
7881
public interface BindMarkerFactoryProvider {
7982

8083
/**
81-
* Return a {@link BindMarkersFactory} for a {@link ConnectionFactory}.
82-
* @param connectionFactory the connection factory to be used with the {@link BindMarkersFactory}
83-
* @return the {@link BindMarkersFactory} if the {@link BindMarkerFactoryProvider}
84+
* Return a {@link BindMarkersFactory} for the given {@link ConnectionFactory}.
85+
* @param connectionFactory the connection factory to be used with the {@code BindMarkersFactory}
86+
* @return the {@code BindMarkersFactory} if this {@code BindMarkerFactoryProvider}
8487
* can provide a bind marker factory object, otherwise {@code null}
8588
*/
8689
@Nullable BindMarkersFactory getBindMarkers(ConnectionFactory connectionFactory);
8790
}
8891

8992

9093
/**
91-
* Exception thrown when {@link BindMarkersFactoryResolver} cannot resolve a
94+
* Exception thrown when a {@link BindMarkersFactoryResolver} cannot resolve a
9295
* {@link BindMarkersFactory}.
9396
*/
9497
@SuppressWarnings("serial")
@@ -105,8 +108,11 @@ public NoBindMarkersFactoryException(String msg) {
105108

106109

107110
/**
108-
* Built-in bind maker factories. Used typically as last {@link BindMarkerFactoryProvider}
109-
* when other providers register with a higher precedence.
111+
* Built-in bind marker factories.
112+
*
113+
* <p>Typically used as the last {@link BindMarkerFactoryProvider} when other
114+
* providers are registered with a higher precedence.
115+
*
110116
* @see org.springframework.core.Ordered
111117
* @see org.springframework.core.annotation.AnnotationAwareOrderComparator
112118
*/

spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/IndexedBindMarkers.java

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@
1919
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
2020

2121
/**
22-
* Index-based bind marker. This implementation creates indexed bind
22+
* Index-based bind markers. This implementation creates indexed bind
2323
* markers using a numeric index and an optional prefix for bind markers
2424
* to be represented within the query string.
2525
*
@@ -43,14 +43,15 @@ class IndexedBindMarkers implements BindMarkers {
4343

4444

4545
/**
46-
* Create a new {@link IndexedBindMarker} instance given {@code prefix} and {@code beginWith}.
47-
* @param prefix bind parameter prefix
48-
* @param beginWith the first index to use
46+
* Create a new {@link IndexedBindMarker} instance for the given {@code prefix}
47+
* and {@code beginWith} value.
48+
* @param prefix the bind parameter prefix
49+
* @param beginIndex the first index to use
4950
*/
50-
IndexedBindMarkers(String prefix, int beginWith) {
51+
IndexedBindMarkers(String prefix, int beginIndex) {
5152
this.counter = 0;
5253
this.prefix = prefix;
53-
this.offset = beginWith;
54+
this.offset = beginIndex;
5455
}
5556

5657

0 commit comments

Comments
 (0)