r2dbc 中 javax.persistence.AttributeConverter 的替代方法是什么

What is the alternative to javax.persistence.AttributeConverter in r2dbc

我需要在 postgres 中存储 YearMonth。根据这个 SO answer 最好的 postgres 类型是 date.

假设我们使用kotlin + spring-data-r2dbc,我们应该如何实现映射?

有了 AttributeConverter 我会这样实现它:

import java.time.LocalDate
import java.time.YearMonth
import javax.persistence.AttributeConverter

class YearMonthIntegerAttributeConverter : AttributeConverter<YearMonth?, Int?> {
  fun convertToDatabaseColumn(
    attribute: YearMonth?
  ): LocalDate? {
    return attribute?.atDay(1)
  }

  fun convertToEntityAttribute(
    date: LocalDate?
  ): YearMonth? {
    if (date == null) {
      return null
    }
    return YearMonth.of(date.year, date.month)
  }
}

但是使用 AttributeConverter 是不可能的,因为 javax.persistence 在此堆栈中不可用。

再次阅读文档 solves it

备选方案是

import org.springframework.core.convert.converter.Converter
import org.springframework.data.convert.ReadingConverter
import org.springframework.data.convert.WritingConverter

上面的例子可以这样实现:

@WritingConverter
class YearMonthToDateConverter : Converter<YearMonth, LocalDate> {
  override fun convert(source: YearMonth): LocalDate {
    return source?.atDay(1)
  }
}


@ReadingConverter
class DateToYearMonthConverter : Converter<LocalDate, YearMonth> {
  override fun convert(source: LocalDate): YearMonth {
    return YearMonth.of(source.year, source.month)
  }
}

这需要使用 r2dbc 配置注册转换器 AbstractR2dbcConfiguration

@Configuration
class R2dbcConfig(
  private val connectionFactory: ConnectionFactory,
) : AbstractR2dbcConfiguration() {
  override fun connectionFactory() = connectionFactory

  override fun getCustomConverters(): List<Any> {
    return listOf<Converter<out Any, out Any>>(
      YearMonthToDateConverter(),
      DateToYearMonthConverter()

    )
  }
}