Skip to content

Commit 77da9b4

Browse files
committed
Improve offset/limit methods
1 parent e114cf9 commit 77da9b4

File tree

7 files changed

+50
-23
lines changed

7 files changed

+50
-23
lines changed

doma-core/src/main/java/org/seasar/doma/internal/jdbc/dialect/MysqlPagingTransformer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
public class MysqlPagingTransformer extends StandardPagingTransformer {
99

10-
protected static String MAXIMUM_LIMIT = "18446744073709551615";
10+
public static String MAXIMUM_LIMIT = "18446744073709551615";
1111

1212
public MysqlPagingTransformer(long offset, long limit) {
1313
super(offset, limit);

doma-core/src/main/java/org/seasar/doma/jdbc/criteria/query/CriteriaBuilder.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ public interface CriteriaBuilder {
99

1010
void concat(PreparedSqlBuilder buf, Runnable leftOperand, Runnable rightOperand);
1111

12+
void offsetAndFetch(PreparedSqlBuilder buf, int offset, int limit);
13+
1214
void lockWithTableHint(
1315
PreparedSqlBuilder buf, ForUpdateOption option, Consumer<PropertyMetamodel<?>> column);
1416

doma-core/src/main/java/org/seasar/doma/jdbc/criteria/query/SelectBuilder.java

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import org.seasar.doma.jdbc.criteria.metamodel.PropertyMetamodel;
2222
import org.seasar.doma.jdbc.criteria.option.DistinctOption;
2323
import org.seasar.doma.jdbc.criteria.option.ForUpdateOption;
24-
import org.seasar.doma.jdbc.dialect.Dialect;
2524

2625
public class SelectBuilder {
2726
private final Config config;
@@ -30,6 +29,7 @@ public class SelectBuilder {
3029
private final PreparedSqlBuilder buf;
3130
private final AliasManager aliasManager;
3231
private final BuilderSupport support;
32+
private final CriteriaBuilder criteriaBuilder;
3333

3434
public SelectBuilder(
3535
Config config,
@@ -57,6 +57,7 @@ public SelectBuilder(
5757
this.buf = Objects.requireNonNull(buf);
5858
this.aliasManager = Objects.requireNonNull(aliasManager);
5959
support = new BuilderSupport(config, commenter, buf, aliasManager);
60+
criteriaBuilder = config.getDialect().getCriteriaBuilder();
6061
}
6162

6263
public PreparedSql build() {
@@ -72,8 +73,7 @@ void interpret() {
7273
groupBy();
7374
having();
7475
orderBy();
75-
limit();
76-
offset();
76+
offsetAndFetch();
7777
forUpdate();
7878
}
7979

@@ -101,8 +101,6 @@ private void from() {
101101
table(context.entityMetamodel);
102102
if (context.forUpdate != null) {
103103
ForUpdateOption option = context.forUpdate.option;
104-
Dialect dialect = config.getDialect();
105-
CriteriaBuilder criteriaBuilder = dialect.getCriteriaBuilder();
106104
criteriaBuilder.lockWithTableHint(buf, option, this::column);
107105
}
108106
}
@@ -199,25 +197,18 @@ public void visit(OrderByItem.Index index) {
199197
}
200198
}
201199

202-
private void limit() {
203-
if (context.limit != null) {
204-
buf.appendSql(" limit ");
205-
buf.appendSql(context.limit.toString());
206-
}
207-
}
208-
209-
private void offset() {
210-
if (context.offset != null) {
211-
buf.appendSql(" offset ");
212-
buf.appendSql(context.offset.toString());
200+
private void offsetAndFetch() {
201+
if (context.offset == null && context.limit == null) {
202+
return;
213203
}
204+
int offset = (context.offset == null || context.offset < 0) ? 0 : context.offset;
205+
int limit = (context.limit == null || context.limit < 0) ? 0 : context.limit;
206+
criteriaBuilder.offsetAndFetch(buf, offset, limit);
214207
}
215208

216209
private void forUpdate() {
217210
if (context.forUpdate != null) {
218211
ForUpdateOption option = context.forUpdate.option;
219-
Dialect dialect = config.getDialect();
220-
CriteriaBuilder criteriaBuilder = dialect.getCriteriaBuilder();
221212
criteriaBuilder.forUpdate(buf, option, this::column, aliasManager);
222213
}
223214
}

doma-core/src/main/java/org/seasar/doma/jdbc/dialect/MysqlDialect.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@
1010
import org.seasar.doma.internal.jdbc.dialect.MysqlCountGettingTransformer;
1111
import org.seasar.doma.internal.jdbc.dialect.MysqlForUpdateTransformer;
1212
import org.seasar.doma.internal.jdbc.dialect.MysqlPagingTransformer;
13+
import org.seasar.doma.internal.jdbc.sql.PreparedSqlBuilder;
1314
import org.seasar.doma.jdbc.JdbcMappingVisitor;
1415
import org.seasar.doma.jdbc.ScriptBlockContext;
1516
import org.seasar.doma.jdbc.SelectForUpdateType;
1617
import org.seasar.doma.jdbc.SqlLogFormattingVisitor;
1718
import org.seasar.doma.jdbc.SqlNode;
19+
import org.seasar.doma.jdbc.criteria.query.CriteriaBuilder;
1820

1921
/** A dialect for MySQL. */
2022
public class MysqlDialect extends StandardDialect {
@@ -130,6 +132,11 @@ public String applyQuote(String name) {
130132
return OPEN_QUOTE + name + CLOSE_QUOTE;
131133
}
132134

135+
@Override
136+
public CriteriaBuilder getCriteriaBuilder() {
137+
return new MysqlCriteriaBuilder();
138+
}
139+
133140
public static class MysqlJdbcMappingVisitor extends StandardJdbcMappingVisitor {}
134141

135142
public static class MysqlSqlLogFormattingVisitor extends StandardSqlLogFormattingVisitor {}
@@ -162,4 +169,18 @@ protected MysqlScriptBlockContext() {
162169
sqlBlockStartKeywordsList.add(Arrays.asList("begin"));
163170
}
164171
}
172+
173+
public static class MysqlCriteriaBuilder extends StandardCriteriaBuilder {
174+
@Override
175+
public void offsetAndFetch(PreparedSqlBuilder buf, int offset, int limit) {
176+
buf.appendSql(" limit ");
177+
if (limit > 0) {
178+
buf.appendSql(Integer.toString(limit));
179+
} else {
180+
buf.appendSql(MysqlPagingTransformer.MAXIMUM_LIMIT);
181+
}
182+
buf.appendSql(" offset ");
183+
buf.appendSql(Integer.toString(offset));
184+
}
185+
}
165186
}

doma-core/src/main/java/org/seasar/doma/jdbc/dialect/StandardDialect.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,18 @@ public void concat(PreparedSqlBuilder buf, Runnable leftOperand, Runnable rightO
10791079
buf.appendSql(")");
10801080
}
10811081

1082+
@Override
1083+
public void offsetAndFetch(PreparedSqlBuilder buf, int offset, int limit) {
1084+
buf.appendSql(" offset ");
1085+
buf.appendSql(Integer.toString(offset));
1086+
buf.appendSql(" rows");
1087+
if (limit > 0) {
1088+
buf.appendSql(" fetch first ");
1089+
buf.appendSql(Integer.toString(limit));
1090+
buf.appendSql(" rows only");
1091+
}
1092+
}
1093+
10821094
@Override
10831095
public void lockWithTableHint(
10841096
PreparedSqlBuilder buf, ForUpdateOption option, Consumer<PropertyMetamodel<?>> column) {}

doma-core/src/test/java/org/seasar/doma/jdbc/criteria/EntityqlSelectTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ void limit() {
161161

162162
Sql<?> sql = stmt.asSql();
163163
assertEquals(
164-
"select t0_.ID, t0_.NAME, t0_.SALARY, t0_.VERSION from EMP t0_ limit 5",
164+
"select t0_.ID, t0_.NAME, t0_.SALARY, t0_.VERSION from EMP t0_ offset 0 rows fetch first 5 rows only",
165165
sql.getFormattedSql());
166166
}
167167

@@ -182,7 +182,7 @@ void offset() {
182182

183183
Sql<?> sql = stmt.asSql();
184184
assertEquals(
185-
"select t0_.ID, t0_.NAME, t0_.SALARY, t0_.VERSION from EMP t0_ offset 5",
185+
"select t0_.ID, t0_.NAME, t0_.SALARY, t0_.VERSION from EMP t0_ offset 5 rows",
186186
sql.getFormattedSql());
187187
}
188188

doma-core/src/test/java/org/seasar/doma/jdbc/criteria/NativeSqlSelectTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,8 @@ void limit() {
655655
Buildable<?> stmt = nativeSql.from(e).limit(10).select(e.id);
656656

657657
Sql<?> sql = stmt.asSql();
658-
assertEquals("select t0_.ID from EMP t0_ limit 10", sql.getFormattedSql());
658+
assertEquals(
659+
"select t0_.ID from EMP t0_ offset 0 rows fetch first 10 rows only", sql.getFormattedSql());
659660
}
660661

661662
@Test
@@ -673,7 +674,7 @@ void offset() {
673674
Buildable<?> stmt = nativeSql.from(e).offset(10).select(e.id);
674675

675676
Sql<?> sql = stmt.asSql();
676-
assertEquals("select t0_.ID from EMP t0_ offset 10", sql.getFormattedSql());
677+
assertEquals("select t0_.ID from EMP t0_ offset 10 rows", sql.getFormattedSql());
677678
}
678679

679680
@Test

0 commit comments

Comments
 (0)