forked from mybatis/mybatis-dynamic-sql
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLimitAndOffsetAdapter.java
94 lines (82 loc) · 3.51 KB
/
LimitAndOffsetAdapter.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/*
* Copyright 2016-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package examples.paging;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.select.SelectModel;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
/**
* This adapter modifies the generated SQL by adding a LIMIT and OFFSET clause at the end
* of the generated SQL. This can be used to create a paginated query.
*
* LIMIT and OFFSET has limited support in relational databases, so this cannot be considered
* a general solution for all paginated queries (and that is why this adapter lives only in the
* test source tree and is not packaged with the core library code).
*
* I believe it works in MySQL, HSQLDB, and Postgres.
*
* <b>Important Note: </b> this adapter is no longer required for limit and offset support as the
* library now supports limit and offset natively. However, this remains a good example of altering the generated
* SQL before it is executed.
*
* @author Jeff Butler
*/
public class LimitAndOffsetAdapter<R> {
private final SelectModel selectModel;
private final Function<SelectStatementProvider, R> mapperMethod;
private final int limit;
private final int offset;
private LimitAndOffsetAdapter(SelectModel selectModel, Function<SelectStatementProvider, R> mapperMethod,
int limit, int offset) {
this.selectModel = Objects.requireNonNull(selectModel);
this.mapperMethod = Objects.requireNonNull(mapperMethod);
this.limit = limit;
this.offset = offset;
}
public R execute() {
return mapperMethod.apply(selectStatement());
}
private SelectStatementProvider selectStatement() {
return new LimitAndOffsetDecorator(
selectModel.render(RenderingStrategies.MYBATIS3));
}
public static <R> LimitAndOffsetAdapter<R> of(SelectModel selectModel,
Function<SelectStatementProvider, R> mapperMethod, int limit, int offset) {
return new LimitAndOffsetAdapter<>(selectModel, mapperMethod, limit, offset);
}
public class LimitAndOffsetDecorator implements SelectStatementProvider {
private final Map<String, Object> parameters = new HashMap<>();
private final String selectStatement;
public LimitAndOffsetDecorator(SelectStatementProvider delegate) {
parameters.putAll(delegate.getParameters());
parameters.put("limit", limit);
parameters.put("offset", offset);
selectStatement = delegate.getSelectStatement() +
" LIMIT #{parameters.limit} OFFSET #{parameters.offset}";
}
@Override
public Map<String, Object> getParameters() {
return parameters;
}
@Override
public String getSelectStatement() {
return selectStatement;
}
}
}