Skip to content

Commit ec437a0

Browse files
committed
Make the SelectDSL generic to support expressive by example methods
1 parent 24a0fb7 commit ec437a0

File tree

9 files changed

+169
-107
lines changed

9 files changed

+169
-107
lines changed

src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,11 @@ static InsertSelectDSL.InsertColumnGatherer insertInto(SqlTable table) {
9494
return InsertSelectDSL.insertInto(table);
9595
}
9696

97-
static QueryExpressionDSL select(BasicColumn...selectList) {
97+
static QueryExpressionDSL<SelectModel> select(BasicColumn...selectList) {
9898
return SelectDSL.select(selectList);
9999
}
100100

101-
static QueryExpressionDSL selectDistinct(BasicColumn...selectList) {
101+
static QueryExpressionDSL<SelectModel> selectDistinct(BasicColumn...selectList) {
102102
return SelectDSL.selectDistinct(selectList);
103103
}
104104

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* Copyright 2016-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.mybatis.dynamic.sql.select;
17+
18+
import java.util.function.Function;
19+
20+
import org.mybatis.dynamic.sql.render.RenderingStrategy;
21+
import org.mybatis.dynamic.sql.select.render.SelectStatement;
22+
23+
/**
24+
* This SelectModel will render the underlying select model for MyBatis3, and then call a MyBatis mapper method.
25+
*
26+
* @author Jeff Butler
27+
*
28+
*/
29+
public class MyBatis3SelectModel<R> {
30+
31+
private SelectModel selectModel;
32+
private Function<SelectStatement, R> mapperMethod;
33+
34+
private MyBatis3SelectModel(SelectModel selectModel, Function<SelectStatement, R> mapperMethod) {
35+
this.selectModel = selectModel;
36+
this.mapperMethod = mapperMethod;
37+
}
38+
39+
public R execute() {
40+
return mapperMethod.apply(selectModel.render(RenderingStrategy.MYBATIS3));
41+
}
42+
43+
public static <R> MyBatis3SelectModel<R> of(SelectModel selectModel, Function<SelectStatement, R> mapperMethod) {
44+
return new MyBatis3SelectModel<>(selectModel, mapperMethod);
45+
}
46+
}

src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@
3737
import org.mybatis.dynamic.sql.where.AbstractWhereDSL;
3838
import org.mybatis.dynamic.sql.where.WhereModel;
3939

40-
public class QueryExpressionDSL {
40+
public class QueryExpressionDSL<R> {
4141

4242
private String connector;
43-
private SelectDSL selectModelBuilder;
43+
private SelectDSL<R> selectModelBuilder;
4444
private boolean isDistinct;
4545
private List<BasicColumn> selectList;
4646
private SqlTable table;
@@ -50,7 +50,7 @@ public class QueryExpressionDSL {
5050
private JoinModel joinModel;
5151
private List<JoinSpecification> joinSpecifications = new ArrayList<>();
5252

53-
private QueryExpressionDSL(Builder builder) {
53+
private QueryExpressionDSL(Builder<R> builder) {
5454
connector = builder.connector;
5555
selectList = Arrays.asList(builder.selectList);
5656
isDistinct = builder.isDistinct;
@@ -68,34 +68,34 @@ public QueryExpressionAfterFrom from(SqlTable table, String tableAlias) {
6868
return new QueryExpressionAfterFrom();
6969
}
7070

71-
public static class Builder {
71+
public static class Builder<R> {
7272
private String connector;
7373
private BasicColumn[] selectList;
7474
private boolean isDistinct;
75-
private SelectDSL selectModelBuilder;
75+
private SelectDSL<R> selectModelBuilder;
7676

77-
public Builder withConnector(String connector) {
77+
public Builder<R> withConnector(String connector) {
7878
this.connector = connector;
7979
return this;
8080
}
8181

82-
public Builder withSelectList(BasicColumn...selectList) {
82+
public Builder<R> withSelectList(BasicColumn...selectList) {
8383
this.selectList = selectList;
8484
return this;
8585
}
8686

87-
public Builder isDistinct() {
87+
public Builder<R> isDistinct() {
8888
this.isDistinct = true;
8989
return this;
9090
}
9191

92-
public Builder withSelectModelBuilder(SelectDSL selectModelBuilder) {
92+
public Builder<R> withSelectModelBuilder(SelectDSL<R> selectModelBuilder) {
9393
this.selectModelBuilder = selectModelBuilder;
9494
return this;
9595
}
9696

97-
public QueryExpressionDSL build() {
98-
return new QueryExpressionDSL(this);
97+
public QueryExpressionDSL<R> build() {
98+
return new QueryExpressionDSL<>(this);
9999
}
100100
}
101101

@@ -112,7 +112,7 @@ protected QueryExpressionModel buildModel() {
112112
.build();
113113
}
114114

115-
public class QueryExpressionAfterFrom implements Buildable<SelectModel> {
115+
public class QueryExpressionAfterFrom implements Buildable<R> {
116116
private QueryExpressionAfterFrom() {
117117
super();
118118
}
@@ -127,7 +127,7 @@ public <T> QueryExpressionWhereBuilder where(BindableColumn<T> column, Visitable
127127
}
128128

129129
@Override
130-
public SelectModel build() {
130+
public R build() {
131131
selectModelBuilder.addQueryExpression(buildModel());
132132
return selectModelBuilder.build();
133133
}
@@ -174,7 +174,7 @@ public GroupByFinisher groupBy(BasicColumn...columns) {
174174
return new GroupByFinisher();
175175
}
176176

177-
public SelectDSL orderBy(SortSpecification...columns) {
177+
public SelectDSL<R> orderBy(SortSpecification...columns) {
178178
selectModelBuilder.addQueryExpression(buildModel());
179179
selectModelBuilder.setOrderByModel(OrderByModel.of(columns));
180180
return selectModelBuilder;
@@ -187,7 +187,7 @@ public UnionBuilder union() {
187187
}
188188

189189
public class QueryExpressionWhereBuilder extends AbstractWhereDSL<QueryExpressionWhereBuilder>
190-
implements Buildable<SelectModel> {
190+
implements Buildable<R> {
191191
private <T> QueryExpressionWhereBuilder(BindableColumn<T> column, VisitableCondition<T> condition) {
192192
super(column, condition);
193193
}
@@ -203,15 +203,15 @@ public UnionBuilder union() {
203203
return new UnionBuilder();
204204
}
205205

206-
public SelectDSL orderBy(SortSpecification...columns) {
206+
public SelectDSL<R> orderBy(SortSpecification...columns) {
207207
whereModel = buildWhereModel();
208208
selectModelBuilder.addQueryExpression(buildModel());
209209
selectModelBuilder.setOrderByModel(OrderByModel.of(columns));
210210
return selectModelBuilder;
211211
}
212212

213213
@Override
214-
public SelectModel build() {
214+
public R build() {
215215
whereModel = buildWhereModel();
216216
selectModelBuilder.addQueryExpression(buildModel());
217217
return selectModelBuilder.build();
@@ -242,7 +242,7 @@ public JoinSpecificationFinisher on(BasicColumn joinColumn, JoinCondition joinCo
242242
}
243243
}
244244

245-
public class JoinSpecificationFinisher implements Buildable<SelectModel> {
245+
public class JoinSpecificationFinisher implements Buildable<R> {
246246

247247
private SqlTable joinTable;
248248
private List<JoinCriterion> joinCriteria = new ArrayList<>();
@@ -291,7 +291,7 @@ protected JoinModel buildJoinModel() {
291291
}
292292

293293
@Override
294-
public SelectModel build() {
294+
public R build() {
295295
joinModel = buildJoinModel();
296296
selectModelBuilder.addQueryExpression(buildModel());
297297
return selectModelBuilder.build();
@@ -358,37 +358,37 @@ public JoinSpecificationStarter fullJoin(SqlTable joinTable, String tableAlias)
358358
return fullJoin(joinTable);
359359
}
360360

361-
public SelectDSL orderBy(SortSpecification...columns) {
361+
public SelectDSL<R> orderBy(SortSpecification...columns) {
362362
joinModel = buildJoinModel();
363363
selectModelBuilder.addQueryExpression(buildModel());
364364
selectModelBuilder.setOrderByModel(OrderByModel.of(columns));
365365
return selectModelBuilder;
366366
}
367367
}
368368

369-
public class GroupByFinisher implements Buildable<SelectModel> {
370-
public SelectDSL orderBy(SortSpecification...columns) {
369+
public class GroupByFinisher implements Buildable<R> {
370+
public SelectDSL<R> orderBy(SortSpecification...columns) {
371371
selectModelBuilder.setOrderByModel(OrderByModel.of(columns));
372372
return selectModelBuilder;
373373
}
374374

375375
@Override
376-
public SelectModel build() {
376+
public R build() {
377377
return selectModelBuilder.build();
378378
}
379379
}
380380

381381
public class UnionBuilder {
382-
public QueryExpressionDSL select(BasicColumn...selectList) {
383-
return new QueryExpressionDSL.Builder()
382+
public QueryExpressionDSL<R> select(BasicColumn...selectList) {
383+
return new QueryExpressionDSL.Builder<R>()
384384
.withConnector("union") //$NON-NLS-1$
385385
.withSelectList(selectList)
386386
.withSelectModelBuilder(selectModelBuilder)
387387
.build();
388388
}
389389

390-
public QueryExpressionDSL selectDistinct(BasicColumn...selectList) {
391-
return new QueryExpressionDSL.Builder()
390+
public QueryExpressionDSL<R> selectDistinct(BasicColumn...selectList) {
391+
return new QueryExpressionDSL.Builder<R>()
392392
.withConnector("union") //$NON-NLS-1$
393393
.withSelectList(selectList)
394394
.isDistinct()

src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,43 +17,74 @@
1717

1818
import java.util.ArrayList;
1919
import java.util.List;
20+
import java.util.Objects;
21+
import java.util.function.Function;
2022

2123
import org.mybatis.dynamic.sql.BasicColumn;
24+
import org.mybatis.dynamic.sql.select.render.SelectStatement;
2225

23-
public class SelectDSL {
26+
/**
27+
* Implements a standard SQL dialect for building model classes.
28+
*
29+
* @author Jeff Butler
30+
*
31+
* @param <R> the type of model produced by this builder
32+
*/
33+
public class SelectDSL<R> {
2434

35+
private Function<SelectModel, R> decoratorFunction;
2536
private List<QueryExpressionModel> queryExpressions = new ArrayList<>();
2637
private OrderByModel orderByModel;
2738

28-
private SelectDSL() {
29-
super();
39+
private SelectDSL(Function<SelectModel, R> decoratorFunction) {
40+
this.decoratorFunction = Objects.requireNonNull(decoratorFunction);
3041
}
3142

32-
private QueryExpressionDSL queryExpressionBuilder(BasicColumn...selectList) {
33-
return new QueryExpressionDSL.Builder()
43+
private QueryExpressionDSL<R> queryExpressionBuilder(BasicColumn...selectList) {
44+
return new QueryExpressionDSL.Builder<R>()
3445
.withSelectList(selectList)
3546
.withSelectModelBuilder(this)
3647
.build();
3748
}
3849

39-
private QueryExpressionDSL distinctQueryExpressionBuilder(BasicColumn...selectList) {
40-
return new QueryExpressionDSL.Builder()
50+
private QueryExpressionDSL<R> distinctQueryExpressionBuilder(BasicColumn...selectList) {
51+
return new QueryExpressionDSL.Builder<R>()
4152
.withSelectList(selectList)
4253
.isDistinct()
4354
.withSelectModelBuilder(this)
4455
.build();
4556
}
4657

47-
public static QueryExpressionDSL select(BasicColumn...selectList) {
48-
SelectDSL selectModelBuilder = new SelectDSL();
58+
public static <R> QueryExpressionDSL<R> genericSelect(Function<SelectModel, R> decoratorFunction, BasicColumn...selectList) {
59+
SelectDSL<R> selectModelBuilder = new SelectDSL<>(decoratorFunction);
4960
return selectModelBuilder.queryExpressionBuilder(selectList);
5061
}
5162

52-
public static QueryExpressionDSL selectDistinct(BasicColumn...selectList) {
53-
SelectDSL selectModelBuilder = new SelectDSL();
63+
public static <R> QueryExpressionDSL<R> genericSelectDistinct(Function<SelectModel, R> decoratorFunction, BasicColumn...selectList) {
64+
SelectDSL<R> selectModelBuilder = new SelectDSL<>(decoratorFunction);
5465
return selectModelBuilder.distinctQueryExpressionBuilder(selectList);
5566
}
5667

68+
public static QueryExpressionDSL<SelectModel> select(BasicColumn...selectList) {
69+
return genericSelect(Function.identity(), selectList);
70+
}
71+
72+
public static <T> QueryExpressionDSL<MyBatis3SelectModel<T>> select(Function<SelectStatement, T> mapperMethod, BasicColumn...selectList) {
73+
return genericSelect(decorate(mapperMethod), selectList);
74+
}
75+
76+
public static QueryExpressionDSL<SelectModel> selectDistinct(BasicColumn...selectList) {
77+
return genericSelectDistinct(Function.identity(), selectList);
78+
}
79+
80+
public static <T> QueryExpressionDSL<MyBatis3SelectModel<T>> selectDistinct(Function<SelectStatement, T> mapperMethod, BasicColumn...selectList) {
81+
return genericSelectDistinct(decorate(mapperMethod), selectList);
82+
}
83+
84+
private static <T> Function<SelectModel, MyBatis3SelectModel<T>> decorate(Function<SelectStatement, T> mapperMethod) {
85+
return selectModel -> MyBatis3SelectModel.of(selectModel, mapperMethod);
86+
}
87+
5788
void addQueryExpression(QueryExpressionModel queryExpression) {
5889
queryExpressions.add(queryExpression);
5990
}
@@ -62,10 +93,11 @@ void setOrderByModel(OrderByModel orderByModel) {
6293
this.orderByModel = orderByModel;
6394
}
6495

65-
public SelectModel build() {
66-
return new SelectModel.Builder()
96+
public R build() {
97+
SelectModel selectModel = new SelectModel.Builder()
6798
.withQueryExpressions(queryExpressions)
6899
.withOrderByModel(orderByModel)
69100
.build();
101+
return decoratorFunction.apply(selectModel);
70102
}
71103
}

src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,16 @@ public R build() {
7171
return decoratorFunction.apply(updateModel);
7272
}
7373

74-
public static <R> UpdateDSL<R> genericUpdate(SqlTable table, Function<UpdateModel, R> decoratorFunction) {
74+
public static <R> UpdateDSL<R> genericUpdate(Function<UpdateModel, R> decoratorFunction, SqlTable table) {
7575
return new UpdateDSL<>(table, decoratorFunction);
7676
}
7777

7878
public static UpdateDSL<UpdateModel> update(SqlTable table) {
79-
return genericUpdate(table, Function.identity());
79+
return genericUpdate(Function.identity(), table);
8080
}
8181

82-
public static UpdateDSL<MyBatis3UpdateModel> update(SqlTable table, Function<UpdateStatement, Integer> mapperMethod) {
83-
return genericUpdate(table, decorate(mapperMethod));
82+
public static UpdateDSL<MyBatis3UpdateModel> update(Function<UpdateStatement, Integer> mapperMethod, SqlTable table) {
83+
return genericUpdate(decorate(mapperMethod), table);
8484
}
8585

8686
private static Function<UpdateModel, MyBatis3UpdateModel> decorate(Function<UpdateStatement, Integer> mapperMethod) {

src/test/java/examples/generated/always/mybatis/GeneratedAlwaysDynamicSqlSupport.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
import org.mybatis.dynamic.sql.SqlTable;
2424
import org.mybatis.dynamic.sql.insert.render.InsertStatement;
2525
import org.mybatis.dynamic.sql.render.RenderingStrategy;
26-
import org.mybatis.dynamic.sql.select.QueryExpressionDSL.QueryExpressionAfterFrom;
26+
import org.mybatis.dynamic.sql.select.QueryExpressionDSL;
27+
import org.mybatis.dynamic.sql.select.SelectModel;
2728
import org.mybatis.dynamic.sql.select.render.SelectStatement;
2829
import org.mybatis.dynamic.sql.update.UpdateDSL;
2930
import org.mybatis.dynamic.sql.update.UpdateModel;
@@ -101,7 +102,7 @@ public static UpdateDSL<UpdateModel> updateByExampleSelective(GeneratedAlwaysRec
101102
.set(lastName).equalToWhenPresent(record.getLastName());
102103
}
103104

104-
public static QueryExpressionAfterFrom selectByExample() {
105+
public static QueryExpressionDSL<SelectModel>.QueryExpressionAfterFrom selectByExample() {
105106
return select(id.as("A_ID"), firstName, lastName, fullName)
106107
.from(generatedAlways, "a");
107108
}

0 commit comments

Comments
 (0)