Skip to content

Commit a9acf5c

Browse files
committed
Support LIMIT and OFFSET on SQL class
Fixes gh-1518
1 parent bee7ba2 commit a9acf5c

File tree

2 files changed

+109
-3
lines changed

2 files changed

+109
-3
lines changed

src/main/java/org/apache/ibatis/jdbc/AbstractSQL.java

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2009-2018 the original author or authors.
2+
* Copyright 2009-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -262,6 +262,54 @@ public T ORDER_BY(String... columns) {
262262
return getSelf();
263263
}
264264

265+
/**
266+
* Set the limit variable string(e.g. {@code "#{limit}"}).
267+
*
268+
* @param variable a limit variable string
269+
* @return a self instance
270+
* @since 3.5.2
271+
*/
272+
public T LIMIT(String variable) {
273+
sql().limit = variable;
274+
return getSelf();
275+
}
276+
277+
/**
278+
* Set the limit value.
279+
*
280+
* @param value an offset value
281+
* @return a self instance
282+
* @since 3.5.2
283+
*/
284+
public T LIMIT(int value) {
285+
sql().limit = String.valueOf(value);
286+
return getSelf();
287+
}
288+
289+
/**
290+
* Set the offset variable string(e.g. {@code "#{offset}"}).
291+
*
292+
* @param variable a offset variable string
293+
* @return a self instance
294+
* @since 3.5.2
295+
*/
296+
public T OFFSET(String variable) {
297+
sql().offset = variable;
298+
return getSelf();
299+
}
300+
301+
/**
302+
* Set the offset value.
303+
*
304+
* @param value an offset value
305+
* @return a self instance
306+
* @since 3.5.2
307+
*/
308+
public T OFFSET(long value) {
309+
sql().offset = String.valueOf(value);
310+
return getSelf();
311+
}
312+
265313
private SQLStatement sql() {
266314
return sql;
267315
}
@@ -328,6 +376,8 @@ public enum StatementType {
328376
List<String> columns = new ArrayList<>();
329377
List<String> values = new ArrayList<>();
330378
boolean distinct;
379+
String offset;
380+
String limit;
331381

332382
public SQLStatement() {
333383
// Prevent Synthetic Access
@@ -368,6 +418,12 @@ private String selectSQL(SafeAppendable builder) {
368418
sqlClause(builder, "GROUP BY", groupBy, "", "", ", ");
369419
sqlClause(builder, "HAVING", having, "(", ")", " AND ");
370420
sqlClause(builder, "ORDER BY", orderBy, "", "", ", ");
421+
if (limit != null) {
422+
builder.append(" LIMIT ").append(limit);
423+
}
424+
if (offset != null) {
425+
builder.append(" OFFSET ").append(offset);
426+
}
371427
return builder.toString();
372428
}
373429

@@ -389,6 +445,9 @@ private String insertSQL(SafeAppendable builder) {
389445
private String deleteSQL(SafeAppendable builder) {
390446
sqlClause(builder, "DELETE FROM", tables, "", "", "");
391447
sqlClause(builder, "WHERE", where, "(", ")", " AND ");
448+
if (limit != null) {
449+
builder.append(" LIMIT ").append(limit);
450+
}
392451
return builder.toString();
393452
}
394453

@@ -397,6 +456,9 @@ private String updateSQL(SafeAppendable builder) {
397456
joins(builder);
398457
sqlClause(builder, "SET", sets, "", "", ", ");
399458
sqlClause(builder, "WHERE", where, "(", ")", " AND ");
459+
if (limit != null) {
460+
builder.append(" LIMIT ").append(limit);
461+
}
400462
return builder.toString();
401463
}
402464

src/test/java/org/apache/ibatis/jdbc/SQLTest.java

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,6 @@ void variableLengthArgumentOnIntoColumnsAndValues() {
293293
INSERT_INTO("TABLE_A").INTO_COLUMNS("a", "b").INTO_VALUES("#{a}", "#{b}");
294294
}}.toString();
295295

296-
System.out.println(sql);
297-
298296
assertEquals("INSERT INTO TABLE_A\n (a, b)\nVALUES (#{a}, #{b})", sql);
299297
}
300298

@@ -303,4 +301,50 @@ void fixFor903UpdateJoins() {
303301
final SQL sql = new SQL().UPDATE("table1 a").INNER_JOIN("table2 b USING (ID)").SET("a.value = b.value");
304302
assertThat(sql.toString()).isEqualTo("UPDATE table1 a\nINNER JOIN table2 b USING (ID)\nSET a.value = b.value");
305303
}
304+
305+
@Test
306+
void selectUsingLimitVariableName() {
307+
final String sql = new SQL() {{
308+
SELECT("*").FROM("test").ORDER_BY("id").LIMIT("#{limit}");
309+
}}.toString();
310+
311+
assertEquals("SELECT *\nFROM test\nORDER BY id LIMIT #{limit}", sql);
312+
}
313+
314+
@Test
315+
void selectUsingOffsetVariableName() {
316+
final String sql = new SQL() {{
317+
SELECT("*").FROM("test").ORDER_BY("id").OFFSET("#{offset}");
318+
}}.toString();
319+
320+
assertEquals("SELECT *\nFROM test\nORDER BY id OFFSET #{offset}", sql);
321+
}
322+
323+
@Test
324+
void selectUsingLimitAndOffset() {
325+
final String sql = new SQL() {{
326+
SELECT("*").FROM("test").ORDER_BY("id").LIMIT(20).OFFSET(100);
327+
}}.toString();
328+
329+
assertEquals("SELECT *\nFROM test\nORDER BY id LIMIT 20 OFFSET 100", sql);
330+
}
331+
332+
@Test
333+
void updateUsingLimit() {
334+
final String sql = new SQL() {{
335+
UPDATE("test").SET("status = #{updStatus}").WHERE("status = #{status}").LIMIT(20);
336+
}}.toString();
337+
338+
assertEquals("UPDATE test\nSET status = #{updStatus}\nWHERE (status = #{status}) LIMIT 20", sql);
339+
}
340+
341+
@Test
342+
void deleteUsingLimit() {
343+
final String sql = new SQL() {{
344+
DELETE_FROM("test").WHERE("status = #{status}").LIMIT(20);
345+
}}.toString();
346+
347+
assertEquals("DELETE FROM test\nWHERE (status = #{status}) LIMIT 20", sql);
348+
}
349+
306350
}

0 commit comments

Comments
 (0)