Skip to content

Commit 6a57b76

Browse files
committed
Implement multi row insert for Kotlin
1 parent 6cb91e5 commit 6a57b76

File tree

7 files changed

+96
-24
lines changed

7 files changed

+96
-24
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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 org.mybatis.dynamic.sql.util.kotlin
17+
18+
import org.mybatis.dynamic.sql.SqlBuilder
19+
import org.mybatis.dynamic.sql.SqlTable
20+
import org.mybatis.dynamic.sql.insert.GeneralInsertDSL
21+
import org.mybatis.dynamic.sql.insert.GeneralInsertModel
22+
import org.mybatis.dynamic.sql.insert.InsertDSL
23+
import org.mybatis.dynamic.sql.insert.InsertModel
24+
import org.mybatis.dynamic.sql.insert.MultiRowInsertDSL
25+
import org.mybatis.dynamic.sql.insert.MultiRowInsertModel
26+
import org.mybatis.dynamic.sql.util.Buildable
27+
import org.mybatis.dynamic.sql.util.kotlin.spring.insertMultiple
28+
import org.mybatis.dynamic.sql.util.kotlin.spring.into
29+
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
30+
31+
typealias GeneralInsertCompleter = GeneralInsertDSL.() -> Buildable<GeneralInsertModel>
32+
33+
typealias InsertCompleter<T> = InsertDSL<T>.() -> Buildable<InsertModel<T>>
34+
35+
typealias MultiRowInsertCompleter<T> = MultiRowInsertDSL<T>.() -> Buildable<MultiRowInsertModel<T>>
36+
37+
@MyBatisDslMarker
38+
class MultiRowInsertHelper<T>(private val records: List<T>, private val template: NamedParameterJdbcTemplate) {
39+
fun into(table: SqlTable, completer: MultiRowInsertCompleter<T>) =
40+
template.insertMultiple(SqlBuilder.insertMultiple(records).into(table, completer))
41+
}
42+

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

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

1818
import org.mybatis.dynamic.sql.SqlColumn
19-
import org.mybatis.dynamic.sql.insert.GeneralInsertDSL
20-
import org.mybatis.dynamic.sql.insert.GeneralInsertModel
21-
import org.mybatis.dynamic.sql.insert.InsertDSL
22-
import org.mybatis.dynamic.sql.insert.InsertModel
23-
import org.mybatis.dynamic.sql.insert.MultiRowInsertDSL
24-
import org.mybatis.dynamic.sql.insert.MultiRowInsertModel
2519
import org.mybatis.dynamic.sql.update.UpdateDSL
2620
import org.mybatis.dynamic.sql.update.UpdateModel
2721
import org.mybatis.dynamic.sql.util.Buildable
2822

29-
// insert completers are here because sonar doesn't see them as covered if they are in a file by themselves
30-
typealias GeneralInsertCompleter = GeneralInsertDSL.() -> Buildable<GeneralInsertModel>
31-
32-
typealias InsertCompleter<T> = InsertDSL<T>.() -> Buildable<InsertModel<T>>
33-
34-
typealias MultiRowInsertCompleter<T> = MultiRowInsertDSL<T>.() -> Buildable<MultiRowInsertModel<T>>
35-
3623
typealias UpdateCompleter = KotlinUpdateBuilder.() -> Buildable<UpdateModel>
3724

