15
15
*/
16
16
package org .springframework .data .r2dbc .repository .query ;
17
17
18
+ import java .util .ArrayList ;
18
19
import java .util .List ;
19
20
import java .util .stream .Collectors ;
20
21
32
33
import org .springframework .data .relational .repository .query .RelationalQueryCreator ;
33
34
import org .springframework .data .repository .query .parser .AbstractQueryCreator ;
34
35
import org .springframework .data .repository .query .parser .PartTree ;
35
- import org .springframework .util . Assert ;
36
+ import org .springframework .lang . Nullable ;
36
37
37
38
/**
38
39
* Implementation of {@link AbstractQueryCreator} that creates {@link PreparedOperation} from a {@link PartTree}.
42
43
* @author Mingyuan Wu
43
44
* @since 1.1
44
45
*/
45
- public class R2dbcQueryCreator extends RelationalQueryCreator <PreparedOperation <?>> {
46
+ class R2dbcQueryCreator extends RelationalQueryCreator <PreparedOperation <?>> {
46
47
47
48
private final PartTree tree ;
48
49
private final RelationalParameterAccessor accessor ;
49
50
private final ReactiveDataAccessStrategy dataAccessStrategy ;
50
51
private final RelationalEntityMetadata <?> entityMetadata ;
52
+ private final List <String > projectedProperties ;
51
53
52
54
/**
53
55
* Creates new instance of this class with the given {@link PartTree}, {@link ReactiveDataAccessStrategy},
54
56
* {@link RelationalEntityMetadata} and {@link RelationalParameterAccessor}.
55
- *
57
+ *
56
58
* @param tree part tree, must not be {@literal null}.
57
59
* @param dataAccessStrategy data access strategy, must not be {@literal null}.
58
60
* @param entityMetadata relational entity metadata, must not be {@literal null}.
59
61
* @param accessor parameter metadata provider, must not be {@literal null}.
62
+ * @param projectedProperties properties to project, must not be {@literal null}.
60
63
*/
61
64
public R2dbcQueryCreator (PartTree tree , ReactiveDataAccessStrategy dataAccessStrategy ,
62
- RelationalEntityMetadata <?> entityMetadata , RelationalParameterAccessor accessor ) {
65
+ RelationalEntityMetadata <?> entityMetadata , RelationalParameterAccessor accessor ,
66
+ List <String > projectedProperties ) {
63
67
super (tree , accessor );
64
68
65
- Assert .notNull (dataAccessStrategy , "Data access strategy must not be null" );
66
- Assert .notNull (entityMetadata , "Relational entity metadata must not be null" );
67
-
68
69
this .tree = tree ;
69
70
this .accessor = accessor ;
70
71
71
72
this .dataAccessStrategy = dataAccessStrategy ;
72
73
this .entityMetadata = entityMetadata ;
74
+ this .projectedProperties = projectedProperties ;
73
75
}
74
76
75
77
/**
@@ -80,7 +82,7 @@ public R2dbcQueryCreator(PartTree tree, ReactiveDataAccessStrategy dataAccessStr
80
82
* @return instance of {@link PreparedOperation}
81
83
*/
82
84
@ Override
83
- protected PreparedOperation <?> complete (Criteria criteria , Sort sort ) {
85
+ protected PreparedOperation <?> complete (@ Nullable Criteria criteria , Sort sort ) {
84
86
85
87
StatementMapper statementMapper = dataAccessStrategy .getStatementMapper ().forType (entityMetadata .getJavaType ());
86
88
@@ -91,15 +93,15 @@ protected PreparedOperation<?> complete(Criteria criteria, Sort sort) {
91
93
return select (criteria , sort , statementMapper );
92
94
}
93
95
94
- private PreparedOperation <?> delete (Criteria criteria , StatementMapper statementMapper ) {
96
+ private PreparedOperation <?> delete (@ Nullable Criteria criteria , StatementMapper statementMapper ) {
95
97
96
98
StatementMapper .DeleteSpec deleteSpec = statementMapper .createDelete (entityMetadata .getTableName ())
97
99
.withCriteria (criteria );
98
100
99
101
return statementMapper .getMappedObject (deleteSpec );
100
102
}
101
103
102
- private PreparedOperation <?> select (Criteria criteria , Sort sort , StatementMapper statementMapper ) {
104
+ private PreparedOperation <?> select (@ Nullable Criteria criteria , Sort sort , StatementMapper statementMapper ) {
103
105
104
106
StatementMapper .SelectSpec selectSpec = statementMapper .createSelect (entityMetadata .getTableName ())
105
107
.withProjection (getSelectProjection ());
@@ -123,8 +125,8 @@ private PreparedOperation<?> select(Criteria criteria, Sort sort, StatementMappe
123
125
selectSpec = selectSpec .withSort (getSort (sort ));
124
126
}
125
127
126
- if (tree .isDistinct ()){
127
- selectSpec = selectSpec .distinct (true );
128
+ if (tree .isDistinct ()) {
129
+ selectSpec = selectSpec .distinct ();
128
130
}
129
131
130
132
return statementMapper .getMappedObject (selectSpec );
@@ -134,7 +136,18 @@ private SqlIdentifier[] getSelectProjection() {
134
136
135
137
List <SqlIdentifier > columnNames ;
136
138
137
- if (tree .isExistsProjection ()) {
139
+ if (!projectedProperties .isEmpty ()) {
140
+
141
+ RelationalPersistentEntity <?> entity = entityMetadata .getTableEntity ();
142
+ columnNames = new ArrayList <>(projectedProperties .size ());
143
+
144
+ for (String projectedProperty : projectedProperties ) {
145
+
146
+ RelationalPersistentProperty property = entity .getPersistentProperty (projectedProperty );
147
+ columnNames .add (property != null ? property .getColumnName () : SqlIdentifier .unquoted (projectedProperty ));
148
+ }
149
+
150
+ } else if (tree .isExistsProjection ()) {
138
151
columnNames = dataAccessStrategy .getIdentifierColumns (entityMetadata .getJavaType ());
139
152
} else {
140
153
columnNames = dataAccessStrategy .getAllColumns (entityMetadata .getJavaType ());
0 commit comments