Skip to content

Commit 59ba4fd

Browse files
committed
Start work on KeyHolder support in Kotlin
1 parent 2f3db58 commit 59ba4fd

File tree

7 files changed

+116
-31
lines changed

7 files changed

+116
-31
lines changed

src/main/java/org/mybatis/dynamic/sql/util/Buildable.java

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

18+
import org.jetbrains.annotations.NotNull;
19+
1820
@FunctionalInterface
1921
public interface Buildable<T> {
22+
@NotNull
2023
T build();
2124
}

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

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

18-
import org.mybatis.dynamic.sql.SqlBuilder
19-
import org.mybatis.dynamic.sql.SqlTable
2018
import org.mybatis.dynamic.sql.insert.GeneralInsertDSL
2119
import org.mybatis.dynamic.sql.insert.GeneralInsertModel
2220
import org.mybatis.dynamic.sql.insert.InsertDSL
2321
import org.mybatis.dynamic.sql.insert.InsertModel
2422
import org.mybatis.dynamic.sql.insert.MultiRowInsertDSL
2523
import org.mybatis.dynamic.sql.insert.MultiRowInsertModel
2624
import org.mybatis.dynamic.sql.util.Buildable
27-
import org.mybatis.dynamic.sql.util.kotlin.spring.insert
28-
import org.mybatis.dynamic.sql.util.kotlin.spring.insertMultiple
29-
import org.mybatis.dynamic.sql.util.kotlin.spring.into
30-
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
3125

3226
typealias GeneralInsertCompleter = GeneralInsertDSL.() -> Buildable<GeneralInsertModel>
3327

3428
typealias InsertCompleter<T> = InsertDSL<T>.() -> Buildable<InsertModel<T>>
3529

3630
typealias MultiRowInsertCompleter<T> = MultiRowInsertDSL<T>.() -> Buildable<MultiRowInsertModel<T>>
37-
38-
@MyBatisDslMarker
39-
class MultiRowInsertHelper<T>(private val records: List<T>, private val template: NamedParameterJdbcTemplate) {
40-
fun into(table: SqlTable, completer: MultiRowInsertCompleter<T>) =
41-
template.insertMultiple(SqlBuilder.insertMultiple(records).into(table, completer))
42-
}
43-
44-
@MyBatisDslMarker
45-
class SingleRowInsertHelper<T>(private val record: T, private val template: NamedParameterJdbcTemplate) {
46-
fun into(table: SqlTable, completer: InsertCompleter<T>) =
47-
template.insert(SqlBuilder.insert(record).into(table, completer))
48-
}

src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/spring/NamedParameterJdbcTemplateExtensions.kt

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,15 @@ import org.mybatis.dynamic.sql.util.kotlin.CountCompleter
3131
import org.mybatis.dynamic.sql.util.kotlin.DeleteCompleter
3232
import org.mybatis.dynamic.sql.util.kotlin.GeneralInsertCompleter
3333
import org.mybatis.dynamic.sql.util.kotlin.InsertCompleter
34-
import org.mybatis.dynamic.sql.util.kotlin.MultiRowInsertHelper
34+
import org.mybatis.dynamic.sql.util.kotlin.MultiRowInsertCompleter
35+
import org.mybatis.dynamic.sql.util.kotlin.MyBatisDslMarker
3536
import org.mybatis.dynamic.sql.util.kotlin.SelectCompleter
36-
import org.mybatis.dynamic.sql.util.kotlin.SingleRowInsertHelper
3737
import org.mybatis.dynamic.sql.util.kotlin.UpdateCompleter
3838
import org.springframework.dao.EmptyResultDataAccessException
3939
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource
40+
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource
4041
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
42+
import org.springframework.jdbc.support.KeyHolder
4143
import java.sql.ResultSet
4244

