gpt4 book ai didi

java - 如何使用 JOOQ 在 PostgreSQL 中插入带有 JSON 列的可更新记录?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:19:39 24 4
gpt4 key购买 nike

我遵循了Is it possible to write a data type Converter to handle postgres JSON columns?中的答案 实现 nodeObject 转换器。

然后我尝试使用可更新的记录来插入记录,我得到了 “org.jooq.exception.SQLDialectNotSupportedException: Type class org.postgresql.util.PGobject is not supported in dialect POSTGRES”异常。

我该如何解决这个问题?

以下是我的代码:

TableRecord r = create.newRecord(TABLE);
ObjectNode node = JsonNodeFactory.instance.objectNode();
r.setValue(TABLE.JSON_FIELD, node, new JsonObjectConverter());
r.store();

最佳答案

当前的 jOOQ 版本

jOOQ 原生支持 JSONJSONB数据类型,因此您无需执行任何特定操作。

历史答案

从 jOOQ 3.5 开始,您可以将自己的自定义数据类型绑定(bind)注册到代码生成器,如下所述:

http://www.jooq.org/doc/latest/manual/code-generation/custom-data-type-bindings

不同于 Converter , 一个 Binding 指示如何在 jOOQ 中的 JDBC 级别处理你的数据类型,而 jOOQ 不知道你的实现。即,您不仅会定义如何在 <T> 之间进行转换和 <U>类型(T = 数据库类型,U = 用户类型),但您还可以定义此类类型:

  • 呈现为 SQL
  • 绑定(bind)到 PreparedStatements
  • 绑定(bind)到 SQLOutput
  • 在 CallableStatements 中注册为 OUT 参数
  • 从结果集中获取
  • 从 SQLInput 中获取
  • 作为 OUT 参数从 CallableStatements 获取

一个例子 Binding与 jackson 一起生产 JsonNode类型在这里给出:

public class PostgresJSONJacksonJsonNodeBinding 
implements Binding<Object, JsonNode> {

@Override
public Converter<Object, JsonNode> converter() {
return new PostgresJSONJacksonJsonNodeConverter();
}

@Override
public void sql(BindingSQLContext<JsonNode> ctx) throws SQLException {

// This ::json cast is explicitly needed by PostgreSQL:
ctx.render().visit(DSL.val(ctx.convert(converter()).value())).sql("::json");
}

@Override
public void register(BindingRegisterContext<JsonNode> ctx) throws SQLException {
ctx.statement().registerOutParameter(ctx.index(), Types.VARCHAR);
}

@Override
public void set(BindingSetStatementContext<JsonNode> ctx) throws SQLException {
ctx.statement().setString(
ctx.index(),
Objects.toString(ctx.convert(converter()).value()));
}

@Override
public void get(BindingGetResultSetContext<JsonNode> ctx) throws SQLException {
ctx.convert(converter()).value(ctx.resultSet().getString(ctx.index()));
}

@Override
public void get(BindingGetStatementContext<JsonNode> ctx) throws SQLException {
ctx.convert(converter()).value(ctx.statement().getString(ctx.index()));
}

// The below methods aren't needed in PostgreSQL:

@Override
public void set(BindingSetSQLOutputContext<JsonNode> ctx) throws SQLException {
throw new SQLFeatureNotSupportedException();
}

@Override
public void get(BindingGetSQLInputContext<JsonNode> ctx) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
}

还有 Converter上面使用的可以在这里看到:

public class PostgresJSONJacksonJsonNodeConverter 
implements Converter<Object, JsonNode> {
@Override
public JsonNode from(Object t) {
try {
return t == null
? NullNode.instance
: new ObjectMapper().readTree(t + "");
}
catch (IOException e) {
throw new RuntimeException(e);
}
}

@Override
public Object to(JsonNode u) {
try {
return u == null || u.equals(NullNode.instance)
? null
: new ObjectMapper().writeValueAsString(u);
}
catch (IOException e) {
throw new RuntimeException(e);
}
}

@Override
public Class<Object> fromType() {
return Object.class;
}

@Override
public Class<JsonNode> toType() {
return JsonNode.class;
}
}

您现在可以通过代码生成器配置注册上述绑定(bind):

<customType>
<name>com.example.PostgresJSONJacksonJsonNodeBinding</name>
<type>com.fasterxml.jackson.databind.JsonNode</type>
<binding>com.example.PostgresJSONJacksonJsonNodeBinding</binding>
</customType>

<forcedType>
<name>com.example.PostgresJSONJacksonJsonNodeBinding</name>
<expression>my_schema\.table\.json_field</expression>
</forcedType>

关于java - 如何使用 JOOQ 在 PostgreSQL 中插入带有 JSON 列的可更新记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27044702/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com