Open
Description
package com.example.demo
import kotlinx.coroutines.flow.toList
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.core.convert.converter.Converter
import org.springframework.data.annotation.Id
import org.springframework.data.convert.ReadingConverter
import org.springframework.data.r2dbc.convert.R2dbcCustomConversions
import org.springframework.data.r2dbc.core.*
import org.springframework.data.r2dbc.dialect.MySqlDialect
import org.springframework.data.relational.core.mapping.Column
import org.springframework.data.relational.core.mapping.Table
import org.springframework.stereotype.Component
import org.springframework.web.reactive.function.server.ServerResponse
import org.springframework.web.reactive.function.server.bodyValueAndAwait
import org.springframework.web.reactive.function.server.coRouter
import org.springframework.web.reactive.function.server.json
@SpringBootApplication
class Demo1Application
fun main(args: Array<String>) {
runApplication<Demo1Application>(*args)
}
@Component
class TestController {
@Bean
fun testRouter(
r2dbcEntityTemplate: R2dbcEntityTemplate
) = coRouter {
GET("read") {
val result = r2dbcEntityTemplate.select<Simple>().flow().toList()
ServerResponse.ok().json().bodyValueAndAwait(result)
}
}
}
@Table(name = "customer")
data class Simple(
@Id
@Column("id")
val id: UInt,
@Column("name")
val name: String,
@Column("age")
val age: UInt,
)
@Table(name = "customer")
data class PrivateConstructor private constructor(
@Id
@Column("id")
val id: UInt,
@Column("name")
val name: String,
@Column("age")
val age: UInt,
)
@Table(name = "customer")
data class DefaultId private constructor(
@Id
@Column("id")
val id: UInt=0u,
@Column("name")
val name: String,
@Column("age")
val age: UInt,
)
@ReadingConverter
object LongToUInt : Converter<Long, UInt> {
override fun convert(source: Long): UInt {
println("LongToUInt $source")
return source.toUInt()
}
}
@ReadingConverter
object LongToInt : Converter<Long, Int> {
override fun convert(source: Long): Int {
println("LongToInt $source")
return source.toInt()
}
}
@Configuration
class Config{
@Bean
fun customConversions(): R2dbcCustomConversions =
R2dbcCustomConversions.of(MySqlDialect.INSTANCE, listOf(LongToUInt,LongToInt))
}
CREATE TABLE `customer` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8mb4_general_ci NOT NULL,
`age` int unsigned DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=55 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
mysql 8.0.24
kotlin 2.0.20
spring-boot 3.3.3
1.When using r2dbcEntityTemplate to query the database, if the Entity constructor is public, everything runs normally regardless of whether the attribute corresponding to the primary Key has a default value. But when the Entity of the constructor is private, if primary key corresponding attributes don't declare a default value, will lead to MappingInstantiationException.
2.Hope ReadingConverter, WriteConverter can support kotlin unsigned type, code only LongToInt will work, but LongToUInt will not.