Skip to content

Commit 82ffdfa

Browse files
authored
Merge pull request #447 from jeffgbutler/join-dsl-update
[Kotlin] Update Join DSL
2 parents 62a7bda + 5fddb3f commit 82ffdfa

File tree

10 files changed

+115
-64
lines changed

10 files changed

+115
-64
lines changed

CHANGELOG.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,19 @@ GitHub milestone: [https://github.com/mybatis/mybatis-dynamic-sql/issues?q=miles
2020
([#438](https://github.com/mybatis/mybatis-dynamic-sql/pull/438))
2121
4. Major update to the Kotlin where clause DSL. Where clauses now support the "group" and "not" features from above. In
2222
addition, the where clause DSL has been fully updated to make it feel more like natural SQL. The previous version
23-
of the where clause DSL yielded almost unreadable code when the "group" and "not" functions were added. This update
24-
is better all around and yields a DSL that is very similar to native SQL. The new DSL includes many Kotlin DSL
25-
construction features including infix functions, operator overloads, and functions with receivers. We believe it
26-
will be well worth the effort to migrate to the new DSL. The prior where clause DSL remains in the library for now,
27-
but is deprecated. It will be removed in version 1.5.0 of the library. Documentation for the new DSL is here:
28-
https://github.com/mybatis/mybatis-dynamic-sql/blob/master/src/site/markdown/docs/kotlinWhereClauses.md
23+
of the where clause DSL would have yielded almost unreadable code had the "group" and "not" functions been added.
24+
This update is better all around and yields a DSL that is very similar to native SQL. The new DSL includes many
25+
Kotlin DSL construction features including infix functions, operator overloads, and functions with receivers.
26+
We believe it will be well worth the effort to migrate to the new DSL. The prior where clause DSL remains in the
27+
library for now, but is deprecated. It will be removed in version 1.5.0 of the library. Documentation for the new
28+
DSL is here: https://github.com/mybatis/mybatis-dynamic-sql/blob/master/src/site/markdown/docs/kotlinWhereClauses.md
2929
([#442](https://github.com/mybatis/mybatis-dynamic-sql/pull/442))
3030
5. General cleanup of the Kotlin DSL. The Kotlin DSL functions are now mostly Unit functions. This should have
3131
no impact on most users and is source code compatible with prior versions of the library when the library was used
3232
as described in the documentation. This change greatly simplifies the type hierarchy of the Kotlin builders.
3333
([#446](https://github.com/mybatis/mybatis-dynamic-sql/pull/446))
34+
6. Minor update the Kotlin join DSL to make it closer to natural SQL. The existing join methods are deprecated and
35+
will be removed in version 1.5.0. ([#447](https://github.com/mybatis/mybatis-dynamic-sql/pull/447))
3436

3537
## Release 1.3.1 - December 18, 2021
3638

src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.mybatis.dynamic.sql.util.kotlin
1717

1818
import org.mybatis.dynamic.sql.BasicColumn
19+
import org.mybatis.dynamic.sql.SqlBuilder
1920
import org.mybatis.dynamic.sql.select.join.JoinCondition
2021
import org.mybatis.dynamic.sql.select.join.JoinCriterion
2122

@@ -27,6 +28,25 @@ class JoinCollector {
2728
val andJoinCriteria = mutableListOf<JoinCriterion>()
2829
private lateinit var internalOnCriterion: JoinCriterion
2930

31+
fun on(leftColumn: BasicColumn): RightColumnCollector = RightColumnCollector {
32+
internalOnCriterion = JoinCriterion.Builder()
33+
.withConnector("on")
34+
.withJoinColumn(leftColumn)
35+
.withJoinCondition(it)
36+
.build()
37+
}
38+
39+
fun and(leftColumn: BasicColumn): RightColumnCollector = RightColumnCollector {
40+
andJoinCriteria.add(
41+
JoinCriterion.Builder()
42+
.withConnector("and")
43+
.withJoinColumn(leftColumn)
44+
.withJoinCondition(it)
45+
.build()
46+
)
47+
}
48+
49+
@Deprecated("Please use: on(leftColumn) equalTo rightColumn")
3050
fun on(column: BasicColumn, condition: JoinCondition) {
3151
internalOnCriterion = JoinCriterion.Builder()
3252
.withConnector("on")
@@ -35,6 +55,7 @@ class JoinCollector {
3555
.build()
3656
}
3757

58+
@Deprecated("Please use: and(leftColumn) equalTo rightColumn")
3859
fun and(column: BasicColumn, condition: JoinCondition) {
3960
andJoinCriteria.add(
4061
JoinCriterion.Builder()
@@ -45,3 +66,7 @@ class JoinCollector {
4566
)
4667
}
4768
}
69+
70+
class RightColumnCollector(private val joinConditionConsumer: (JoinCondition) -> Unit) {
71+
infix fun equalTo(rightColumn: BasicColumn) = joinConditionConsumer.invoke(SqlBuilder.equalTo(rightColumn))
72+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ import org.mybatis.dynamic.sql.where.condition.IsNotNull
7676
import org.mybatis.dynamic.sql.where.condition.IsNull
7777

7878
// join support
79+
@Deprecated("Please use the infix function in the JoinCollector")
7980
fun equalTo(column: BasicColumn): EqualTo = SqlBuilder.equalTo(column)
8081

8182
// aggregate support

src/site/markdown/docs/kotlinMyBatis3.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -922,7 +922,7 @@ fun PersonWithAddressMapper.select(completer: SelectCompleter): List<PersonWithA
922922
) {
923923
from(person, "p")
924924
fullJoin(address) {
925-
on(person.addressId, equalTo(address.id))
925+
on(person.addressId) equalTo address.id
926926
}
927927
completer()
928928
}.run(this::selectMany)

src/site/markdown/docs/kotlinOverview.md

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -396,25 +396,35 @@ This method creates models or providers depending on which package is used:
396396
Select statement support enables the creation of methods that execute a query allowing a user to specify a where clause,
397397
join specifications, order by clauses, group by clauses, pagination clauses, etc.
398398

399-
The DSL for select statements looks like this:
399+
The full DSL for select statements looks like this:
400400

401401
```kotlin
402-
val selectStatement = select(id, firstName, lastName, birthDate, employed, occupation, addressId) {
403-
from(person)
404-
where { id isLessThan 5 }
405-
and {
406-
id isLessThan 4
407-
and {
408-
id isLessThan 3
409-
or { id isLessThan 2 }
410-
}
402+
val selectStatement = select(orderMaster.orderId, orderMaster.orderDate, orderDetail.lineNumber,
403+
orderDetail.description, orderDetail.quantity
404+
) {
405+
from(orderMaster, "om")
406+
join(orderDetail, "od") {
407+
on(orderMaster.orderId) equalTo orderDetail.orderId
408+
and(orderMaster.orderId) equalTo orderDetail.orderId
411409
}
412-
orderBy(id)
410+
where { orderMaster.orderId isEqualTo 1 }
411+
or {
412+
orderMaster.orderId isEqualTo 2
413+
and { orderDetail.quantity isLessThan 6 }
414+
}
415+
orderBy(orderMaster.orderId)
413416
limit(3)
414417
}
415418
```
416419

420+
In a select statement you must specify a table in a `from` clause. Everything else is optional.
421+
422+
Multiple join clauses can be specified if you need to join additional tables. In a join clause, you must
423+
specify an `on` condition, and you may specify additional `and` conditions as necessary. Full, left, right, inner,
424+
and outer joins are supported.
425+
417426
Where clauses can be of arbitrary complexity and support all SQL operators including exists operators, subqueries, etc.
427+
You can nest `and`, `or`, and `not` clauses as necessary in where clauses.
418428

419429
There is also a method that will create a "distinct" query (`select distinct ...`) as follows:
420430

src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonWithAddressMapperExtensions.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import examples.kotlin.mybatis3.canonical.PersonDynamicSqlSupport.id
2424
import examples.kotlin.mybatis3.canonical.PersonDynamicSqlSupport.lastName
2525
import examples.kotlin.mybatis3.canonical.PersonDynamicSqlSupport.occupation
2626
import org.mybatis.dynamic.sql.util.kotlin.SelectCompleter
27-
import org.mybatis.dynamic.sql.util.kotlin.elements.equalTo
2827
import org.mybatis.dynamic.sql.util.kotlin.mybatis3.select
2928
import org.mybatis.dynamic.sql.util.kotlin.mybatis3.selectDistinct
3029

@@ -36,7 +35,7 @@ fun PersonWithAddressMapper.selectOne(completer: SelectCompleter): PersonWithAdd
3635
select(columnList) {
3736
from(person)
3837
fullJoin(address) {
39-
on(person.addressId, equalTo(address.id))
38+
on(person.addressId) equalTo address.id
4039
}
4140
completer()
4241
}.run(this::selectOne)
@@ -45,7 +44,7 @@ fun PersonWithAddressMapper.select(completer: SelectCompleter): List<PersonWithA
4544
select(columnList) {
4645
from(person, "p")
4746
fullJoin(address) {
48-
on(person.addressId, equalTo(address.id))
47+
on(person.addressId) equalTo address.id
4948
}
5049
completer()
5150
}.run(this::selectMany)
@@ -54,7 +53,7 @@ fun PersonWithAddressMapper.selectDistinct(completer: SelectCompleter): List<Per
5453
selectDistinct(columnList) {
5554
from(person)
5655
fullJoin(address) {
57-
on(person.addressId, equalTo(address.id))
56+
on(person.addressId) equalTo address.id
5857
}
5958
completer()
6059
}.run(this::selectMany)

src/test/kotlin/examples/kotlin/mybatis3/general/GeneralKotlinTest.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ import org.assertj.core.api.Assertions.assertThat
4242
import org.assertj.core.api.Assertions.assertThatExceptionOfType
4343
import org.junit.jupiter.api.Test
4444
import org.mybatis.dynamic.sql.util.kotlin.elements.count
45-
import org.mybatis.dynamic.sql.util.kotlin.elements.equalTo
4645
import org.mybatis.dynamic.sql.util.kotlin.elements.insert
4746
import org.mybatis.dynamic.sql.util.kotlin.elements.insertMultiple
4847
import org.mybatis.dynamic.sql.util.kotlin.mybatis3.count
@@ -453,7 +452,7 @@ class GeneralKotlinTest {
453452
) {
454453
from(person)
455454
join(address) {
456-
on(addressId, equalTo(address.id))
455+
on(addressId) equalTo address.id
457456
}
458457
where { id isLessThan 4 }
459458
orderBy(id)
@@ -489,7 +488,7 @@ class GeneralKotlinTest {
489488
) {
490489
from(person)
491490
join(address) {
492-
on(addressId, equalTo(address.id))
491+
on(addressId) equalTo address.id
493492
}
494493
where { id isLessThan 5 }
495494
and {
@@ -530,7 +529,7 @@ class GeneralKotlinTest {
530529
) {
531530
from(person)
532531
join(address) {
533-
on(addressId, equalTo(address.id))
532+
on(addressId) equalTo address.id
534533
}
535534
where { id isEqualTo 5 }
536535
or {

0 commit comments

Comments
 (0)