3825
class KotlinUpdateBuilder(private val dsl: UpdateDSL<UpdateModel>) :

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@ import org.mybatis.dynamic.sql.SqlTable
2323
import org.mybatis.dynamic.sql.delete.render.DeleteStatementProvider
2424
import org.mybatis.dynamic.sql.insert.render.GeneralInsertStatementProvider
2525
import org.mybatis.dynamic.sql.insert.render.InsertStatementProvider
26+
import org.mybatis.dynamic.sql.insert.render.MultiRowInsertStatementProvider
2627
import org.mybatis.dynamic.sql.select.CountDSL
2728
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider
2829
import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider
2930
import org.mybatis.dynamic.sql.util.kotlin.CountCompleter
3031
import org.mybatis.dynamic.sql.util.kotlin.DeleteCompleter
3132
import org.mybatis.dynamic.sql.util.kotlin.GeneralInsertCompleter
3233
import org.mybatis.dynamic.sql.util.kotlin.InsertCompleter
34+
import org.mybatis.dynamic.sql.util.kotlin.MultiRowInsertHelper
3335
import org.mybatis.dynamic.sql.util.kotlin.SelectCompleter
3436
import org.mybatis.dynamic.sql.util.kotlin.UpdateCompleter
3537
import org.springframework.dao.EmptyResultDataAccessException
@@ -67,6 +69,15 @@ fun NamedParameterJdbcTemplate.insert(insertStatement: GeneralInsertStatementPro
6769
fun NamedParameterJdbcTemplate.insertInto(table: SqlTable, completer: GeneralInsertCompleter) =
6870
insert(org.mybatis.dynamic.sql.util.kotlin.spring.insertInto(table, completer))
6971

72+
fun <T> NamedParameterJdbcTemplate.insertMultiple(vararg records: T) =
73+
insertMultiple(records.asList())
74+
75+
fun <T> NamedParameterJdbcTemplate.insertMultiple(records: List<T>) =
76+
MultiRowInsertHelper(records, this)
77+
78+
fun <T> NamedParameterJdbcTemplate.insertMultiple(insertStatement: MultiRowInsertStatementProvider<T>) =
79+
update(insertStatement.insertStatement, BeanPropertySqlParameterSource(insertStatement))
80+
7081
fun NamedParameterJdbcTemplate.select(vararg selectList: BasicColumn) =
7182
SelectListFromGatherer(selectList.toList(), this)
7283

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
@@ -19,6 +19,7 @@ import org.mybatis.dynamic.sql.SqlBuilder
1919
import org.mybatis.dynamic.sql.SqlTable
2020
import org.mybatis.dynamic.sql.insert.GeneralInsertDSL
2121
import org.mybatis.dynamic.sql.insert.InsertDSL
22+
import org.mybatis.dynamic.sql.insert.MultiRowInsertDSL
2223
import org.mybatis.dynamic.sql.render.RenderingStrategies
2324
import org.mybatis.dynamic.sql.select.CountDSL
2425
import org.mybatis.dynamic.sql.select.QueryExpressionDSL
@@ -31,6 +32,7 @@ import org.mybatis.dynamic.sql.util.kotlin.KotlinCountBuilder
3132
import org.mybatis.dynamic.sql.util.kotlin.KotlinDeleteBuilder
3233
import org.mybatis.dynamic.sql.util.kotlin.KotlinQueryBuilder
3334
import org.mybatis.dynamic.sql.util.kotlin.KotlinUpdateBuilder
35+
import org.mybatis.dynamic.sql.util.kotlin.MultiRowInsertCompleter
3436
import org.mybatis.dynamic.sql.util.kotlin.SelectCompleter
3537
import org.mybatis.dynamic.sql.util.kotlin.UpdateCompleter
3638

@@ -45,6 +47,9 @@ fun deleteFrom(table: SqlTable, completer: DeleteCompleter) =
4547
fun <T> InsertDSL.IntoGatherer<T>.into(table: SqlTable, completer: InsertCompleter<T>) =
4648
completer(into(table)).build().render(RenderingStrategies.SPRING_NAMED_PARAMETER)
4749

50+
fun <T> MultiRowInsertDSL.IntoGatherer<T>.into(table: SqlTable, completer: MultiRowInsertCompleter<T>) =
51+
completer(into(table)).build().render(RenderingStrategies.SPRING_NAMED_PARAMETER)
52+
4853
fun CountDSL.FromGatherer<SelectModel>.from(table: SqlTable, completer: CountCompleter) =
4954
completer(KotlinCountBuilder(from(table))).build().render(RenderingStrategies.SPRING_NAMED_PARAMETER)
5055

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

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -191,25 +191,34 @@ class CanonicalSpringKotlinTemplateDirectTest {
191191

192192
@Test
193193
fun testMultiRowInsert() {
194-
TODO()
194+
val record1 = PersonRecord(100, "Joe", LastName("Jones"), Date(), true, "Developer", 1)
195+
val record2 = PersonRecord(101, "Sarah", LastName("Smith"), Date(), true, "Architect", 2)
196+
197+
val rows = template.insertMultiple(record1, record2).into(Person) {
198+
map(id).toProperty("id")
199+
map(firstName).toProperty("firstName")
200+
map(lastName).toProperty("lastNameAsString")
201+
map(birthDate).toProperty("birthDate")
202+
map(employed).toProperty("employedAsString")
203+
map(occupation).toProperty("occupation")
204+
map(addressId).toProperty("addressId")
205+
}
206+
207+
assertThat(rows).isEqualTo(2)
195208
}
196209

197-
@Test
198210
fun testBatchInsert() {
199211
TODO()
200212
}
201213

202-
@Test
203214
fun testGeneralInsertWithGeneratedKey() {
204215
TODO()
205216
}
206217

207-
@Test
208218
fun testInsertWithGeneratedKey() {
209219
TODO()
210220
}
211221

212-
@Test
213222
fun testMultiRowInsertWithGeneratedKey() {
214223
TODO()
215224
}

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

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -285,25 +285,43 @@ class CanonicalSpringKotlinTest {
285285

286286
@Test
287287
fun testMultiRowInsert() {
288-
TODO()
288+
val record1 = PersonRecord(100, "Joe", LastName("Jones"), Date(), true, "Developer", 1)
289+
val record2 = PersonRecord(101, "Sarah", LastName("Smith"), Date(), true, "Architect", 2)
290+
291+
val insertStatement = insertMultiple(record1, record2).into(Person) {
292+
map(id).toProperty("id")
293+
map(firstName).toProperty("firstName")
294+
map(lastName).toProperty("lastNameAsString")
295+
map(birthDate).toProperty("birthDate")
296+
map(employed).toProperty("employedAsString")
297+
map(occupation).toProperty("occupation")
298+
map(addressId).toProperty("addressId")
299+
}
300+
301+
assertThat(insertStatement.insertStatement).isEqualTo(
302+
"insert into Person (id, first_name, last_name, birth_date, employed, occupation, address_id) " +
303+
"values (:records[0].id, :records[0].firstName, :records[0].lastNameAsString, " +
304+
":records[0].birthDate, :records[0].employedAsString, :records[0].occupation, :records[0].addressId), " +
305+
"(:records[1].id, :records[1].firstName, :records[1].lastNameAsString, " +
306+
":records[1].birthDate, :records[1].employedAsString, :records[1].occupation, :records[1].addressId)"
307+
)
308+
309+
val rows = template.insertMultiple(insertStatement)
310+
assertThat(rows).isEqualTo(2)
289311
}
290312

291-
@Test
292313
fun testBatchInsert() {
293314
TODO()
294315
}
295316

296-
@Test
297317
fun testGeneralInsertWithGeneratedKey() {
298318
TODO()
299319
}
300320

301-
@Test
302321
fun testInsertWithGeneratedKey() {
303322
TODO()
304323
}
305324

306-
@Test
307325
fun testMultiRowInsertWithGeneratedKey() {
308326
TODO()
309327
}

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

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)