Skip to content

Commit 0dbd06f

Browse files
committed
Add Kotlin Utility Functions to Avoid platform type issue
1 parent 13c8177 commit 0dbd06f

File tree

4 files changed

+42
-19
lines changed

4 files changed

+42
-19
lines changed

src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/mybatis3/UtilityFunctions.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.mybatis.dynamic.sql.util.kotlin.mybatis3
1717

18+
import org.mybatis.dynamic.sql.BasicColumn
1819
import org.mybatis.dynamic.sql.SqlBuilder
1920
import org.mybatis.dynamic.sql.SqlTable
2021
import org.mybatis.dynamic.sql.insert.InsertDSL
@@ -24,6 +25,7 @@ import org.mybatis.dynamic.sql.insert.render.MultiRowInsertStatementProvider
2425
import org.mybatis.dynamic.sql.render.RenderingStrategies
2526
import org.mybatis.dynamic.sql.select.QueryExpressionDSL
2627
import org.mybatis.dynamic.sql.select.SelectModel
28+
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider
2729
import org.mybatis.dynamic.sql.util.kotlin.DeleteCompleter
2830
import org.mybatis.dynamic.sql.util.kotlin.SelectCompleter
2931
import org.mybatis.dynamic.sql.util.kotlin.UpdateCompleter
@@ -50,3 +52,19 @@ fun QueryExpressionDSL.FromGatherer<SelectModel>.from(table: SqlTable, alias: St
5052

5153
fun update(table: SqlTable, complete: UpdateCompleter) =
5254
complete(SqlBuilder.update(table)).build().render(RenderingStrategies.MYBATIS3)
55+
56+
/**
57+
* Function to handle platform type issues. Use this function, instead of calling MyBatis3Utils directly, to
58+
* avoid having to specify a return type explicitly.
59+
*/
60+
fun <T> selectDistinct(mapper: (SelectStatementProvider) -> List<T>, selectList: Array<out BasicColumn>, table: SqlTable,
61+
completer: SelectCompleter): List<T> =
62+
MyBatis3Utils.selectDistinct(mapper, selectList, table, completer)
63+
64+
/**
65+
* Function to handle platform type issues. Use this function, instead of calling MyBatis3Utils directly, to
66+
* avoid having to specify a return type explicitly.
67+
*/
68+
fun <T> selectList(mapper: (SelectStatementProvider) -> List<T>, selectList: Array<out BasicColumn>, table: SqlTable,
69+
completer: SelectCompleter): List<T> =
70+
MyBatis3Utils.selectList(mapper, selectList, table, completer)

src/site/markdown/docs/kotlin.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ interface PersonMapper {
5454
And then extensions could be added to make a shortcut method as follows:
5555

5656
```kotlin
57-
private val selectList = arrayOf(id.`as`("A_ID"), firstName, lastName, birthDate, employed, occupation, addressId)
57+
private val columnList = arrayOf(id.`as`("A_ID"), firstName, lastName, birthDate, employed, occupation, addressId)
5858

5959
fun PersonMapper.select(completer: SelectCompleter): List<PersonRecord> =
60-
MyBatis3Utils.selectList(this::selectMany, selectList, Person, completer)
60+
selectList(this::selectMany, columnList, Person, completer)
6161
```
6262

6363
The extension method shows the use of the `SelectCompleter` type alias. This is a DSL extension supplied with the library. We will detail its use below. For now see that the extension method can be used in client code as follows:
@@ -251,19 +251,19 @@ interface PersonMapper {
251251
These methods can be used to create simplified select methods with Kotlin extension methods:
252252

253253
```kotlin
254-
private val selectList = arrayOf(id.`as`("A_ID"), firstName, lastName, birthDate, employed, occupation, addressId)
254+
private val columnList = arrayOf(id.`as`("A_ID"), firstName, lastName, birthDate, employed, occupation, addressId)
255255

256256
fun PersonMapper.selectOne(completer: SelectCompleter) =
257-
MyBatis3Utils.selectOne(this::selectOne, selectList, Person, completer)
257+
MyBatis3Utils.selectOne(this::selectOne, columnList, Person, completer)
258258

259-
fun PersonMapper.select(completer: SelectCompleter): List<PersonRecord> =
260-
MyBatis3Utils.selectList(this::selectMany, selectList, Person, completer)
259+
fun PersonMapper.select(completer: SelectCompleter) =
260+
selectList(this::selectMany, columnList, Person, completer)
261261

262-
fun PersonMapper.selectDistinct(completer: SelectCompleter): List<PersonRecord> =
263-
MyBatis3Utils.selectDistinct(this::selectMany, selectList, Person, completer)
262+
fun PersonMapper.selectDistinct(completer: SelectCompleter) =
263+
selectDistinct(this::selectMany, columnList, Person, completer)
264264
```
265265

266-
These methods show the use of `SelectCompleter` which is a which is a Kotlin typealias for a function with a receiver that will allow a user to supply a where clause. The `selectMany` method can be used to implement generalized select methods where a user can specify a where clause and/or an order by clause. Typically we recommend two of these methods - for select, and select distinct. The `selectOne` method is used to create a generalized select method where a user can specify a where clause.
266+
These methods show the use of `SelectCompleter` which is a which is a Kotlin typealias for a function with a receiver that will allow a user to supply a where clause. The `selectMany` method can be used to implement generalized select methods where a user can specify a where clause and/or an order by clause. Typically we recommend two of these methods - for select, and select distinct. The `selectOne` method is used to create a generalized select method where a user can specify a where clause. These methods also show the use of the built in Kotlin functions `selectDistinct` and `selectList`. These functions help to avoid platform type issues in Kotlin and enable the Kotlin compiler to correctly infer the result type (`List<PersonRecord>` in this case).
267267

268268
The general `selectOne` method can also be used to implement a `selectByPrimaryKey` method:
269269

src/test/kotlin/examples/kotlin/canonical/PersonMapperExtensions.kt

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,14 @@ import examples.kotlin.canonical.PersonDynamicSqlSupport.Person.occupation
2626
import org.mybatis.dynamic.sql.SqlBuilder.isEqualTo
2727
import org.mybatis.dynamic.sql.update.UpdateDSL
2828
import org.mybatis.dynamic.sql.update.UpdateModel
29-
import org.mybatis.dynamic.sql.util.kotlin.*
29+
import org.mybatis.dynamic.sql.util.kotlin.CountCompleter
30+
import org.mybatis.dynamic.sql.util.kotlin.DeleteCompleter
31+
import org.mybatis.dynamic.sql.util.kotlin.SelectCompleter
32+
import org.mybatis.dynamic.sql.util.kotlin.UpdateCompleter
3033
import org.mybatis.dynamic.sql.util.kotlin.mybatis3.insert
3134
import org.mybatis.dynamic.sql.util.kotlin.mybatis3.insertMultiple
35+
import org.mybatis.dynamic.sql.util.kotlin.mybatis3.selectDistinct
36+
import org.mybatis.dynamic.sql.util.kotlin.mybatis3.selectList
3237
import org.mybatis.dynamic.sql.util.mybatis3.MyBatis3Utils
3338

3439
fun PersonMapper.count(completer: CountCompleter) =
@@ -78,16 +83,16 @@ fun PersonMapper.insertSelective(record: PersonRecord) =
7883
map(addressId).toPropertyWhenPresent("addressId", record::addressId)
7984
}
8085

81-
private val selectList = arrayOf(id.`as`("A_ID"), firstName, lastName, birthDate, employed, occupation, addressId)
86+
private val columnList = arrayOf(id.`as`("A_ID"), firstName, lastName, birthDate, employed, occupation, addressId)
8287

8388
fun PersonMapper.selectOne(completer: SelectCompleter) =
84-
MyBatis3Utils.selectOne(this::selectOne, selectList, Person, completer)
89+
MyBatis3Utils.selectOne(this::selectOne, columnList, Person, completer)
8590

86-
fun PersonMapper.select(completer: SelectCompleter): List<PersonRecord> =
87-
MyBatis3Utils.selectList(this::selectMany, selectList, Person, completer)
91+
fun PersonMapper.select(completer: SelectCompleter) =
92+
selectList(this::selectMany, columnList, Person, completer)
8893

89-
fun PersonMapper.selectDistinct(completer: SelectCompleter): List<PersonRecord> =
90-
MyBatis3Utils.selectDistinct(this::selectMany, selectList, Person, completer)
94+
fun PersonMapper.selectDistinct(completer: SelectCompleter) =
95+
selectDistinct(this::selectMany, columnList, Person, completer)
9196

9297
fun PersonMapper.selectByPrimaryKey(id_: Int) =
9398
selectOne {

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ import org.mybatis.dynamic.sql.util.kotlin.fromJoining
2929
import org.mybatis.dynamic.sql.util.kotlin.fullJoin
3030
import org.mybatis.dynamic.sql.util.mybatis3.MyBatis3Utils
3131

32-
private val selectList = arrayOf(id.`as`("A_ID"), firstName, lastName, birthDate, employed, occupation, Address.id,
32+
private val columnList = arrayOf(id.`as`("A_ID"), firstName, lastName, birthDate, employed, occupation, Address.id,
3333
Address.streetAddress, Address.city, Address.state)
3434

3535
fun PersonWithAddressMapper.selectOne(completer: SelectCompleter): PersonWithAddress? {
36-
val start = select(*selectList).fromJoining(Person) {
36+
val start = select(*columnList).fromJoining(Person) {
3737
fullJoin(Address) {
3838
on(Person.addressId, equalTo(Address.id))
3939
}
@@ -43,7 +43,7 @@ fun PersonWithAddressMapper.selectOne(completer: SelectCompleter): PersonWithAdd
4343
}
4444

4545
fun PersonWithAddressMapper.select(completer: SelectCompleter): List<PersonWithAddress> {
46-
val start = select(*selectList).fromJoining(Person, "p") {
46+
val start = select(*columnList).fromJoining(Person, "p") {
4747
fullJoin(Address) {
4848
on(Person.addressId, equalTo(Address.id))
4949
}

0 commit comments

Comments
 (0)