R2DBC和枚举(PostgreSQL) [英] R2DBC and enum (PostgreSQL)

查看:524
本文介绍了R2DBC和枚举(PostgreSQL)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

H2DBC是否支持PostgreSQL枚举?我检查了他们 git页面,但它没有提及任何内容。如果是这样,那么如何使用枚举(INSERT,SELECT)?

可以说PostgreSQL枚举

 创建类型的情绪作为枚举(未知,快乐,悲伤,...); 

Java类

  @Data 
公共类Person {
private字符串名称;
私人心情;
// ...

枚举Mood {未知,快乐,SAD,...}
}

我尝试过:

  //插入
var person = ...;
client.insert()
.table( people)
.using(person)
.then()
.subscribe(System.out :: println );

//选择
var query = SELECT * FROM people;
client.execute(query)
.as(Person.class)
.fetch()。all()
.subscribe(System.out :: println);

但是我收到错误消息:



< pre class = lang-sh prettyprint-override> #插入
警告[reactor-tcp-epoll-1](Loggers.java:294)-错误:SEVERITY_LOCALIZED =错误,SEVERITY_NON_LOCALIZED =错误,CODE = 42804,MESSAGE =列 mood的类型为心情,但表达式的类型为字符变化,HINT =您将需要重写或强制转换该表达式。,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]读取传入数据时收到错误。连接将关闭。
Reactor.core.Exceptions $ ErrorCallbackNotImplemented:org.springframework.data.mapping.MappingException:无法读取私有属性...

我发现相似的帖子,但没有运气解决我的问题..也许我是错误地应用了它。.

任何帮助或提示都欢迎。

解决方案

使用 org.springframework.data:spring-data-r2dbc:1.0.0.RELEASE io.r2dbc:r2dbc-postgresql:0.8进行测试。 1.发布



科特林版本。


  1. 定义枚举类

     枚举类Mood { 
    未知,
    快乐,
    SAD
    }


  2. 创建自定义编解码器

      class MoodCodec(私有val分配器:ByteBufAll ocator):编解码器< Mood>。 {
    重写fun canEncodeNull(type:Class< *>):布尔值=假

    重写fun canEncode(value:任何):布尔值=心情

    重写fun encode(value:Any):参数{
    return Parameter(Format.FORMAT_TEXT,oid){
    ByteBufUtils.encode(allocator,(Mood值).name)
    }
    }

    重写fun canDecode(dataType:Int,format:Format,type:Class< *>):布尔值= dataType == oid

    重写fun解码(缓冲区:ByteBuf ?,数据类型:整数,格式:格式,类型:类< out Mood>):心情? {
    buffer?:返回null
    返回Mood.valueOf(ByteBufUtils.decode(buffer))
    }

    覆盖fun type():Class< *> = Mood :: class.java

    重写fun encodeNull():参数=
    参数(Format.FORMAT_TEXT,oid,Parameter.NULL_VALUE)

    随播对象{
    //从pg_type获取形式`select oid,其中typname ='mood'`
    private const val oid = YOUR_ENUM_OID
    }
    }


  3. 注册编解码器



    您可能需要更改 runtimeOnly( io.r2dbc:r2dbc-postgresql)实现($ io $ r $code>

      @Configuration 
    @ EnableR2dbcRepositories
    类AppConfig:AbstractR2dbcConfiguration(){
    覆盖fun connectionFactory():ConnectionFactory = PostgresqlConnectionConfiguration.builder()
    .port(5432)//在此处添加配置。
    .codecRegistrar {_,分配器,注册表->
    Registry.addFirst(MoodCodec(allocator))
    Mono.empty()
    } .build()
    .let {PostgresqlConnectionFactory(it)}
    }



Does H2DBC support PostgreSQL enums? I checked they git page but it doesn't mention anything about it. If it does, how enums could be used (INSERT, SELECT)?
Lets say PostgreSQL enum

CREATE TYPE mood AS ENUM ('UNKNOWN', 'HAPPY', 'SAD', ...);

Java class

@Data
public class Person {
    private String name;
    private Mood mood;
    // ...

    enum Mood{ UNKNOWN, HAPPY, SAD, ...}
}

I tried:

        // 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);

But I'm getting error messages:

# 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 ...

I found similar post but without luck to solve my problem.. maybe I was applying it wrong..
Any help or tips are welcome.

解决方案

Tested with org.springframework.data:spring-data-r2dbc:1.0.0.RELEASE and io.r2dbc:r2dbc-postgresql:0.8.1.RELEASE.

Kotlin version.

  1. Define a enum class

    enum class Mood {
        UNKNOWN,
        HAPPY,
        SAD
    }
    

  2. Create a custom codec

    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
        }
    }
    

  3. Registe the codec

    You may need change runtimeOnly("io.r2dbc:r2dbc-postgresql") to 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) }
    }
    

这篇关于R2DBC和枚举(PostgreSQL)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