Skip to content

Commit 2525927

Browse files
Support TypedPropertyPath for queries and update.
1 parent 60980b6 commit 2525927

File tree

5 files changed

+137
-2
lines changed

5 files changed

+137
-2
lines changed

spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/query/CriteriaUnitTests.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323
import org.assertj.core.api.SoftAssertions;
2424
import org.junit.jupiter.api.Test;
25-
2625
import org.springframework.data.relational.core.query.Criteria;
2726
import org.springframework.data.relational.core.sql.SqlIdentifier;
2827

@@ -31,6 +30,7 @@
3130
*
3231
* @author Mark Paluch
3332
* @author Mingyuan Wu
33+
* @author Christoph Strobl
3434
*/
3535
class CriteriaUnitTests {
3636

@@ -46,6 +46,11 @@ void fromCriteria() {
4646
assertThat(criteria.getPrevious()).isEqualTo(Criteria.empty());
4747
}
4848

49+
@Test // GH-2226
50+
void whereWithTypedPropertyPathIsEqualToStringColumnName() {
51+
assertThat(where(Person::getName).is("o")).isEqualTo(where("name").is("o"));
52+
}
53+
4954
@Test // gh-289
5055
void fromCriteriaOptimized() {
5156

@@ -95,6 +100,13 @@ void andChainedCriteria() {
95100
assertThat(criteria.getValue()).isEqualTo("bar");
96101
}
97102

103+
@Test // gh-2226
104+
void andChainedCriteriaWithTypedPropertyPathIsEqualToStringColumnName() {
105+
106+
assertThat(where(Person::getName).is("o").and(Person::getAge).isNotNull())
107+
.isEqualTo(where("name").is("o").and("age").isNotNull());
108+
}
109+
98110
@Test // gh-289
99111
void andGroupedCriteria() {
100112

@@ -128,6 +140,13 @@ void orChainedCriteria() {
128140
assertThat(criteria.getValue()).isEqualTo("bar");
129141
}
130142

143+
@Test // gh-2226
144+
void orChainedCriteriaWithTypedPropertyPathIsEqualToStringColumnName() {
145+
146+
assertThat(where(Person::getName).is("o").or(Person::getAge).isNotNull())
147+
.isEqualTo(where("name").is("o").or("age").isNotNull());
148+
}
149+
131150
@Test // gh-289
132151
void orGroupedCriteria() {
133152

@@ -290,4 +309,18 @@ void shouldBuildIsFalseCriteria() {
290309
assertThat(criteria.getColumn()).isEqualTo(SqlIdentifier.unquoted("foo"));
291310
assertThat(criteria.getComparator()).isEqualTo(Comparator.IS_FALSE);
292311
}
312+
313+
static class Person {
314+
315+
private String name;
316+
private Integer age;
317+
318+
public String getName() {
319+
return name;
320+
}
321+
322+
public Integer getAge() {
323+
return this.age;
324+
}
325+
}
293326
}

spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Criteria.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
import org.jspecify.annotations.Nullable;
2828
import org.springframework.dao.InvalidDataAccessApiUsageException;
29+
import org.springframework.data.core.TypedPropertyPath;
2930
import org.springframework.data.relational.core.sql.IdentifierProcessing;
3031
import org.springframework.data.relational.core.sql.SqlIdentifier;
3132
import org.springframework.data.util.Pair;
@@ -54,6 +55,7 @@
5455
* @author Oliver Drotbohm
5556
* @author Roman Chigvintsev
5657
* @author Jens Schauder
58+
* @author Christoph Strobl
5759
* @since 2.0
5860
*/
5961
public class Criteria implements CriteriaDefinition {
@@ -157,6 +159,17 @@ public static CriteriaStep where(String column) {
157159
return new DefaultCriteriaStep(SqlIdentifier.unquoted(column));
158160
}
159161

162+
/**
163+
* Static factory method to create a Criteria using the provided {@code path}.
164+
*
165+
* @param property Must not be {@literal null}.
166+
* @return a new {@link CriteriaStep} object to complete the first {@link Criteria}.
167+
* @since 4.1
168+
*/
169+
public static <T, P> CriteriaStep where(TypedPropertyPath<T,P> property) {
170+
return where(TypedPropertyPath.of(property).toDotPath());
171+
}
172+
160173
/**
161174
* Create a new {@link Criteria} and combine it with {@code AND} using the provided {@code column} name.
162175
*
@@ -177,6 +190,18 @@ protected Criteria createCriteria(Comparator comparator, @Nullable Object value)
177190
};
178191
}
179192

193+
/**
194+
* Create a new {@link Criteria} and combine it with {@code AND} using the provided {@code path}.
195+
*
196+
* @param property Must not be {@literal null}.
197+
* @return a new {@link CriteriaStep} object to complete the next {@link Criteria}.
198+
* @since 4.1
199+
*/
200+
@CheckReturnValue
201+
public <T,P> CriteriaStep and(TypedPropertyPath<T,P> property) {
202+
return and(TypedPropertyPath.of(property).toDotPath());
203+
}
204+
180205
/**
181206
* Create a new {@link Criteria} and combine it as group with {@code AND} using the provided {@link Criteria} group.
182207
*
@@ -227,6 +252,18 @@ protected Criteria createCriteria(Comparator comparator, @Nullable Object value)
227252
};
228253
}
229254

255+
/**
256+
* Create a new {@link Criteria} and combine it with {@code OR} using the provided {@code path}.
257+
*
258+
* @param property Must not be {@literal null}.
259+
* @return a new {@link CriteriaStep} object to complete the next {@link Criteria}.
260+
* @since 4.1
261+
*/
262+
@CheckReturnValue
263+
public <T,P> CriteriaStep or(TypedPropertyPath<T,P> property) {
264+
return or(TypedPropertyPath.of(property).toDotPath());
265+
}
266+
230267
/**
231268
* Create a new {@link Criteria} and combine it as group with {@code OR} using the provided {@link Criteria} group.
232269
*

spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Query.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222
import java.util.List;
2323
import java.util.Optional;
2424
import java.util.stream.Collectors;
25+
import java.util.stream.Stream;
2526

2627
import org.jspecify.annotations.Nullable;
28+
import org.springframework.data.core.TypedPropertyPath;
2729
import org.springframework.data.domain.Pageable;
2830
import org.springframework.data.domain.Sort;
2931
import org.springframework.data.relational.core.sql.SqlIdentifier;
@@ -35,6 +37,7 @@
3537
* class are designed to be used in a fluent style creating immutable objects.
3638
*
3739
* @author Mark Paluch
40+
* @author Christoph Strobl
3841
* @since 2.0
3942
* @see Criteria
4043
* @see Sort
@@ -114,7 +117,19 @@ public Query columns(Collection<String> columns) {
114117

115118
Assert.notNull(columns, "Columns must not be null");
116119

117-
return withColumns(columns.stream().map(SqlIdentifier::unquoted).collect(Collectors.toList()));
120+
return withColumns(columns.stream());
121+
}
122+
123+
/**
124+
* Add columns to the query.
125+
*
126+
* @param properties
127+
* @return a new {@link Query} object containing the former settings with {@code columns} applied.
128+
* @since 4.1
129+
*/
130+
@CheckReturnValue
131+
public <T> Query columnsOf(Collection<TypedPropertyPath<T,?>> properties) {
132+
return withColumns(properties.stream().map(TypedPropertyPath::of).map(TypedPropertyPath::toDotPath));
118133
}
119134

120135
/**
@@ -132,6 +147,10 @@ public Query columns(SqlIdentifier... columns) {
132147
return withColumns(Arrays.asList(columns));
133148
}
134149

150+
private Query withColumns(Stream<String> columns) {
151+
return withColumns(columns.map(SqlIdentifier::unquoted).collect(Collectors.toList()));
152+
}
153+
135154
/**
136155
* Add columns to the query.
137156
*

spring-data-relational/src/main/java/org/springframework/data/relational/core/query/Update.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.StringJoiner;
2222

2323
import org.jspecify.annotations.Nullable;
24+
import org.springframework.data.core.TypedPropertyPath;
2425
import org.springframework.data.relational.core.sql.IdentifierProcessing;
2526
import org.springframework.data.relational.core.sql.SqlIdentifier;
2627
import org.springframework.lang.CheckReturnValue;
@@ -32,6 +33,7 @@
3233
*
3334
* @author Mark Paluch
3435
* @author Oliver Drotbohm
36+
* @author Christoph Strobl
3537
* @since 2.0
3638
*/
3739
public class Update {
@@ -65,6 +67,18 @@ public static Update update(String column, @Nullable Object value) {
6567
return EMPTY.set(column, value);
6668
}
6769

70+
/**
71+
* Static factory method to create an {@link Update} using the provided path.
72+
*
73+
* @param property must not be {@literal null}.
74+
* @param value can be {@literal null}.
75+
* @return new instance of {@link Update}.
76+
* @since 4.1
77+
*/
78+
public static <T,P> Update update(TypedPropertyPath<T,P> property, @Nullable Object value) {
79+
return update(TypedPropertyPath.of(property).toDotPath(), value);
80+
}
81+
6882
/**
6983
* Update a column by assigning a value.
7084
*
@@ -80,6 +94,19 @@ public Update set(String column, @Nullable Object value) {
8094
return addMultiFieldOperation(SqlIdentifier.unquoted(column), value);
8195
}
8296

97+
/**
98+
* Update a path by assigning a value.
99+
*
100+
* @param property must not be {@literal null}.
101+
* @param value can be {@literal null}.
102+
* @return new instance of {@link Update}.
103+
* @since 4.1
104+
*/
105+
@CheckReturnValue
106+
public <T,P> Update set(TypedPropertyPath<T,P> property, @Nullable Object value) {
107+
return set(TypedPropertyPath.of(property).toDotPath(), value);
108+
}
109+
83110
/**
84111
* Update a column by assigning a value.
85112
*

spring-data-relational/src/test/java/org/springframework/data/relational/core/query/UpdateUnitTests.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
* Unit tests for {@link Update}.
2424
*
2525
* @author Mark Paluch
26+
* @author Christoph Strobl
2627
*/
2728
public class UpdateUnitTests {
2829

@@ -31,4 +32,22 @@ public void shouldRenderUpdateToString() {
3132

3233
assertThat(Update.update("foo", "baz").set("bar", 42)).hasToString("SET foo = 'baz', bar = 42");
3334
}
35+
36+
@Test // GH-2226
37+
public void shouldRenderUpdateWithTypedPropertyPathToString() {
38+
assertThat(Update.update(Person::getFirstName, "baz").set("bar", 42)).hasToString("SET firstName = 'baz', bar = 42");
39+
}
40+
41+
static class Person {
42+
private String firstName;
43+
private String lastName;
44+
45+
public String getFirstName() {
46+
return firstName;
47+
}
48+
49+
public String getLastName() {
50+
return lastName;
51+
}
52+
}
3453
}

0 commit comments

Comments
 (0)