postgresql - R2DBC 和枚举 (PostgreSQL)
问题描述
2020 年 8 月 15 日更新:看起来Enum
支持是在 6 月 16 日添加的。R2DBC 提交。
H2DBC 是否支持 PostgreSQL 枚举?我检查了他们的git 页面,但没有提及任何内容。如果是这样,如何使用枚举(INSERT,SELECT)?
让我们说 PostgreSQL 枚举
CREATE TYPE mood AS ENUM ('UNKNOWN', 'HAPPY', 'SAD', ...);
Java 类
@Data
public class Person {
private String name;
private Mood mood;
// ...
enum Mood{ UNKNOWN, HAPPY, SAD, ...}
}
我试过了:
// insert
var person = ...;
client.insert()
.table("people")
.using(person)
.then()
.subscribe(System.out::println);
// select
var query = "SELECT * FROM people";
client.execute(query)
.as(Person.class)
.fetch().all()
.subscribe(System.out::println);
但我收到错误消息:
# on insert
WARN [reactor-tcp-epoll-1] (Loggers.java:294) - Error: SEVERITY_LOCALIZED=ERROR, SEVERITY_NON_LOCALIZED=ERROR, CODE=42804, MESSAGE=column "mood" is of type mood but expression is of type character varying, HINT=You will need to rewrite or cast the expression., POSITION=61, FILE=parse_target.c, LINE=591, ROUTINE=transformAssignedExpr
# on select
ERROR [reactor-tcp-epoll-1] (Loggers.java:319) - [id: 0x8581acdb, L:/127.0.0.1:39726 ! R:127.0.0.1/127.0.0.1:5432] Error was received while reading the incoming data. The connection will be closed.
reactor.core.Exceptions$ErrorCallbackNotImplemented: org.springframework.data.mapping.MappingException: Could not read property private ...
我发现了类似的帖子,但没有运气解决我的问题..也许我应用错了..
欢迎任何帮助或提示。
解决方案
用org.springframework.data:spring-data-r2dbc:1.0.0.RELEASE
和测试io.r2dbc:r2dbc-postgresql:0.8.1.RELEASE
。
科特林版本。
定义一个枚举类
enum class Mood { UNKNOWN, HAPPY, SAD }
创建自定义编解码器
class MoodCodec(private val allocator: ByteBufAllocator) : Codec<Mood> { override fun canEncodeNull(type: Class<*>): Boolean = false override fun canEncode(value: Any): Boolean = value is Mood override fun encode(value: Any): Parameter { return Parameter(Format.FORMAT_TEXT, oid) { ByteBufUtils.encode(allocator, (value as Mood).name) } } override fun canDecode(dataType: Int, format: Format, type: Class<*>): Boolean = dataType == oid override fun decode(buffer: ByteBuf?, dataType: Int, format: Format, type: Class<out Mood>): Mood? { buffer ?: return null return Mood.valueOf(ByteBufUtils.decode(buffer)) } override fun type(): Class<*> = Mood::class.java override fun encodeNull(): Parameter = Parameter(Format.FORMAT_TEXT, oid, Parameter.NULL_VALUE) companion object { // Get form `select oid from pg_type where typname = 'mood'` private const val oid = YOUR_ENUM_OID } }
注册编解码器
您可能需要更改
runtimeOnly("io.r2dbc:r2dbc-postgresql")
为implementation("io.r2dbc:r2dbc-postgresql")
@Configuration @EnableR2dbcRepositories class AppConfig : AbstractR2dbcConfiguration() { override fun connectionFactory(): ConnectionFactory = PostgresqlConnectionConfiguration.builder() .port(5432) // Add your config here. .codecRegistrar { _, allocator, registry -> registry.addFirst(MoodCodec(allocator)) Mono.empty() }.build() .let { PostgresqlConnectionFactory(it) } }
推荐阅读
- mongodb - MongoDB查找正则表达式匹配的关键字
- android - ListPreference:将字符串数组中的项目引用为 defaultValue
- java - 如何在弹性搜索中为多个布尔查询生成查询
- python - 尝试使用 python3 从 api 调用将数据输入数据库时的响应 [400]
- python - .loc 按日期过滤数据库
- c - 我正在制作代码树,数据结构。但是在打印过程中出现了错误
- node.js - 如何在 TypeScript 中扩展非导出类?
- angular - 如何引用 Leaflet.draw 中已删除的图层?
- javascript - 输入明文时出现错误“文本字符串必须在文本中呈现...”
- r - 如何在r中选择并重复数据框中的多行