【问题标题】:It is possible to use JSON or JSONB postgresql datatypes with spring r2dbc manually?可以手动将 JSON 或 JSONB postgresql 数据类型与 spring r2dbc 一起使用吗?
【发布时间】:2019-12-05 03:08:50
【问题描述】:

我正在使用 spring boot、webflux 和 r2dbc (postgresql) 构建一个新的 api。我的一张表将有一个 json 或 jsonb 字段,用于存储动态 json 文档。

目前,r2dbc 不支持 postgresql 数据库的 json 数据类型。我想知道是否可以使用它,为存储库编写一些代码。

我创建了一个简单的测试项目来尝试一下,但还没有运气。我能够通过使用org.springframework.data.r2dbc.core.DatabaseClient.execute() 并在查询中用to_json() 包装json 字段来保存JSON 字段,但我以后无法读取它。

测试实体:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Table("Test")
public class Test {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", columnDefinition = "serial")
    private Long id;
    @Column(name = "data", columnDefinition = "json")
    private String data;

}

保存方法工作:

public Mono<Integer> save(Test test) {
        return databaseClient.execute("INSERT INTO test (data) VALUES(to_json($1))")
                .bind("$1", test.getData())
                .fetch()
                .rowsUpdated();
    }

回读时出现异常:

java.lang.IllegalArgumentException: Cannot decode value of type java.lang.Object
    at io.r2dbc.postgresql.codec.DefaultCodecs.decode(DefaultCodecs.java:97)
    at io.r2dbc.postgresql.PostgresqlRow.get(PostgresqlRow.java:88)
    at io.r2dbc.spi.Row.get(Row.java:63)
    at org.springframework.data.r2dbc.convert.ColumnMapRowMapper.getColumnValue(ColumnMapRowMapper.java:100)
    at org.springframework.data.r2dbc.convert.ColumnMapRowMapper.apply(ColumnMapRowMapper.java:59)
    at org.springframework.data.r2dbc.convert.ColumnMapRowMapper.apply(ColumnMapRowMapper.java:44)
    at io.r2dbc.postgresql.PostgresqlResult.lambda$map$0(PostgresqlResult.java:71)

【问题讨论】:

  • 根据this 博客,新的候选版本支持它。
  • 以上链接已失效...
  • 抱歉,我认为他们删除了发行说明。但现在在README 上,它说它支持JSONJSONB。添加了新的编解码器 - io.r2dbc.postgresql.codec.Json。新link
  • 我刚试过这个,但我还不能在 spring-data-r2dbc 中使用这种方法。 r2dbc 支持已经存在,但还没有在 spring-data-r2dbc 抽象中。

标签: java postgresql java-11 r2dbc spring-data-r2dbc


【解决方案1】:

使用io.r2dbc.postgresql.codec.Json 作为您的实体属性类型,请检查my post 关于这一点。

【讨论】:

    【解决方案2】:

    我可以通过查询将 json/jsonb 转换为 TEXT 来做到这一点。我不确定这是否是正确的选择,但它确实有效。

    public Mono<Test> findById(Long id) {
        return databaseClient.execute("SELECT id, data::TEXT FROM test WHERE id = $1")
                .bind("$1", id)
                .map(row -> new Test(
                              row.get("id", Long.class),
                              row.get("data", String.class)
                            )
                )
                .one();
    }
    

    【讨论】:

      猜你喜欢
      • 2018-08-25
      • 2021-07-27
      • 2021-11-23
      • 2020-04-11
      • 2021-07-22
      • 1970-01-01
      • 2020-01-16
      • 2020-03-09
      相关资源
      最近更新 更多