Type Conversion
Kuery Client uses Spring Type Conversion for values written to bind parameters and values read into mapped properties. Register Spring @WritingConverter and @ReadingConverter implementations on the client builder.
Default behavior
Without any configuration:
- Types the driver supports natively (numbers, strings, date/time types, and so on) are passed through unchanged.
- Enums are written by their name (
Enum.name) and read back by name. - Kotlin value classes are written as their underlying value and read back by boxing the column value through the constructor.
Custom converters registered via converters(...) take precedence over these defaults. For example, registering a @WritingConverter from your enum to Int overrides the write-by-name default for that enum.
Example
Define a custom type
data class StringWrapper(val value: String)Create the converters
@WritingConverter
class StringWrapperToStringConverter : Converter<StringWrapper, String> {
override fun convert(source: StringWrapper): String {
return source.value
}
}
@ReadingConverter
class StringToStringWrapperConverter : Converter<String, StringWrapper> {
override fun convert(source: String): StringWrapper {
return StringWrapper(source)
}
}Register the converters
val kueryClient = SpringR2dbcKueryClient.builder()
.connectionFactory(connectionFactory)
.converters(
listOf(
StringWrapperToStringConverter(),
StringToStringWrapperConverter(),
)
)
.build()val kueryClient = SpringJdbcKueryClient.builder()
.dataSource(dataSource)
.converters(
listOf(
StringWrapperToStringConverter(),
StringToStringWrapperConverter(),
)
)
.build()Use the type
suspend fun write(str: StringWrapper): Long = kueryClient
.sql {
+"INSERT INTO test_table (text) VALUES ($str)"
}
.rowsUpdated()
data class Record(
val text: StringWrapper,
)
suspend fun read(): List<Record> = kueryClient
.sql {
+"SELECT * FROM test_table"
}
.list()The blocking client uses the same SQL and mapping code without suspend.
Conversion is performed per bound value and per mapped column. A non-simple custom type used as the top-level return type does not automatically use its @ReadingConverter; put it in a mapped data class property instead. (Kotlin value classes are the exception: they work in both positions without converters. See Kotlin value classes in Row Mapping.)