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

我跟着答案是否有可能写一个数据类型转换器来处理postgres JSON列? 实现nodeObject转换器。

然后我尝试使用可更新的记录来插入记录,我得到了“org.jooq.exception.SQLDialectNotSupportedException:在方言POSTGRES中不支持类型类org.postgresql.util.PGobject”exception。

我怎么解决这个问题?

以下是我的代码:

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

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

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

Converter不同, Binding指示如何在jOOQ内的JDBC级别处理数据类型,而不知道您的实现。 即,您不仅将定义如何在类型之间进行转换( T =数据库类型, U =用户类型),而且还可以定义这些类型的方式:

  • 呈现为SQL
  • 绑定到PreparedStatements
  • 绑定到SQLOutput
  • 在CallableStatements中注册为OUT参数
  • 从ResultSet获取
  • 从SQLInput获取
  • 从CallableStatements获取为OUT参数

这里给出了一个与Jackson一起使用以生成JsonNode类型的示例:

 public class PostgresJSONJacksonJsonNodeBinding implements Binding { @Override public Converter converter() { return new PostgresJSONJacksonJsonNodeConverter(); } @Override public void sql(BindingSQLContext 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 ctx) throws SQLException { ctx.statement().registerOutParameter(ctx.index(), Types.VARCHAR); } @Override public void set(BindingSetStatementContext ctx) throws SQLException { ctx.statement().setString( ctx.index(), Objects.toString(ctx.convert(converter()).value())); } @Override public void get(BindingGetResultSetContext ctx) throws SQLException { ctx.convert(converter()).value(ctx.resultSet().getString(ctx.index())); } @Override public void get(BindingGetStatementContext 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 ctx) throws SQLException { throw new SQLFeatureNotSupportedException(); } @Override public void get(BindingGetSQLInputContext ctx) throws SQLException { throw new SQLFeatureNotSupportedException(); } } 

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

 public class PostgresJSONJacksonJsonNodeConverter implements Converter { @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 fromType() { return Object.class; } @Override public Class toType() { return JsonNode.class; } } 

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

  com.example.PostgresJSONJacksonJsonNodeBinding com.fasterxml.jackson.databind.JsonNode com.example.PostgresJSONJacksonJsonNodeBinding   com.example.PostgresJSONJacksonJsonNodeBinding my_schema\.table\.json_field