Skip to content

Commit ccab50d

Browse files
committed
Add group support to Kotlin DSL
1 parent 4b70644 commit ccab50d

File tree

4 files changed

+211
-38
lines changed

4 files changed

+211
-38
lines changed

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

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -226,25 +226,38 @@ static WhereDSL where(ExistsPredicate existsPredicate, AndOrCriteriaGroup... sub
226226
// where condition connectors
227227
static <T> CriteriaGroup group(BindableColumn<T> column, VisitableCondition<T> condition,
228228
AndOrCriteriaGroup...subCriteria) {
229+
return group(column, condition, Arrays.asList(subCriteria));
230+
}
231+
232+
static <T> CriteriaGroup group(BindableColumn<T> column, VisitableCondition<T> condition,
233+
List<AndOrCriteriaGroup> subCriteria) {
229234
return new CriteriaGroup.Builder()
230235
.withInitialCriterion(new ColumnAndConditionCriterion.Builder<T>().withColumn(column)
231-
.withCondition(condition).build())
232-
.withSubCriteria(Arrays.asList(subCriteria))
236+
.withCondition(condition).build())
237+
.withSubCriteria(subCriteria)
233238
.build();
234239
}
235240

236241
static CriteriaGroup group(ExistsPredicate existsPredicate, AndOrCriteriaGroup...subCriteria) {
242+
return group(existsPredicate, Arrays.asList(subCriteria));
243+
}
244+
245+
static CriteriaGroup group(ExistsPredicate existsPredicate, List<AndOrCriteriaGroup> subCriteria) {
237246
return new CriteriaGroup.Builder()
238247
.withInitialCriterion(new ExistsCriterion.Builder()
239-
.withExistsPredicate(existsPredicate).build())
240-
.withSubCriteria(Arrays.asList(subCriteria))
248+
.withExistsPredicate(existsPredicate).build())
249+
.withSubCriteria(subCriteria)
241250
.build();
242251
}
243252

244253
static CriteriaGroup group(CriteriaGroup criterionGroup, AndOrCriteriaGroup...subCriteria) {
254+
return group(criterionGroup, Arrays.asList(subCriteria));
255+
}
256+
257+
static CriteriaGroup group(CriteriaGroup criterionGroup, List<AndOrCriteriaGroup> subCriteria) {
245258
return new CriteriaGroup.Builder()
246259
.withInitialCriterion(criterionGroup)
247-
.withSubCriteria(Arrays.asList(subCriteria))
260+
.withSubCriteria(subCriteria)
248261
.build();
249262
}
250263

