move repositories to separate db package

replace jacoco with kover
This commit is contained in:
Savosin Denis
2025-03-28 14:38:57 +07:00
parent 4f9ad14767
commit d7c051746d
37 changed files with 603 additions and 34 deletions

View File

@@ -1,40 +1,85 @@
plugins {
idea
alias(libs.plugins.kotlin.kover)
alias(libs.plugins.kotlin.jpa)
alias(libs.plugins.kotlin.jvm)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.kotlin.spring)
alias(libs.plugins.spring.boot)
alias(libs.plugins.spring.dependencyManagement)
jacoco
}
group = "com.github.dannecron.demo"
version = "single-version"
java {
allprojects {
apply {
plugin(rootProject.libs.plugins.kotlin.jvm.get().pluginId)
plugin(rootProject.libs.plugins.kotlin.serialization.get().pluginId)
plugin(rootProject.libs.plugins.kotlin.kover.get().pluginId)
plugin("java")
}
plugins.withId("org.jetbrains.kotlinx.kover") {
tasks.named("koverXmlReport") {
dependsOn(tasks.test)
}
}
java {
sourceCompatibility = JavaVersion.VERSION_17
}
kotlin {
compilerOptions {
freeCompilerArgs.addAll("-Xjsr305=strict")
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_1)
}
}
repositories {
mavenCentral()
}
dependencies {
implementation(rootProject.libs.kotlin.reflect)
implementation(rootProject.libs.kotlinx.serialization.json)
implementation(rootProject.libs.spring.aspects)
testImplementation(rootProject.libs.kotlin.test.junit)
testImplementation(rootProject.libs.mockito.kotlin)
testImplementation(rootProject.libs.spring.boot.starter.test)
kover(project(":db"))
}
tasks.test {
useJUnitPlatform()
finalizedBy("koverXmlReport")
}
}
repositories {
mavenCentral()
subprojects {
apply {
plugin(rootProject.libs.plugins.kotlin.spring.get().pluginId)
plugin(rootProject.libs.plugins.spring.boot.get().pluginId)
plugin(rootProject.libs.plugins.spring.dependencyManagement.get().pluginId)
}
}
dependencies {
implementation(project(":db"))
runtimeOnly(libs.micrometer.registry.prometheus)
implementation(libs.bundles.tracing)
implementation(libs.flyway.core)
implementation(libs.jackson.datatype.jsr)
implementation(libs.jackson.module.kotlin)
implementation(libs.json.schema.validator)
implementation(libs.kotlin.reflect)
implementation(libs.kotlinx.serialization.json)
implementation(libs.ktor.client.cio)
implementation(libs.ktor.client.core)
implementation(libs.logback.encoder)
implementation(libs.postgres)
implementation(libs.spring.aspects)
implementation(libs.spring.boot.starter.actuator)
implementation(libs.spring.boot.starter.jdbc)
implementation(libs.spring.boot.starter.mustache)
@@ -43,33 +88,10 @@ dependencies {
implementation(libs.spring.doc.openapi.starter)
implementation(libs.spring.kafka)
testImplementation(libs.kotlin.test.junit)
testImplementation(libs.mockito.kotlin)
testImplementation(libs.spring.boot.starter.test)
testImplementation(libs.spring.kafka.test)
testImplementation(libs.testcontainers)
testImplementation(libs.testcontainers.junit.jupiter)
testImplementation(libs.testcontainers.postgresql)
testImplementation(libs.ktor.client.mock)
developmentOnly(libs.spring.boot.devtools)
}
kotlin {
compilerOptions {
freeCompilerArgs.addAll("-Xjsr305=strict")
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_1)
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
tasks.test {
finalizedBy(tasks.jacocoTestReport) // report is always generated after tests run
}
tasks.jacocoTestReport {
dependsOn(tasks.test) // tests are required to run before generating the report
}

16
db/build.gradle.kts Normal file
View File

@@ -0,0 +1,16 @@
plugins {
alias(libs.plugins.kotlin.jpa)
}
group = "com.github.dannecron.demo"
version = "single-version"
dependencies {
implementation(rootProject.libs.flyway.core)
implementation(rootProject.libs.postgres)
implementation(rootProject.libs.spring.boot.starter.jdbc)
testImplementation(libs.testcontainers)
testImplementation(libs.testcontainers.junit.jupiter)
testImplementation(libs.testcontainers.postgresql)
}

View File

@@ -0,0 +1,31 @@
package com.github.dannecron.demo.db.entity
import com.github.dannecron.demo.db.serialialization.OffsetDateTimeSerialization
import com.github.dannecron.demo.db.serialialization.UuidSerialization
import kotlinx.serialization.Serializable
import org.springframework.data.annotation.Id
import org.springframework.data.relational.core.mapping.Column
import org.springframework.data.relational.core.mapping.Table
import java.time.OffsetDateTime
import java.util.UUID
@Table("city")
@Serializable
data class City(
@Id
val id: Long?,
@Serializable(with = UuidSerialization::class)
val guid: UUID,
val name: String,
@Serializable(with = OffsetDateTimeSerialization::class)
@Column(value = "created_at")
val createdAt: OffsetDateTime,
@Serializable(with = OffsetDateTimeSerialization::class)
@Column(value = "updated_at")
val updatedAt: OffsetDateTime?,
@Serializable(with = OffsetDateTimeSerialization::class)
@Column(value = "deleted_at")
val deletedAt: OffsetDateTime?,
) {
fun isDeleted(): Boolean = deletedAt != null
}

View File

@@ -0,0 +1,27 @@
package com.github.dannecron.demo.db.entity
import com.github.dannecron.demo.db.serialialization.OffsetDateTimeSerialization
import com.github.dannecron.demo.db.serialialization.UuidSerialization
import kotlinx.serialization.Serializable
import org.springframework.data.annotation.Id
import org.springframework.data.relational.core.mapping.Column
import org.springframework.data.relational.core.mapping.Table
import java.time.OffsetDateTime
import java.util.UUID
@Table("customer")
@Serializable
data class Customer(
@Id
val id: Long?,
@Serializable(with = UuidSerialization::class)
val guid: UUID,
val name: String,
val cityId: Long?,
@Serializable(with = OffsetDateTimeSerialization::class)
@Column(value = "created_at")
val createdAt: OffsetDateTime,
@Serializable(with = OffsetDateTimeSerialization::class)
@Column(value = "updated_at")
val updatedAt: OffsetDateTime?,
)

View File

@@ -0,0 +1,42 @@
package com.github.dannecron.demo.db.entity
import com.github.dannecron.demo.db.serialialization.OffsetDateTimeSerialization
import com.github.dannecron.demo.db.serialialization.UuidSerialization
import kotlinx.serialization.Serializable
import org.springframework.data.annotation.Id
import org.springframework.data.relational.core.mapping.Column
import org.springframework.data.relational.core.mapping.Table
import java.time.OffsetDateTime
import java.util.UUID
import kotlin.math.pow
import kotlin.math.roundToInt
@Table(value = "product")
@Serializable
data class Product(
@Id
val id: Long?,
@Serializable(with = UuidSerialization::class)
val guid: UUID,
val name: String,
val description: String?,
val price: Long,
@Serializable(with = OffsetDateTimeSerialization::class)
@Column(value = "created_at")
val createdAt: OffsetDateTime,
@Serializable(with = OffsetDateTimeSerialization::class)
@Column(value = "updated_at")
val updatedAt: OffsetDateTime?,
@Serializable(with = OffsetDateTimeSerialization::class)
@Column(value = "deleted_at")
val deletedAt: OffsetDateTime?,
) {
fun getPriceDouble(): Double = (price.toDouble() / 100).roundTo(2)
fun isDeleted(): Boolean = deletedAt != null
private fun Double.roundTo(numFractionDigits: Int): Double {
val factor = 10.0.pow(numFractionDigits.toDouble())
return (this * factor).roundToInt() / factor
}
}

View File

@@ -0,0 +1,31 @@
package com.github.dannecron.demo.db.entity.order
import com.github.dannecron.demo.db.serialialization.OffsetDateTimeSerialization
import com.github.dannecron.demo.db.serialialization.UuidSerialization
import kotlinx.serialization.Serializable
import org.springframework.data.annotation.Id
import org.springframework.data.relational.core.mapping.Column
import org.springframework.data.relational.core.mapping.Table
import java.time.OffsetDateTime
import java.util.UUID
@Table(value = "order")
@Serializable
data class Order(
@Id
val id: Long?,
@Serializable(with = UuidSerialization::class)
val guid: UUID,
val customerId: Long,
@Serializable(with = OffsetDateTimeSerialization::class)
@Column(value = "delivered_at")
val deliveredAt: OffsetDateTime?,
@Serializable(with = OffsetDateTimeSerialization::class)
@Column(value = "created_at")
val createdAt: OffsetDateTime,
@Serializable(with = OffsetDateTimeSerialization::class)
@Column(value = "updated_at")
val updatedAt: OffsetDateTime?
) {
fun isDelivered(): Boolean = deliveredAt != null
}

View File

@@ -0,0 +1,41 @@
package com.github.dannecron.demo.db.entity.order
import com.github.dannecron.demo.db.serialialization.OffsetDateTimeSerialization
import com.github.dannecron.demo.db.serialialization.UuidSerialization
import kotlinx.serialization.Serializable
import org.springframework.data.annotation.Id
import org.springframework.data.annotation.Transient
import org.springframework.data.domain.Persistable
import org.springframework.data.relational.core.mapping.Column
import org.springframework.data.relational.core.mapping.Table
import java.time.OffsetDateTime
import java.util.UUID
@Table(value = "order_product")
@Serializable
data class OrderProduct(
@Id
@Serializable(with = UuidSerialization::class)
val guid: UUID,
@Column(value = "order_id")
val orderId: Long,
@Column(value = "product_id")
val productId: Long,
@Serializable(with = OffsetDateTimeSerialization::class)
@Column(value = "created_at")
val createdAt: OffsetDateTime,
@Serializable(with = OffsetDateTimeSerialization::class)
@Column(value = "updated_at")
val updatedAt: OffsetDateTime?,
): Persistable<UUID> {
@Transient
var isNewInstance: Boolean? = null
override fun getId(): UUID {
return guid
}
override fun isNew(): Boolean {
return isNewInstance ?: true
}
}

View File

@@ -0,0 +1,17 @@
package com.github.dannecron.demo.db.repository
import com.github.dannecron.demo.db.entity.City
import org.springframework.data.jdbc.repository.query.Query
import org.springframework.data.repository.CrudRepository
import org.springframework.data.repository.query.Param
import org.springframework.stereotype.Repository
import java.time.OffsetDateTime
import java.util.UUID
@Repository
interface CityRepository: CrudRepository<City, Long> {
fun findByGuid(guid: UUID): City?
@Query(value = "UPDATE city SET deleted_at = :deletedAt WHERE guid = :guid RETURNING *")
fun softDelete(@Param("guid") guid: UUID, @Param("deletedAt") deletedAt: OffsetDateTime): City?
}

View File

@@ -0,0 +1,11 @@
package com.github.dannecron.demo.db.repository
import com.github.dannecron.demo.db.entity.Customer
import org.springframework.data.repository.CrudRepository
import org.springframework.stereotype.Repository
import java.util.UUID
@Repository
interface CustomerRepository: CrudRepository<Customer, Long> {
fun findByGuid(guid: UUID): Customer?
}

View File

@@ -0,0 +1,11 @@
package com.github.dannecron.demo.db.repository
import com.github.dannecron.demo.db.entity.order.OrderProduct
import org.springframework.data.repository.CrudRepository
import org.springframework.stereotype.Repository
import java.util.UUID
@Repository
interface OrderProductRepository: CrudRepository<OrderProduct, UUID> {
fun findByOrderId(orderId: Long): List<OrderProduct>
}

View File

@@ -0,0 +1,10 @@
package com.github.dannecron.demo.db.repository
import com.github.dannecron.demo.db.entity.order.Order
import org.springframework.data.repository.CrudRepository
import org.springframework.stereotype.Repository
@Repository
interface OrderRepository: CrudRepository<Order, Long> {
fun findByCustomerId(customerId: Long): List<Order>
}

View File

@@ -0,0 +1,17 @@
package com.github.dannecron.demo.db.repository
import com.github.dannecron.demo.db.entity.Product
import org.springframework.data.jdbc.repository.query.Query
import org.springframework.data.repository.CrudRepository
import org.springframework.data.repository.PagingAndSortingRepository
import org.springframework.stereotype.Repository
import java.time.OffsetDateTime
import java.util.UUID
@Repository
interface ProductRepository: CrudRepository<Product, Long>, PagingAndSortingRepository<Product, Long> {
fun findByGuid(guid: UUID): Product?
@Query(value = "UPDATE Product SET deleted_at = :deletedAt WHERE guid = :guid RETURNING *")
fun softDelete(guid: UUID, deletedAt: OffsetDateTime): Product?
}

View File

@@ -0,0 +1,19 @@
package com.github.dannecron.demo.db.serialialization
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import java.time.OffsetDateTime
import java.time.format.DateTimeFormatter
object OffsetDateTimeSerialization: KSerializer<OffsetDateTime> {
override val descriptor = PrimitiveSerialDescriptor("Time", PrimitiveKind.STRING)
override fun deserialize(decoder: Decoder): OffsetDateTime = OffsetDateTime.parse(decoder.decodeString())
override fun serialize(encoder: Encoder, value: OffsetDateTime) {
encoder.encodeString(value.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME))
}
}

View File

@@ -0,0 +1,18 @@
package com.github.dannecron.demo.db.serialialization
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import java.util.UUID
object UuidSerialization: KSerializer<UUID> {
override val descriptor = PrimitiveSerialDescriptor("UUID", PrimitiveKind.STRING)
override fun deserialize(decoder: Decoder): UUID = UUID.fromString(decoder.decodeString())
override fun serialize(encoder: Encoder, value: UUID) {
encoder.encodeString(value.toString())
}
}

View File

@@ -0,0 +1,14 @@
package com.github.dannecron.demo.db
import org.springframework.boot.test.autoconfigure.data.jdbc.DataJdbcTest
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories
import org.springframework.test.context.ActiveProfiles
import org.testcontainers.junit.jupiter.Testcontainers
@ActiveProfiles("db")
@DataJdbcTest
@Testcontainers(disabledWithoutDocker = false)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@EnableJdbcRepositories
class BaseDbTest

View File

@@ -0,0 +1,49 @@
package com.github.dannecron.demo.db.repository
import com.github.dannecron.demo.db.BaseDbTest
import com.github.dannecron.demo.db.entity.City
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.context.jdbc.Sql
import java.time.OffsetDateTime
import java.util.UUID
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNull
@ContextConfiguration(classes = [CityRepository::class])
class CityRepositoryTest : BaseDbTest() {
@Autowired
private lateinit var cityRepository: CityRepository
private val cityGuid = UUID.fromString("21a1a3a8-621a-40f7-b64f-7e118aa241b9")
private val city = City(
id = 1000,
guid = cityGuid,
name = "Tokyo",
createdAt = OffsetDateTime.parse("2025-01-01T12:10:05+00:00"),
updatedAt = null,
deletedAt = null,
)
@Test
@Sql(scripts = ["/sql/insert_city.sql"])
fun findByGuid() {
val result = cityRepository.findByGuid(cityGuid)
assertEquals(city, result)
val emptyResult = cityRepository.findByGuid(UUID.randomUUID())
assertNull(emptyResult)
}
@Test
@Sql(scripts = ["/sql/insert_city.sql"])
fun softDelete() {
val deletedAt = OffsetDateTime.parse("2025-01-02T12:10:05+00:00")
val expectedCity = city.copy(deletedAt = deletedAt)
val result = cityRepository.softDelete(cityGuid, deletedAt)
assertEquals(expectedCity, result)
}
}

View File

@@ -0,0 +1,39 @@
package com.github.dannecron.demo.db.repository
import com.github.dannecron.demo.db.BaseDbTest
import com.github.dannecron.demo.db.entity.Customer
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.context.jdbc.Sql
import java.time.OffsetDateTime
import java.util.UUID
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNull
@ContextConfiguration(classes = [CustomerRepository::class])
class CustomerRepositoryTest : BaseDbTest() {
@Autowired
private lateinit var customerRepository: CustomerRepository
private val customerGuid = UUID.fromString("823c50de-4c81-49bd-a69a-2d52be42b728")
private val customer = Customer(
id = 1000,
guid = customerGuid,
name = "Customer",
cityId = 1000,
createdAt = OffsetDateTime.parse("2025-01-01T12:10:05+00:00"),
updatedAt = null,
)
@Test
@Sql(scripts = ["/sql/insert_city.sql", "/sql/insert_customer.sql"])
fun findByGuid() {
val result = customerRepository.findByGuid(customerGuid)
assertEquals(customer, result)
val emptyResult = customerRepository.findByGuid(UUID.randomUUID())
assertNull(emptyResult)
}
}

View File

@@ -0,0 +1,43 @@
package com.github.dannecron.demo.db.repository
import com.github.dannecron.demo.db.BaseDbTest
import com.github.dannecron.demo.db.entity.order.OrderProduct
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.context.jdbc.Sql
import java.time.OffsetDateTime
import java.util.UUID
import kotlin.test.Test
import kotlin.test.assertEquals
@ContextConfiguration(classes = [OrderProductRepository::class])
class OrderProductRepositoryTest : BaseDbTest() {
@Autowired
private lateinit var orderProductRepository: OrderProductRepository
private val orderId = 1000L
private val orderProduct = OrderProduct(
guid = UUID.fromString("930f54e2-c60d-448e-83b1-0d259ff2c2d3"),
orderId = orderId,
productId = 1000,
createdAt = OffsetDateTime.parse("2025-01-01T12:10:05+00:00"),
updatedAt = null,
)
@Test
@Sql(
scripts = [
"/sql/insert_city.sql",
"/sql/insert_customer.sql",
"/sql/insert_order.sql",
"/sql/insert_product.sql",
"/sql/insert_order_product.sql",
]
)
fun findByOrderId() {
val result = orderProductRepository.findByOrderId(orderId)
assertEquals(1, result.size)
assertEquals(orderProduct, result[0])
}
}

View File

@@ -0,0 +1,43 @@
package com.github.dannecron.demo.db.repository
import com.github.dannecron.demo.db.BaseDbTest
import com.github.dannecron.demo.db.entity.order.Order
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.context.jdbc.Sql
import java.time.OffsetDateTime
import java.util.UUID
import kotlin.test.Test
import kotlin.test.assertEquals
@ContextConfiguration(classes = [OrderRepository::class])
class OrderRepositoryTest : BaseDbTest() {
@Autowired
private lateinit var orderRepository: OrderRepository
private val orderGuid = UUID.fromString("2c960a08-7187-4e91-9ef3-275c91b1342c")
private val customerId = 1000L
private val order = Order(
id = 1000,
guid = orderGuid,
customerId = customerId,
deliveredAt = null,
createdAt = OffsetDateTime.parse("2025-01-01T12:10:05+00:00"),
updatedAt = null,
)
@Test
@Sql(
scripts = [
"/sql/insert_city.sql",
"/sql/insert_customer.sql",
"/sql/insert_order.sql",
]
)
fun findByGuid() {
val result = orderRepository.findByCustomerId(customerId)
assertEquals(1, result.size)
assertEquals(order, result[0])
}
}

View File

@@ -0,0 +1,41 @@
package com.github.dannecron.demo.db.repository
import com.github.dannecron.demo.db.BaseDbTest
import com.github.dannecron.demo.db.entity.Product
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.context.jdbc.Sql
import java.time.OffsetDateTime
import java.util.UUID
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNull
@ContextConfiguration(classes = [ProductRepository::class])
class ProductRepositoryTest : BaseDbTest() {
@Autowired
private lateinit var productRepository: ProductRepository
private val productGuid = UUID.fromString("1fb5c7e4-8ce2-43b8-8ca7-1089b04959b9")
private val product = Product(
id = 1000,
guid = productGuid,
name = "product",
description = "description",
price = 10000,
createdAt = OffsetDateTime.parse("2025-01-01T12:10:05+00:00"),
updatedAt = null,
deletedAt = null,
)
@Test
@Sql(scripts = ["/sql/insert_product.sql"])
fun findByGuid() {
val result = productRepository.findByGuid(productGuid)
assertEquals(product, result)
val emptyResult = productRepository.findByGuid(UUID.randomUUID())
assertNull(emptyResult)
}
}

View File

@@ -0,0 +1,10 @@
---
spring:
datasource:
url: jdbc:tc:postgresql:14-alpine:///test
driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver
hikari:
maximum-pool-size: 2
flyway:
enabled: true
locations: classpath:migration/structure, classpath:migration/data

View File

@@ -0,0 +1,3 @@
insert into "city" (id, guid, name, created_at) values
(1000, '21a1a3a8-621a-40f7-b64f-7e118aa241b9', 'Tokyo', '2025-01-01 12:10:05 +00:00')
;

View File

@@ -0,0 +1,3 @@
insert into "customer" (id, guid, name, city_id, created_at) values
(1000, '823c50de-4c81-49bd-a69a-2d52be42b728', 'Customer', 1000, '2025-01-01 12:10:05 +00:00')
;

View File

@@ -0,0 +1,3 @@
insert into "order" (id, guid, customer_id, created_at) values
(1000, '2c960a08-7187-4e91-9ef3-275c91b1342c', 1000, '2025-01-01 12:10:05 +00:00')
;

View File

@@ -0,0 +1,3 @@
insert into "order_product" (guid, order_id, product_id, created_at) values
('930f54e2-c60d-448e-83b1-0d259ff2c2d3', 1000, 1000, '2025-01-01 12:10:05 +00:00')
;

View File

@@ -0,0 +1,3 @@
insert into "product" (id, guid, name, description, price, created_at) values
(1000, '1fb5c7e4-8ce2-43b8-8ca7-1089b04959b9', 'product', 'description', 10000, '2025-01-01 12:10:05 +00:00')
;

View File

@@ -42,9 +42,10 @@ testcontainers-postgresql = { module = "org.testcontainers:postgresql", version.
tracing = ["micrometer-bridge-otel", "otel-exporter"]
[plugins]
kotlin-kover = { id = "org.jetbrains.kotlinx.kover", version = "0.8.3" }
kotlin-jpa = { id = "org.jetbrains.kotlin.plugin.jpa", version.ref = "kotlin" }
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
kotlin-jpa = { id = "org.jetbrains.kotlin.plugin.jpa", version.ref = "kotlin" }
kotlin-spring = { id = "org.jetbrains.kotlin.plugin.spring", version.ref = "kotlin" }
spring-boot = { id = "org.springframework.boot", version.ref = "spring-boot" }
spring-dependencyManagement = { id = "io.spring.dependency-management", version = "1.1.6"}

View File

@@ -1 +1,2 @@
rootProject.name = "demo"
include("db")