Skip to content

Commit 80e6870

Browse files
committed
#220 - Refactor StatementMapper.
Use limit/offset instead of Page and accept Expression objects to declare a select list.
1 parent 603cec1 commit 80e6870

File tree

2 files changed

+117
-25
lines changed

2 files changed

+117
-25
lines changed

Diff for: src/main/java/org/springframework/data/r2dbc/core/DefaultStatementMapper.java

+24-8
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import java.util.Collection;
2020
import java.util.List;
2121

22-
import org.springframework.data.domain.Pageable;
2322
import org.springframework.data.domain.Sort;
2423
import org.springframework.data.mapping.context.MappingContext;
2524
import org.springframework.data.r2dbc.dialect.BindMarkers;
@@ -84,9 +83,9 @@ public PreparedOperation<?> getMappedObject(SelectSpec selectSpec) {
8483
private PreparedOperation<Select> getMappedObject(SelectSpec selectSpec,
8584
@Nullable RelationalPersistentEntity<?> entity) {
8685

87-
Table table = Table.create(toSql(selectSpec.getTable()));
88-
List<Column> columns = table.columns(toSql(selectSpec.getProjectedFields()));
89-
SelectBuilder.SelectFromAndJoin selectBuilder = StatementBuilder.select(columns).from(table);
86+
Table table = selectSpec.getTable();
87+
SelectBuilder.SelectFromAndJoin selectBuilder = StatementBuilder.select(getSelectList(selectSpec, entity))
88+
.from(table);
9089

9190
BindMarkers bindMarkers = this.dialect.getBindMarkersFactory().create();
9291
Bindings bindings = Bindings.empty();
@@ -106,17 +105,34 @@ private PreparedOperation<Select> getMappedObject(SelectSpec selectSpec,
106105
selectBuilder.orderBy(createOrderByFields(table, mappedSort));
107106
}
108107

109-
if (selectSpec.getPage().isPaged()) {
110-
111-
Pageable page = selectSpec.getPage();
108+
if (selectSpec.getLimit() > 0) {
109+
selectBuilder.limit(selectSpec.getLimit());
110+
}
112111

113-
selectBuilder.limitOffset(page.getPageSize(), page.getOffset());
112+
if (selectSpec.getOffset() > 0) {
113+
selectBuilder.offset(selectSpec.getOffset());
114114
}
115115

116116
Select select = selectBuilder.build();
117117
return new DefaultPreparedOperation<>(select, this.renderContext, bindings);
118118
}
119119

120+
protected List<Expression> getSelectList(SelectSpec selectSpec, @Nullable RelationalPersistentEntity<?> entity) {
121+
122+
if (entity == null) {
123+
return selectSpec.getSelectList();
124+
}
125+
126+
List<Expression> selectList = selectSpec.getSelectList();
127+
List<Expression> mapped = new ArrayList<>(selectList.size());
128+
129+
for (Expression expression : selectList) {
130+
mapped.add(updateMapper.getMappedObject(expression, entity));
131+
}
132+
133+
return mapped;
134+
}
135+
120136
private Collection<? extends OrderByField> createOrderByFields(Table table, Sort sortToUse) {
121137

122138
List<OrderByField> fields = new ArrayList<>();

Diff for: src/main/java/org/springframework/data/r2dbc/core/StatementMapper.java

+93-17
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.LinkedHashMap;
2323
import java.util.List;
2424
import java.util.Map;
25+
import java.util.function.BiFunction;
2526
import java.util.stream.Collectors;
2627

2728
import org.springframework.data.domain.Pageable;
@@ -30,6 +31,9 @@
3031
import org.springframework.data.r2dbc.mapping.SettableValue;
3132
import org.springframework.data.r2dbc.query.Criteria;
3233
import org.springframework.data.r2dbc.query.Update;
34+
import org.springframework.data.relational.core.sql.Column;
35+
import org.springframework.data.relational.core.sql.Expression;
36+
import org.springframework.data.relational.core.sql.Table;
3337
import org.springframework.data.relational.core.sql.SqlIdentifier;
3438
import org.springframework.lang.Nullable;
3539

@@ -179,19 +183,23 @@ default DeleteSpec createDelete(SqlIdentifier table) {
179183
*/
180184
class SelectSpec {
181185

182-
private final SqlIdentifier table;
183-
private final List<SqlIdentifier> projectedFields;
186+
private final Table table;
187+
private final List<String> projectedFields;
188+
private final List<Expression> selectList;
184189
private final @Nullable Criteria criteria;
185190
private final Sort sort;
186-
private final Pageable page;
191+
private final long offset;
192+
private final int limit;
187193

188-
protected SelectSpec(SqlIdentifier table, List<SqlIdentifier> projectedFields, @Nullable Criteria criteria,
189-
Sort sort, Pageable page) {
194+
protected SelectSpec(Table table, List<String> projectedFields, List<Expression> selectList,
195+
@Nullable Criteria criteria, Sort sort, int limit, long offset) {
190196
this.table = table;
191197
this.projectedFields = projectedFields;
198+
this.selectList = selectList;
192199
this.criteria = criteria;
193200
this.sort = sort;
194-
this.page = page;
201+
this.offset = offset;
202+
this.limit = limit;
195203
}
196204

197205
/**
@@ -212,7 +220,23 @@ public static SelectSpec create(String table) {
212220
* @since 1.1
213221
*/
214222
public static SelectSpec create(SqlIdentifier table) {
215-
return new SelectSpec(table, Collections.emptyList(), null, Sort.unsorted(), Pageable.unpaged());
223+
return new SelectSpec(Table.create(table), Collections.emptyList(), Collections.emptyList(), null,
224+
Sort.unsorted(), -1, -1);
225+
}
226+
227+
public SelectSpec doWithTable(BiFunction<Table, SelectSpec, SelectSpec> function) {
228+
return function.apply(getTable(), this);
229+
}
230+
231+
/**
232+
* Associate {@code projectedFields} with the select and create a new {@link SelectSpec}.
233+
*
234+
* @param projectedFields
235+
* @return the {@link SelectSpec}.
236+
* @since 1.1
237+
*/
238+
public SelectSpec withProjection(String... projectedFields) {
239+
return withProjection(Arrays.asList(projectedFields));
216240
}
217241

218242
/**
@@ -237,7 +261,25 @@ public SelectSpec withProjection(Collection<SqlIdentifier> projectedFields) {
237261
List<SqlIdentifier> fields = new ArrayList<>(this.projectedFields);
238262
fields.addAll(projectedFields);
239263

240-
return new SelectSpec(this.table, fields, this.criteria, this.sort, this.page);
264+
List<Expression> selectList = new ArrayList<>(this.selectList);
265+
projectedFields.stream().map(s -> Column.create(s, table)).forEach(selectList::add);
266+
267+
return new SelectSpec(this.table, fields, selectList, this.criteria, this.sort, this.limit, this.offset);
268+
}
269+
270+
/**
271+
* Associate {@code expressions} with the select list and create a new {@link SelectSpec}.
272+
*
273+
* @param expressions
274+
* @return the {@link SelectSpec}.
275+
* @since 1.1
276+
*/
277+
public SelectSpec withProjection(Expression... expressions) {
278+
279+
List<Expression> selectList = new ArrayList<>(this.selectList);
280+
selectList.addAll(Arrays.asList(expressions));
281+
282+
return new SelectSpec(this.table, projectedFields, selectList, this.criteria, this.sort, this.limit, this.offset);
241283
}
242284

243285
/**
@@ -247,7 +289,8 @@ public SelectSpec withProjection(Collection<SqlIdentifier> projectedFields) {
247289
* @return the {@link SelectSpec}.
248290
*/
249291
public SelectSpec withCriteria(Criteria criteria) {
250-
return new SelectSpec(this.table, this.projectedFields, criteria, this.sort, this.page);
292+
return new SelectSpec(this.table, this.projectedFields, this.selectList, criteria, this.sort, this.limit,
293+
this.offset);
251294
}
252295

253296
/**
@@ -259,10 +302,12 @@ public SelectSpec withCriteria(Criteria criteria) {
259302
public SelectSpec withSort(Sort sort) {
260303

261304
if (sort.isSorted()) {
262-
return new SelectSpec(this.table, this.projectedFields, this.criteria, sort, this.page);
305+
return new SelectSpec(this.table, this.projectedFields, this.selectList, this.criteria, sort, this.limit,
306+
this.offset);
263307
}
264308

265-
return new SelectSpec(this.table, this.projectedFields, this.criteria, this.sort, this.page);
309+
return new SelectSpec(this.table, this.projectedFields, this.selectList, this.criteria, this.sort, this.limit,
310+
this.offset);
266311
}
267312

268313
/**
@@ -277,21 +322,48 @@ public SelectSpec withPage(Pageable page) {
277322

278323
Sort sort = page.getSort();
279324

280-
return new SelectSpec(this.table, this.projectedFields, this.criteria, sort.isSorted() ? sort : this.sort,
281-
page);
325+
return new SelectSpec(this.table, this.projectedFields, this.selectList, this.criteria,
326+
sort.isSorted() ? sort : this.sort, page.getPageSize(), page.getOffset());
282327
}
283328

284-
return new SelectSpec(this.table, this.projectedFields, this.criteria, this.sort, page);
329+
return new SelectSpec(this.table, this.projectedFields, this.selectList, this.criteria, this.sort, this.limit,
330+
this.offset);
285331
}
286332

287-
public SqlIdentifier getTable() {
333+
/**
334+
* Associate a result offset with the select and create a new {@link SelectSpec}.
335+
*
336+
* @param page
337+
* @return the {@link SelectSpec}.
338+
*/
339+
public SelectSpec offset(long offset) {
340+
return new SelectSpec(this.table, this.projectedFields, this.selectList, this.criteria, this.sort, this.limit,
341+
offset);
342+
}
343+
344+
/**
345+
* Associate a result limit with the select and create a new {@link SelectSpec}.
346+
*
347+
* @param page
348+
* @return the {@link SelectSpec}.
349+
*/
350+
public SelectSpec limit(int limit) {
351+
return new SelectSpec(this.table, this.projectedFields, this.selectList, this.criteria, this.sort, limit,
352+
this.offset);
353+
}
354+
355+
public Table getTable() {
288356
return this.table;
289357
}
290358

291359
public List<SqlIdentifier> getProjectedFields() {
292360
return Collections.unmodifiableList(this.projectedFields);
293361
}
294362

363+
public List<Expression> getSelectList() {
364+
return Collections.unmodifiableList(selectList);
365+
}
366+
295367
@Nullable
296368
public Criteria getCriteria() {
297369
return this.criteria;
@@ -301,8 +373,12 @@ public Sort getSort() {
301373
return this.sort;
302374
}
303375

304-
public Pageable getPage() {
305-
return this.page;
376+
public long getOffset() {
377+
return this.offset;
378+
}
379+
380+
public int getLimit() {
381+
return this.limit;
306382
}
307383
}
308384

0 commit comments

Comments
 (0)