src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ package org.mybatis.dynamic.sql.util.kotlin.elements
1919
import org.mybatis.dynamic.sql.BasicColumn
2020
import org.mybatis.dynamic.sql.BindableColumn
2121
import org.mybatis.dynamic.sql.Constant
22+
import org.mybatis.dynamic.sql.CriteriaGroup
2223
import org.mybatis.dynamic.sql.ExistsPredicate
2324
import org.mybatis.dynamic.sql.SortSpecification
2425
import org.mybatis.dynamic.sql.SqlBuilder
2526
import org.mybatis.dynamic.sql.SqlColumn
2627
import org.mybatis.dynamic.sql.StringConstant
28+
import org.mybatis.dynamic.sql.VisitableCondition
2729
import org.mybatis.dynamic.sql.select.aggregate.Avg
2830
import org.mybatis.dynamic.sql.select.aggregate.Count
2931
import org.mybatis.dynamic.sql.select.aggregate.CountAll
@@ -41,6 +43,8 @@ import org.mybatis.dynamic.sql.select.function.Substring
4143
import org.mybatis.dynamic.sql.select.function.Subtract
4244
import org.mybatis.dynamic.sql.select.function.Upper
4345
import org.mybatis.dynamic.sql.select.join.EqualTo
46+
import org.mybatis.dynamic.sql.util.kotlin.CriteriaCollector
47+
import org.mybatis.dynamic.sql.util.kotlin.CriteriaReceiver
4448
import org.mybatis.dynamic.sql.util.kotlin.KotlinSubQueryBuilder
4549
import org.mybatis.dynamic.sql.where.condition.IsBetween
4650
import org.mybatis.dynamic.sql.where.condition.IsEqualTo
@@ -146,6 +150,19 @@ fun <T> substring(
146150

147151
fun <T> upper(column: BindableColumn<T>): Upper<T> = SqlBuilder.upper(column)
148152

153+
fun group(initialCriterion: CriteriaGroup, subCriteria: CriteriaReceiver = {}): CriteriaGroup =
154+
SqlBuilder.group(initialCriterion, CriteriaCollector().apply(subCriteria).criteria)
155+
156+
fun group(existsPredicate: ExistsPredicate, subCriteria: CriteriaReceiver = {}): CriteriaGroup =
157+
SqlBuilder.group(existsPredicate, CriteriaCollector().apply(subCriteria).criteria)
158+
159+
fun <T> group(
160+
column: BindableColumn<T>,
161+
condition: VisitableCondition<T>,
162+
subCriteria: CriteriaReceiver = {}
163+
): CriteriaGroup =
164+
SqlBuilder.group(column, condition, CriteriaCollector().apply(subCriteria).criteria)
165+
149166
// conditions for all data types
150167
fun <T> isNull(): IsNull<T> = SqlBuilder.isNull()
151168

src/test/java/examples/complexquery/GroupingTest.java

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@
2121
import org.mybatis.dynamic.sql.render.RenderingStrategies;
2222
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
2323

24-
import static examples.complexquery.PersonDynamicSqlSupport.firstName;
25-
import static examples.complexquery.PersonDynamicSqlSupport.id;
26-
import static examples.complexquery.PersonDynamicSqlSupport.lastName;
27-
import static examples.complexquery.PersonDynamicSqlSupport.person;
2824
import static org.assertj.core.api.Assertions.assertThat;
2925
import static org.mybatis.dynamic.sql.SqlBuilder.exists;
3026
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
@@ -36,7 +32,7 @@
3632
import static org.mybatis.dynamic.sql.SqlBuilder.select;
3733

3834
class GroupingTest {
39-
public static class Foo extends SqlTable {
35+
private static class Foo extends SqlTable {
4036
public SqlColumn<Integer> A = column("A");
4137
public SqlColumn<Integer> B = column("B");
4238
public SqlColumn<Integer> C = column("C");
@@ -46,40 +42,40 @@ public Foo() {
4642
}
4743
}
4844

45+
private static final Foo foo = new Foo();
46+
private static final SqlColumn<Integer> A = foo.A;
47+
private static final SqlColumn<Integer> B = foo.B;
48+
private static final SqlColumn<Integer> C = foo.C;
49+
4950
@Test
5051
void testSimpleGrouping() {
51-
SelectStatementProvider selectStatement = select(id, firstName, lastName)
52-
.from(person)
53-
.where(firstName, isEqualTo("Fred"), or(firstName, isEqualTo("Wilma")))
54-
.and(lastName, isEqualTo("Flintstone"))
52+
SelectStatementProvider selectStatement = select(A, B, C)
53+
.from(foo)
54+
.where(A, isEqualTo(1), or(A, isEqualTo(2)))
55+
.and(B, isEqualTo(3))
5556
.build()
5657
.render(RenderingStrategies.MYBATIS3);
5758

58-
String expected = "select person_id, first_name, last_name"
59-
+ " from Person"
60-
+ " where (first_name = #{parameters.p1} or first_name = #{parameters.p2}) and last_name = #{parameters.p3}";
59+
String expected = "select A, B, C"
60+
+ " from Foo"
61+
+ " where (A = #{parameters.p1} or A = #{parameters.p2}) and B = #{parameters.p3}";
6162

6263
assertThat(selectStatement.getSelectStatement()).isEqualTo(expected);
63-
assertThat(selectStatement.getParameters()).containsEntry("p1", "Fred");
64-
assertThat(selectStatement.getParameters()).containsEntry("p2", "Wilma");
65-
assertThat(selectStatement.getParameters()).containsEntry("p3", "Flintstone");
64+
assertThat(selectStatement.getParameters()).containsEntry("p1", 1);
65+
assertThat(selectStatement.getParameters()).containsEntry("p2", 2);
66+
assertThat(selectStatement.getParameters()).containsEntry("p3", 3);
6667
}
6768

6869
@Test
6970
void testComplexGrouping() {
70-
Foo foo = new Foo();
71-
SqlColumn<Integer> A = foo.A;
72-
SqlColumn<Integer> B = foo.B;
73-
SqlColumn<Integer> C = foo.C;
74-
7571
SelectStatementProvider selectStatement = select(A, B, C)
7672
.from(foo)
7773
.where(
7874
group(A, isEqualTo(1), or(A, isGreaterThan(5))),
7975
and(B, isEqualTo(1)),
8076
or(A, isLessThan(0), and(B, isEqualTo(2)))
8177
)
82-
.and(foo.C, isEqualTo(1))
78+
.and(C, isEqualTo(1))
8379
.build()
8480
.render(RenderingStrategies.MYBATIS3);
8581

@@ -98,19 +94,14 @@ void testComplexGrouping() {
9894

9995
@Test
10096
void testGroupAndExists() {
101-
Foo foo = new Foo();
102-
SqlColumn<Integer> A = foo.A;
103-
SqlColumn<Integer> B = foo.B;
104-
SqlColumn<Integer> C = foo.C;
105-
10697
SelectStatementProvider selectStatement = select(A, B, C)
10798
.from(foo)
10899
.where(
109100
group(exists(select(foo.allColumns()).from(foo).where(A, isEqualTo(3))), and (A, isEqualTo(1)), or(A, isGreaterThan(5))),
110101
and(B, isEqualTo(1)),
111102
or(A, isLessThan(0), and(B, isEqualTo(2)))
112103
)
113-
.and(foo.C, isEqualTo(1))
104+
.and(C, isEqualTo(1))
114105
.build()
115106
.render(RenderingStrategies.MYBATIS3);
116107

@@ -130,19 +121,14 @@ void testGroupAndExists() {
130121

131122
@Test
132123
void testNestedGrouping() {
133-
Foo foo = new Foo();
134-
SqlColumn<Integer> A = foo.A;
135-
SqlColumn<Integer> B = foo.B;
136-
SqlColumn<Integer> C = foo.C;
137-
138124
SelectStatementProvider selectStatement = select(A, B, C)
139125
.from(foo)
140126
.where(
141127
group(group(A, isEqualTo(1), or(A, isGreaterThan(5))), and(A, isGreaterThan(5))),
142128
and(group(A, isEqualTo(1), or(A, isGreaterThan(5))), or(B, isEqualTo(1))),
143129
or(group(A, isEqualTo(1), or(A, isGreaterThan(5))), and(A, isLessThan(0), and(B, isEqualTo(2))))
144130
)
145-
.and(foo.C, isEqualTo(1))
131+
.and(C, isEqualTo(1))
146132
.build()
147133
.render(RenderingStrategies.MYBATIS3);
148134

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
package examples.kotlin.mybatis3.general
2+
3+
import examples.kotlin.mybatis3.general.FooDynamicSqlSupport.A
4+
import examples.kotlin.mybatis3.general.FooDynamicSqlSupport.B
5+
import examples.kotlin.mybatis3.general.FooDynamicSqlSupport.C
6+
import examples.kotlin.mybatis3.general.FooDynamicSqlSupport.foo
7+
import org.assertj.core.api.Assertions.assertThat
8+
import org.junit.jupiter.api.Test
9+
import org.mybatis.dynamic.sql.SqlTable
10+
import org.mybatis.dynamic.sql.util.kotlin.elements.exists
11+
import org.mybatis.dynamic.sql.util.kotlin.elements.group
12+
import org.mybatis.dynamic.sql.util.kotlin.elements.isEqualTo
13+
import org.mybatis.dynamic.sql.util.kotlin.elements.isGreaterThan
14+
import org.mybatis.dynamic.sql.util.kotlin.elements.isLessThan
15+
import org.mybatis.dynamic.sql.util.kotlin.mybatis3.select
16+
17+
object FooDynamicSqlSupport {
18+
class Foo : SqlTable("Foo") {
19+
var A = column<Int>("A")
20+
var B = column<Int>("B")
21+
var C = column<Int>("C")
22+
}
23+
24+
val foo = Foo()
25+
val A = foo.A
26+
val B = foo.B
27+
val C = foo.C
28+
}
29+
30+
class KGroupingTest {
31+
@Test
32+
fun testSimpleGrouping() {
33+
val selectStatement = select(A, B, C) {
34+
from(foo)
35+
where (A, isEqualTo(1)) {
36+
or(A, isEqualTo(2))
37+
}
38+
and(B, isEqualTo(3))
39+
}
40+
41+
val expected = "select A, B, C" +
42+
" from Foo" +
43+
" where (A = #{parameters.p1} or A = #{parameters.p2}) and B = #{parameters.p3}"
44+
45+
assertThat(selectStatement.selectStatement).isEqualTo(expected)
46+
assertThat(selectStatement.parameters).containsEntry("p1", 1)
47+
assertThat(selectStatement.parameters).containsEntry("p2", 2)
48+
assertThat(selectStatement.parameters).containsEntry("p3", 3)
49+
}
50+
51+
@Test
52+
fun testComplexGrouping() {
53+
val selectStatement = select(A, B, C) {
54+
from(foo)
55+
where(group(A, isEqualTo(1)) {
56+
or(A, isGreaterThan(5))
57+
}) {
58+
and(B, isEqualTo(1))
59+
or(A, isLessThan(0)) {
60+
and(B, isEqualTo(2))
61+
}
62+
}
63+
and(C, isEqualTo(1))
64+
}
65+
66+
val expected = "select A, B, C" +
67+
" from Foo" +
68+
" where ((A = #{parameters.p1} or A > #{parameters.p2}) and B = #{parameters.p3} or (A < #{parameters.p4} and B = #{parameters.p5})) and C = #{parameters.p6}"
69+
70+
assertThat(selectStatement.selectStatement).isEqualTo(expected)
71+
assertThat(selectStatement.parameters).containsEntry("p1", 1)
72+
assertThat(selectStatement.parameters).containsEntry("p2", 5)
73+
assertThat(selectStatement.parameters).containsEntry("p3", 1)
74+
assertThat(selectStatement.parameters).containsEntry("p4", 0)
75+
assertThat(selectStatement.parameters).containsEntry("p5", 2)
76+
assertThat(selectStatement.parameters).containsEntry("p6", 1)
77+
}
78+
79+
@Test
80+
fun testGroupAndExists() {
81+
val selectStatement = select(A, B, C) {
82+
from(foo)
83+
where(group(exists {
84+
select(foo.allColumns()) {
85+
from (foo)
86+
where(A, isEqualTo(3))
87+
}
88+
}) {
89+
and(A, isEqualTo((1)))
90+
or(A, isGreaterThan(5))
91+
}) {
92+
and(B, isEqualTo(1))
93+
or(A, isLessThan(0)) {
94+
and(B, isEqualTo(2))
95+
}
96+
}
97+
and(C, isEqualTo(1))
98+
}
99+
100+
val expected = "select A, B, C" +
101+
" from Foo" +
102+
" where ((exists (select * from Foo where A = #{parameters.p1}) and A = #{parameters.p2} or A > #{parameters.p3}) and B = #{parameters.p4} or (A < #{parameters.p5} and B = #{parameters.p6})) and C = #{parameters.p7}"
103+
assertThat(selectStatement.selectStatement).isEqualTo(expected)
104+
assertThat(selectStatement.parameters).containsEntry("p1", 3)
105+
assertThat(selectStatement.parameters).containsEntry("p2", 1)
106+
assertThat(selectStatement.parameters).containsEntry("p3", 5)
107+
assertThat(selectStatement.parameters).containsEntry("p4", 1)
108+
assertThat(selectStatement.parameters).containsEntry("p5", 0)
109+
assertThat(selectStatement.parameters).containsEntry("p6", 2)
110+
assertThat(selectStatement.parameters).containsEntry("p7", 1)
111+
}
112+
113+
@Test
114+
fun testNestedGrouping() {
115+
val selectStatement = select(A, B, C) {
116+
from(foo)
117+
where(
118+
group(group(A, isEqualTo(1)) {
119+
or(A, isGreaterThan(5))
120+
}) {
121+
and(A, isGreaterThan(5))
122+
}
123+
) {
124+
and(group(A, isEqualTo(1)) {
125+
or(A, isGreaterThan(5))
126+
}) {
127+
or(B, isEqualTo(1))
128+
}
129+
or(group(A, isEqualTo(1)) {
130+
or(A, isGreaterThan(5))
131+
}) {
132+
and(A, isLessThan(0)) {
133+
and(B, isEqualTo(2))
134+
}
135+
}
136+
}
137+
and(C, isEqualTo(1))
138+
}
139+
140+
val expected = "select A, B, C" +
141+
" from Foo" +
142+
" where (((A = #{parameters.p1} or A > #{parameters.p2}) and A > #{parameters.p3}) and ((A = #{parameters.p4} or A > #{parameters.p5}) or B = #{parameters.p6}) or ((A = #{parameters.p7} or A > #{parameters.p8}) and (A < #{parameters.p9} and B = #{parameters.p10}))) and C = #{parameters.p11}"
143+
144+
assertThat(selectStatement.selectStatement).isEqualTo(expected)
145+
assertThat(selectStatement.parameters).containsEntry("p1", 1)
146+
assertThat(selectStatement.parameters).containsEntry("p2", 5)
147+
assertThat(selectStatement.parameters).containsEntry("p3", 5)
148+
assertThat(selectStatement.parameters).containsEntry("p4", 1)
149+
assertThat(selectStatement.parameters).containsEntry("p5", 5)
150+
assertThat(selectStatement.parameters).containsEntry("p6", 1)
151+
assertThat(selectStatement.parameters).containsEntry("p7", 1)
152+
assertThat(selectStatement.parameters).containsEntry("p8", 5)
153+
assertThat(selectStatement.parameters).containsEntry("p9", 0)
154+
assertThat(selectStatement.parameters).containsEntry("p10", 2)
155+
assertThat(selectStatement.parameters).containsEntry("p11", 1)
156+
}
157+
}

0 commit comments

Comments
 (0)