Skip to content

Commit 2889522

Browse files
committed
Refactoring to support future paging models
1 parent e332748 commit 2889522

File tree

10 files changed

+278
-68
lines changed

10 files changed

+278
-68
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,17 @@ protected SqlTable(Supplier<Optional<String>> schemaSupplier, String tableName)
4040
this(Optional::empty, schemaSupplier, tableName);
4141
}
4242

43-
protected SqlTable(Supplier<Optional<String>> catalogSupplier, Supplier<Optional<String>> schemaSupplier, String tableName) {
43+
protected SqlTable(Supplier<Optional<String>> catalogSupplier, Supplier<Optional<String>> schemaSupplier,
44+
String tableName) {
4445
Objects.requireNonNull(catalogSupplier);
4546
Objects.requireNonNull(schemaSupplier);
4647
Objects.requireNonNull(tableName);
4748

4849
this.nameSupplier = () -> compose(catalogSupplier, schemaSupplier, tableName);
4950
}
5051

51-
private String compose(Supplier<Optional<String>> catalogSupplier, Supplier<Optional<String>> schemaSupplier, String tableName) {
52+
private String compose(Supplier<Optional<String>> catalogSupplier, Supplier<Optional<String>> schemaSupplier,
53+
String tableName) {
5254
return catalogSupplier.get().map(c -> compose(c, schemaSupplier, tableName))
5355
.orElse(compose(schemaSupplier, tableName));
5456
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* Copyright 2016-2019 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.Optional;
19+
20+
public class LimitAndOffsetPagingModel implements PagingModel {
21+
22+
private Long limit;
23+
private Long offset;
24+
25+
private LimitAndOffsetPagingModel(Builder builder) {
26+
this.limit = builder.limit;
27+
this.offset = builder.offset;
28+
}
29+
30+
public Optional<Long> limit() {
31+
return Optional.ofNullable(limit);
32+
}
33+
34+
public Optional<Long> offset() {
35+
return Optional.ofNullable(offset);
36+
}
37+
38+
@Override
39+
public <R> R accept(PagingModelVisitor<R> visitor) {
40+
return visitor.visit(this);
41+
}
42+
43+
public static class Builder {
44+
private Long limit;
45+
private Long offset;
46+
47+
public Builder withLimit(Long limit) {
48+
this.limit = limit;
49+
return this;
50+
}
51+
52+
public Builder withOffset(Long offset) {
53+
this.offset = offset;
54+
return this;
55+
}
56+
57+
public LimitAndOffsetPagingModel build() {
58+
return new LimitAndOffsetPagingModel(this);
59+
}
60+
}
61+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* Copyright 2016-2019 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+
public interface PagingModel {
19+
<R> R accept(PagingModelVisitor<R> visitor);
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* Copyright 2016-2019 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+
public interface PagingModelVisitor<R> {
19+
R visit(LimitAndOffsetPagingModel pagingModel);
20+
}

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

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ public class SelectDSL<R> implements Buildable<R> {
3838
private Function<SelectModel, R> adapterFunction;
3939
private List<QueryExpressionModel> queryExpressions = new ArrayList<>();
4040
private OrderByModel orderByModel;
41-
private Long limit;
42-
private Long offset;
41+
private PagingModel pagingModel;
4342

4443
private SelectDSL(Function<SelectModel, R> adapterFunction) {
4544
this.adapterFunction = Objects.requireNonNull(adapterFunction);
@@ -100,39 +99,61 @@ void setOrderByModel(OrderByModel orderByModel) {
10099
}
101100

102101
public LimitFinisher limit(long limit) {
103-
this.limit = limit;
104-
return new LimitFinisher();
102+
return new LimitFinisher(limit);
105103
}
106104

107105
public OffsetFinisher offset(long offset) {
108-
this.offset = offset;
109-
return new OffsetFinisher();
106+
return new OffsetFinisher(offset);
110107
}
111108

112109
@Override
113110
public R build() {
114111
SelectModel selectModel = SelectModel.withQueryExpressions(queryExpressions)
115112
.withOrderByModel(orderByModel)
116-
.withLimit(limit)
117-
.withOffset(offset)
113+
.withPagingModel(pagingModel)
118114
.build();
119115
return adapterFunction.apply(selectModel);
120116
}
121117

122118
public class LimitFinisher implements Buildable<R> {
123-
public OffsetFinisher offset(int offset) {
124-
return SelectDSL.this.offset(offset);
119+
private long limit;
120+
121+
public LimitFinisher(long limit) {
122+
this.limit = limit;
123+
}
124+
125+
public OffsetFinisher offset(long offset) {
126+
return new OffsetFinisher(limit, offset);
125127
}
126128

127129
@Override
128130
public R build() {
131+
SelectDSL.this.pagingModel = new LimitAndOffsetPagingModel.Builder()
132+
.withLimit(limit)
133+
.build();
129134
return SelectDSL.this.build();
130135
}
131136
}
132137

133138
public class OffsetFinisher implements Buildable<R> {
139+
private LimitAndOffsetPagingModel pagingModel;
140+
141+
public OffsetFinisher(long limit, long offset) {
142+
pagingModel = new LimitAndOffsetPagingModel.Builder()
143+
.withLimit(limit)
144+
.withOffset(offset)
145+
.build();
146+
}
147+
148+
public OffsetFinisher(long offset) {
149+
pagingModel = new LimitAndOffsetPagingModel.Builder()
150+
.withOffset(offset)
151+
.build();
152+
}
153+
134154
@Override
135155
public R build() {
156+
SelectDSL.this.pagingModel = pagingModel;
136157
return SelectDSL.this.build();
137158
}
138159
}

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

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,12 @@
2929
public class SelectModel {
3030
private List<QueryExpressionModel> queryExpressions;
3131
private OrderByModel orderByModel;
32-
private Long limit;
33-
private Long offset;
32+
private PagingModel pagingModel;
3433

3534
private SelectModel(Builder builder) {
3635
queryExpressions = Objects.requireNonNull(builder.queryExpressions);
3736
orderByModel = builder.orderByModel;
38-
limit = builder.limit;
39-
offset = builder.offset;
37+
pagingModel = builder.pagingModel;
4038
}
4139

4240
public <R> Stream<R> mapQueryExpressions(Function<QueryExpressionModel, R> mapper) {
@@ -47,12 +45,8 @@ public Optional<OrderByModel> orderByModel() {
4745
return Optional.ofNullable(orderByModel);
4846
}
4947

50-
public Optional<Long> limit() {
51-
return Optional.ofNullable(limit);
52-
}
53-
54-
public Optional<Long> offset() {
55-
return Optional.ofNullable(offset);
48+
public Optional<PagingModel> pagingModel() {
49+
return Optional.ofNullable(pagingModel);
5650
}
5751

5852
public SelectStatementProvider render(RenderingStrategy renderingStrategy) {
@@ -69,8 +63,7 @@ public static Builder withQueryExpressions(List<QueryExpressionModel> queryExpre
6963
public static class Builder {
7064
private List<QueryExpressionModel> queryExpressions = new ArrayList<>();
7165
private OrderByModel orderByModel;
72-
private Long limit;
73-
private Long offset;
66+
private PagingModel pagingModel;
7467

7568
public Builder withQueryExpressions(List<QueryExpressionModel> queryExpressions) {
7669
this.queryExpressions.addAll(queryExpressions);
@@ -81,14 +74,9 @@ public Builder withOrderByModel(OrderByModel orderByModel) {
8174
this.orderByModel = orderByModel;
8275
return this;
8376
}
84-
85-
public Builder withLimit(Long limit) {
86-
this.limit = limit;
87-
return this;
88-
}
89-
90-
public Builder withOffset(Long offset) {
91-
this.offset = offset;
77+
78+
public Builder withPagingModel(PagingModel pagingModel) {
79+
this.pagingModel = pagingModel;
9280
return this;
9381
}
9482

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/**
2+
* Copyright 2016-2019 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.render;
17+
18+
import java.util.Optional;
19+
20+
import org.mybatis.dynamic.sql.render.RenderingStrategy;
21+
import org.mybatis.dynamic.sql.select.LimitAndOffsetPagingModel;
22+
import org.mybatis.dynamic.sql.util.FragmentAndParameters;
23+
24+
public class LimitAndOffsetPagingModelRenderer {
25+
private static final String LIMIT_PARAMETER = "_limit"; //$NON-NLS-1$
26+
private static final String OFFSET_PARAMETER = "_offset"; //$NON-NLS-1$
27+
private RenderingStrategy renderingStrategy;
28+
private LimitAndOffsetPagingModel pagingModel;
29+
30+
public LimitAndOffsetPagingModelRenderer(RenderingStrategy renderingStrategy,
31+
LimitAndOffsetPagingModel pagingModel) {
32+
this.renderingStrategy = renderingStrategy;
33+
this.pagingModel = pagingModel;
34+
}
35+
36+
public Optional<FragmentAndParameters> render() {
37+
return pagingModel.limit()
38+
.map(this::renderWithLimit)
39+
.orElse(renderOffsetOnly());
40+
}
41+
42+
private Optional<FragmentAndParameters> renderWithLimit(Long limit) {
43+
return pagingModel.offset()
44+
.map(o -> renderLimitAndOffset(limit, o))
45+
.orElse(renderLimitOnly(limit));
46+
}
47+
48+
private Optional<FragmentAndParameters> renderOffsetOnly() {
49+
return pagingModel.offset().flatMap(this::renderOffsetOnly);
50+
}
51+
52+
private Optional<FragmentAndParameters> renderOffsetOnly(Long offset) {
53+
return FragmentAndParameters
54+
.withFragment("offset " + renderPlaceholder(OFFSET_PARAMETER)) //$NON-NLS-1$
55+
.withParameter(OFFSET_PARAMETER, offset)
56+
.buildOptional();
57+
}
58+
59+
private Optional<FragmentAndParameters> renderLimitOnly(Long limit) {
60+
return FragmentAndParameters.withFragment("limit " + renderPlaceholder(LIMIT_PARAMETER)) //$NON-NLS-1$
61+
.withParameter(LIMIT_PARAMETER, limit)
62+
.buildOptional();
63+
}
64+
65+
private Optional<FragmentAndParameters> renderLimitAndOffset(Long limit, Long offset) {
66+
return FragmentAndParameters.withFragment("limit " + renderPlaceholder(LIMIT_PARAMETER) //$NON-NLS-1$
67+
+ " offset " + renderPlaceholder(OFFSET_PARAMETER)) //$NON-NLS-1$
68+
.withParameter(LIMIT_PARAMETER, limit)
69+
.withParameter(OFFSET_PARAMETER, offset)
70+
.buildOptional();
71+
}
72+
73+
private String renderPlaceholder(String parameterName) {
74+
return renderingStrategy.getFormattedJdbcPlaceholder(RenderingStrategy.DEFAULT_PARAMETER_PREFIX,
75+
parameterName);
76+
}
77+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* Copyright 2016-2019 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.render;
17+
18+
import java.util.Optional;
19+
20+
import org.mybatis.dynamic.sql.render.RenderingStrategy;
21+
import org.mybatis.dynamic.sql.select.LimitAndOffsetPagingModel;
22+
import org.mybatis.dynamic.sql.select.PagingModelVisitor;
23+
import org.mybatis.dynamic.sql.util.FragmentAndParameters;
24+
25+
public class PagingModelRenderer implements PagingModelVisitor<Optional<FragmentAndParameters>> {
26+
private RenderingStrategy renderingStrategy;
27+
28+
public PagingModelRenderer(RenderingStrategy renderingStrategy) {
29+
this.renderingStrategy = renderingStrategy;
30+
}
31+
32+
@Override
33+
public Optional<FragmentAndParameters> visit(LimitAndOffsetPagingModel pagingModel) {
34+
return new LimitAndOffsetPagingModelRenderer(renderingStrategy, pagingModel).render();
35+
}
36+
}

0 commit comments

Comments
 (0)