4345
fun NamedParameterJdbcTemplate.count(selectStatement: SelectStatementProvider) =
@@ -76,6 +78,9 @@ fun <T> NamedParameterJdbcTemplate.insert(record: T, table: SqlTable, completer:
7678
fun NamedParameterJdbcTemplate.insert(insertStatement: GeneralInsertStatementProvider) =
7779
update(insertStatement.insertStatement, insertStatement.parameters)
7880

81+
fun NamedParameterJdbcTemplate.insert(insertStatement: GeneralInsertStatementProvider, keyHolder: KeyHolder) =
82+
update(insertStatement.insertStatement, MapSqlParameterSource(insertStatement.parameters), keyHolder)
83+
7984
fun NamedParameterJdbcTemplate.insertInto(table: SqlTable, completer: GeneralInsertCompleter) =
8085
insert(org.mybatis.dynamic.sql.util.kotlin.spring.insertInto(table, completer))
8186

@@ -185,3 +190,15 @@ class SelectOneMapperGatherer(
185190
fun <T> withRowMapper(rowMapper: (rs: ResultSet, rowNum: Int) -> T) =
186191
template.selectOne(selectStatement, rowMapper)
187192
}
193+
194+
@MyBatisDslMarker
195+
class MultiRowInsertHelper<T>(private val records: List<T>, private val template: NamedParameterJdbcTemplate) {
196+
fun into(table: SqlTable, completer: MultiRowInsertCompleter<T>) =
197+
template.insertMultiple(SqlBuilder.insertMultiple(records).into(table, completer))
198+
}
199+
200+
@MyBatisDslMarker
201+
class SingleRowInsertHelper<T>(private val record: T, private val template: NamedParameterJdbcTemplate) {
202+
fun into(table: SqlTable, completer: InsertCompleter<T>) =
203+
template.insert(SqlBuilder.insert(record).into(table, completer))
204+
}

src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTemplateDirectTest.kt

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package examples.kotlin.spring.canonical
1717

1818
import examples.kotlin.spring.canonical.AddressDynamicSqlSupport.Address
19+
import examples.kotlin.spring.canonical.GeneratedAlwaysDynamicSqlSupport.GeneratedAlways
1920
import examples.kotlin.spring.canonical.PersonDynamicSqlSupport.Person
2021
import examples.kotlin.spring.canonical.PersonDynamicSqlSupport.Person.addressId
2122
import examples.kotlin.spring.canonical.PersonDynamicSqlSupport.Person.birthDate
@@ -32,18 +33,21 @@ import org.mybatis.dynamic.sql.util.kotlin.spring.*
3233
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
3334
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder
3435
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType
36+
import org.springframework.jdbc.support.GeneratedKeyHolder
3537
import java.util.*
3638

3739
class CanonicalSpringKotlinTemplateDirectTest {
3840
private lateinit var template: NamedParameterJdbcTemplate
3941

4042
@BeforeEach
4143
fun setup() {
42-
val db = EmbeddedDatabaseBuilder()
43-
.setType(EmbeddedDatabaseType.HSQL)
44-
.generateUniqueName(true)
45-
.addScript("classpath:/examples/kotlin/spring/CreateSimpleDB.sql")
46-
.build()
44+
val db = EmbeddedDatabaseBuilder().run {
45+
setType(EmbeddedDatabaseType.HSQL)
46+
generateUniqueName(true)
47+
addScript("classpath:/examples/kotlin/spring/CreateGeneratedAlwaysDB.sql")
48+
addScript("classpath:/examples/kotlin/spring/CreateSimpleDB.sql")
49+
build()
50+
}
4751
template = NamedParameterJdbcTemplate(db)
4852
}
4953

@@ -229,6 +233,16 @@ class CanonicalSpringKotlinTemplateDirectTest {
229233
}
230234

231235
fun testGeneralInsertWithGeneratedKey() {
236+
// val keyHolder = GeneratedKeyHolder()
237+
//
238+
// val rows = template.insertInto(GeneratedAlways) {
239+
// set(GeneratedAlways.firstName).toValue("Fred")
240+
// set(GeneratedAlways.lastName).toValue("Flintstone")
241+
// }.withKeyHolder(keyHolder)
242+
//
243+
// assertThat(rows).isEqualTo(1)
244+
// assertThat(keyHolder.keys).containsEntry("ID", 22)
245+
// assertThat(keyHolder.keys).containsEntry("FULL_NAME", "Fred Flintstone")
232246
TODO()
233247
}
234248

src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package examples.kotlin.spring.canonical
1717

1818
import examples.kotlin.spring.canonical.AddressDynamicSqlSupport.Address
19+
import examples.kotlin.spring.canonical.GeneratedAlwaysDynamicSqlSupport.GeneratedAlways
1920
import examples.kotlin.spring.canonical.PersonDynamicSqlSupport.Person
2021
import examples.kotlin.spring.canonical.PersonDynamicSqlSupport.Person.addressId
2122
import examples.kotlin.spring.canonical.PersonDynamicSqlSupport.Person.birthDate
@@ -32,6 +33,8 @@ import org.mybatis.dynamic.sql.util.kotlin.spring.*
3233
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
3334
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder
3435
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType
36+
import org.springframework.jdbc.support.GeneratedKeyHolder
37+
import org.springframework.jdbc.support.KeyHolder
3538
import java.util.*
3639

3740
@Suppress("LargeClass", "MaxLineLength")
@@ -40,11 +43,13 @@ class CanonicalSpringKotlinTest {
4043

4144
@BeforeEach
4245
fun setup() {
43-
val db = EmbeddedDatabaseBuilder()
44-
.setType(EmbeddedDatabaseType.HSQL)
45-
.generateUniqueName(true)
46-
.addScript("classpath:/examples/kotlin/spring/CreateSimpleDB.sql")
47-
.build()
46+
val db = EmbeddedDatabaseBuilder().run {
47+
setType(EmbeddedDatabaseType.HSQL)
48+
generateUniqueName(true)
49+
addScript("classpath:/examples/kotlin/spring/CreateGeneratedAlwaysDB.sql")
50+
addScript("classpath:/examples/kotlin/spring/CreateSimpleDB.sql")
51+
build()
52+
}
4853
template = NamedParameterJdbcTemplate(db)
4954
}
5055

@@ -314,8 +319,19 @@ class CanonicalSpringKotlinTest {
314319
TODO()
315320
}
316321

322+
@Test
317323
fun testGeneralInsertWithGeneratedKey() {
318-
TODO()
324+
val insertStatement = insertInto(GeneratedAlways) {
325+
set(GeneratedAlways.firstName).toValue("Fred")
326+
set(GeneratedAlways.lastName).toValue("Flintstone")
327+
}
328+
329+
val keyHolder = GeneratedKeyHolder()
330+
331+
val rows = template.insert(insertStatement, keyHolder)
332+
assertThat(rows).isEqualTo(1)
333+
assertThat(keyHolder.keys).containsEntry("ID", 22)
334+
assertThat(keyHolder.keys).containsEntry("FULL_NAME", "Fred Flintstone")
319335
}
320336

321337
fun testInsertWithGeneratedKey() {
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* Copyright 2016-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package examples.kotlin.spring.canonical
17+
18+
import org.mybatis.dynamic.sql.SqlTable
19+
import java.sql.JDBCType
20+
21+
object GeneratedAlwaysDynamicSqlSupport {
22+
object GeneratedAlways : SqlTable("GeneratedAlways") {
23+
val id = column<Int>("id", JDBCType.INTEGER)
24+
val firstName = column<String>("first_name", JDBCType.VARCHAR)
25+
val lastName = column<String>("last_name", JDBCType.VARCHAR)
26+
val fullName = column<String>("full_name", JDBCType.VARCHAR)
27+
}
28+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--
2+
-- Copyright 2016-2019 the original author or authors.
3+
--
4+
-- Licensed under the Apache License, Version 2.0 (the "License");
5+
-- you may not use this file except in compliance with the License.
6+
-- You may obtain a copy of the License at
7+
--
8+
-- http://www.apache.org/licenses/LICENSE-2.0
9+
--
10+
-- Unless required by applicable law or agreed to in writing, software
11+
-- distributed under the License is distributed on an "AS IS" BASIS,
12+
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
-- See the License for the specific language governing permissions and
14+
-- limitations under the License.
15+
--
16+
17+
drop table GeneratedAlways if exists;
18+
19+
create table GeneratedAlways (
20+
id int generated by default as identity(start with 22),
21+
first_name varchar(30) not null,
22+
last_name varchar(30) not null,
23+
full_name varchar(61) generated always as (first_name || ' ' || last_name),
24+
primary key(id)
25+
);

0 commit comments

Comments
 (0)