Skip to content

Commit 6b4b900

Browse files
committed
Basic support for generated keys in Spring
1 parent 59ba4fd commit 6b4b900

File tree

9 files changed

+86
-21
lines changed

9 files changed

+86
-21
lines changed

src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertModel.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2016-2019 the original author or authors.
2+
* Copyright 2016-2020 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.
@@ -17,6 +17,7 @@
1717

1818
import java.util.Collection;
1919

20+
import org.jetbrains.annotations.NotNull;
2021
import org.mybatis.dynamic.sql.insert.render.BatchInsert;
2122
import org.mybatis.dynamic.sql.insert.render.BatchInsertRenderer;
2223
import org.mybatis.dynamic.sql.render.RenderingStrategy;
@@ -27,6 +28,7 @@ private BatchInsertModel(Builder<T> builder) {
2728
super(builder);
2829
}
2930

31+
@NotNull
3032
public BatchInsert<T> render(RenderingStrategy renderingStrategy) {
3133
return BatchInsertRenderer.withBatchInsertModel(this)
3234
.withRenderingStrategy(renderingStrategy)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2016-2017 the original author or authors.
2+
* Copyright 2016-2020 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.

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

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

18+
import org.mybatis.dynamic.sql.insert.BatchInsertDSL
19+
import org.mybatis.dynamic.sql.insert.BatchInsertModel
1820
import org.mybatis.dynamic.sql.insert.GeneralInsertDSL
1921
import org.mybatis.dynamic.sql.insert.GeneralInsertModel
2022
import org.mybatis.dynamic.sql.insert.InsertDSL
@@ -28,3 +30,5 @@ typealias GeneralInsertCompleter = GeneralInsertDSL.() -> Buildable<GeneralInser
2830
typealias InsertCompleter<T> = InsertDSL<T>.() -> Buildable<InsertModel<T>>
2931

3032
typealias MultiRowInsertCompleter<T> = MultiRowInsertDSL<T>.() -> Buildable<MultiRowInsertModel<T>>
33+
34+
typealias BatchInsertCompleter<T> = BatchInsertDSL<T>.() -> Buildable<BatchInsertModel<T>>

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import org.mybatis.dynamic.sql.BasicColumn
2121
import org.mybatis.dynamic.sql.SqlBuilder
2222
import org.mybatis.dynamic.sql.SqlTable
2323
import org.mybatis.dynamic.sql.delete.render.DeleteStatementProvider
24+
import org.mybatis.dynamic.sql.insert.render.BatchInsert
2425
import org.mybatis.dynamic.sql.insert.render.GeneralInsertStatementProvider
2526
import org.mybatis.dynamic.sql.insert.render.InsertStatementProvider
2627
import org.mybatis.dynamic.sql.insert.render.MultiRowInsertStatementProvider
@@ -39,6 +40,7 @@ import org.springframework.dao.EmptyResultDataAccessException
3940
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource
4041
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource
4142
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
43+
import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils
4244
import org.springframework.jdbc.support.KeyHolder
4345
import java.sql.ResultSet
4446

@@ -60,10 +62,17 @@ fun NamedParameterJdbcTemplate.delete(deleteStatement: DeleteStatementProvider)
6062
fun NamedParameterJdbcTemplate.deleteFrom(table: SqlTable, completer: DeleteCompleter) =
6163
delete(org.mybatis.dynamic.sql.util.kotlin.spring.deleteFrom(table, completer))
6264

65+
// batch insert
66+
fun <T> NamedParameterJdbcTemplate.insert(insertStatement: BatchInsert<T>): IntArray =
67+
batchUpdate(insertStatement.insertStatementSQL, SqlParameterSourceUtils.createBatch(insertStatement.records))
68+
6369
// single record insert
6470
fun <T> NamedParameterJdbcTemplate.insert(insertStatement: InsertStatementProvider<T>) =
6571
update(insertStatement.insertStatement, BeanPropertySqlParameterSource(insertStatement.record))
6672

73+
fun <T> NamedParameterJdbcTemplate.insert(insertStatement: InsertStatementProvider<T>, keyHolder: KeyHolder) =
74+
update(insertStatement.insertStatement, BeanPropertySqlParameterSource(insertStatement.record), keyHolder)
75+
6776
fun <T> NamedParameterJdbcTemplate.insert(record: T) =
6877
SingleRowInsertHelper(record, this)
6978

@@ -94,6 +103,10 @@ fun <T> NamedParameterJdbcTemplate.insertMultiple(records: List<T>) =
94103
fun <T> NamedParameterJdbcTemplate.insertMultiple(insertStatement: MultiRowInsertStatementProvider<T>) =
95104
update(insertStatement.insertStatement, BeanPropertySqlParameterSource(insertStatement))
96105

106+
fun <T> NamedParameterJdbcTemplate.insertMultiple(insertStatement: MultiRowInsertStatementProvider<T>,
107+
keyHolder: KeyHolder) =
108+
update(insertStatement.insertStatement, BeanPropertySqlParameterSource(insertStatement), keyHolder)
109+
97110
fun NamedParameterJdbcTemplate.select(vararg selectList: BasicColumn) =
98111
SelectListFromGatherer(selectList.toList(), this)
99112

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@ package org.mybatis.dynamic.sql.util.kotlin.spring
1717

1818
import org.mybatis.dynamic.sql.SqlBuilder
1919
import org.mybatis.dynamic.sql.SqlTable
20+
import org.mybatis.dynamic.sql.insert.BatchInsertDSL
2021
import org.mybatis.dynamic.sql.insert.GeneralInsertDSL
2122
import org.mybatis.dynamic.sql.insert.InsertDSL
2223
import org.mybatis.dynamic.sql.insert.MultiRowInsertDSL
2324
import org.mybatis.dynamic.sql.render.RenderingStrategies
2425
import org.mybatis.dynamic.sql.select.CountDSL
2526
import org.mybatis.dynamic.sql.select.QueryExpressionDSL
2627
import org.mybatis.dynamic.sql.select.SelectModel
28+
import org.mybatis.dynamic.sql.util.kotlin.BatchInsertCompleter
2729
import org.mybatis.dynamic.sql.util.kotlin.CountCompleter
2830
import org.mybatis.dynamic.sql.util.kotlin.DeleteCompleter
2931
import org.mybatis.dynamic.sql.util.kotlin.GeneralInsertCompleter
@@ -44,6 +46,9 @@ fun deleteFrom(table: SqlTable, completer: DeleteCompleter) =
4446
completer(KotlinDeleteBuilder(SqlBuilder.deleteFrom(table))).build()
4547
.render(RenderingStrategies.SPRING_NAMED_PARAMETER)
4648

49+
fun <T> BatchInsertDSL.IntoGatherer<T>.into(table: SqlTable, completer: BatchInsertCompleter<T>) =
50+
completer(into(table)).build().render(RenderingStrategies.SPRING_NAMED_PARAMETER)
51+
4752
fun <T> InsertDSL.IntoGatherer<T>.into(table: SqlTable, completer: InsertCompleter<T>) =
4853
completer(into(table)).build().render(RenderingStrategies.SPRING_NAMED_PARAMETER)
4954

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

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

1818
import examples.kotlin.spring.canonical.AddressDynamicSqlSupport.Address
19-
import examples.kotlin.spring.canonical.GeneratedAlwaysDynamicSqlSupport.GeneratedAlways
2019
import examples.kotlin.spring.canonical.PersonDynamicSqlSupport.Person
2120
import examples.kotlin.spring.canonical.PersonDynamicSqlSupport.Person.addressId
2221
import examples.kotlin.spring.canonical.PersonDynamicSqlSupport.Person.birthDate
@@ -33,15 +32,14 @@ import org.mybatis.dynamic.sql.util.kotlin.spring.*
3332
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
3433
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder
3534
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType
36-
import org.springframework.jdbc.support.GeneratedKeyHolder
3735
import java.util.*
3836

3937
class CanonicalSpringKotlinTemplateDirectTest {
4038
private lateinit var template: NamedParameterJdbcTemplate
4139

4240
@BeforeEach
4341
fun setup() {
44-
val db = EmbeddedDatabaseBuilder().run {
42+
val db = with(EmbeddedDatabaseBuilder()) {
4543
setType(EmbeddedDatabaseType.HSQL)
4644
generateUniqueName(true)
4745
addScript("classpath:/examples/kotlin/spring/CreateGeneratedAlwaysDB.sql")
@@ -233,16 +231,6 @@ class CanonicalSpringKotlinTemplateDirectTest {
233231
}
234232

235233
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")
246234
TODO()
247235
}
248236

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

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
3434
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder
3535
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType
3636
import org.springframework.jdbc.support.GeneratedKeyHolder
37-
import org.springframework.jdbc.support.KeyHolder
3837
import java.util.*
3938

4039
@Suppress("LargeClass", "MaxLineLength")
@@ -43,7 +42,7 @@ class CanonicalSpringKotlinTest {
4342

4443
@BeforeEach
4544
fun setup() {
46-
val db = EmbeddedDatabaseBuilder().run {
45+
val db = with(EmbeddedDatabaseBuilder()) {
4746
setType(EmbeddedDatabaseType.HSQL)
4847
generateUniqueName(true)
4948
addScript("classpath:/examples/kotlin/spring/CreateGeneratedAlwaysDB.sql")
@@ -315,8 +314,25 @@ class CanonicalSpringKotlinTest {
315314
assertThat(rows).isEqualTo(2)
316315
}
317316

317+
@Test
318318
fun testBatchInsert() {
319-
TODO()
319+
val record1 = PersonRecord(100, "Joe", LastName("Jones"), Date(), true, "Developer", 1)
320+
val record2 = PersonRecord(101, "Sarah", LastName("Smith"), Date(), true, "Architect", 2)
321+
322+
val insertStatement = insert(record1, record2).into(Person) {
323+
map(id).toProperty("id")
324+
map(firstName).toProperty("firstName")
325+
map(lastName).toProperty("lastNameAsString")
326+
map(birthDate).toProperty("birthDate")
327+
map(employed).toProperty("employedAsString")
328+
map(occupation).toProperty("occupation")
329+
map(addressId).toProperty("addressId")
330+
}
331+
332+
val rows = template.insert(insertStatement)
333+
assertThat(rows).hasSize(2)
334+
assertThat(rows[0]).isEqualTo(1)
335+
assertThat(rows[1]).isEqualTo(1)
320336
}
321337

322338
@Test
@@ -334,12 +350,42 @@ class CanonicalSpringKotlinTest {
334350
assertThat(keyHolder.keys).containsEntry("FULL_NAME", "Fred Flintstone")
335351
}
336352

353+
@Test
337354
fun testInsertWithGeneratedKey() {
338-
TODO()
355+
val record = GeneratedAlwaysRecord(firstName = "Fred", lastName = "Flintstone")
356+
357+
val insertStatement = insert(record).into(GeneratedAlways) {
358+
map(firstName).toProperty("firstName")
359+
map(lastName).toProperty("lastName")
360+
}
361+
362+
val keyHolder = GeneratedKeyHolder()
363+
364+
val rows = template.insert(insertStatement, keyHolder)
365+
assertThat(rows).isEqualTo(1)
366+
assertThat(keyHolder.keys).containsEntry("ID", 22)
367+
assertThat(keyHolder.keys).containsEntry("FULL_NAME", "Fred Flintstone")
339368
}
340369

370+
@Test
341371
fun testMultiRowInsertWithGeneratedKey() {
342-
TODO()
372+
val record1 = GeneratedAlwaysRecord(firstName = "Fred", lastName = "Flintstone")
373+
val record2 = GeneratedAlwaysRecord(firstName = "Barney", lastName = "Rubble")
374+
375+
val insertStatement = insertMultiple(record1, record2)
376+
.into(GeneratedAlways) {
377+
map(firstName).toProperty("firstName")
378+
map(lastName).toProperty("lastName")
379+
}
380+
381+
val keyHolder = GeneratedKeyHolder()
382+
383+
val rows = template.insertMultiple(insertStatement, keyHolder)
384+
assertThat(rows).isEqualTo(2)
385+
assertThat(keyHolder.keyList[0]).containsEntry("ID", 22)
386+
assertThat(keyHolder.keyList[0]).containsEntry("FULL_NAME", "Fred Flintstone")
387+
assertThat(keyHolder.keyList[1]).containsEntry("ID", 23)
388+
assertThat(keyHolder.keyList[1]).containsEntry("FULL_NAME", "Barney Rubble")
343389
}
344390

345391
@Test

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,10 @@ data class AddressRecord(
5858
var city: String? = null,
5959
var state: String? = null
6060
)
61+
62+
data class GeneratedAlwaysRecord (
63+
var id: Int? = null,
64+
var firstName: String? = null,
65+
var lastName: String? = null,
66+
var fullName: String? = null
67+
)

src/test/resources/examples/kotlin/spring/CreateGeneratedAlwaysDB.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--
2-
-- Copyright 2016-2019 the original author or authors.
2+
-- Copyright 2016-2020 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.

0 commit comments

Comments
 (0)