sql >> Databáze >  >> RDS >> PostgreSQL

Jak vložit aktualizovatelný záznam se sloupcem JSON v PostgreSQL pomocí JOOQ?

Aktuální verze jOOQ

jOOQ má nativní podporu pro JSON a JSONB datové typy, takže nemusíte dělat nic konkrétního.

Historická odpověď

Od jOOQ 3.5 můžete do generátoru kódu zaregistrovat své vlastní vazby typu dat, jak je zdokumentováno zde:

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

Na rozdíl od Converter , Binding určuje, jak je s vaším datovým typem nakládáno na úrovni JDBC v rámci jOOQ, aniž by jOOQ věděl o vaší implementaci. To znamená, že nejen definujete, jak převádět mezi <T> a <U> typy (T =typ databáze, U =typ uživatele), ale budete také moci definovat, jak takové typy jsou:

  • Vykresleno jako SQL
  • Vázané na PreparedStatements
  • Vázaný na SQLOutput
  • Registrováno v CallableStatements jako parametry OUT
  • Načteno ze sad výsledků
  • Načteno z SQLInput
  • Načteno z CallableStatements jako parametry OUT

Příklad Binding pro použití s ​​Jacksonem k vytvoření JsonNode typy jsou uvedeny zde:

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();
    }
}

A Converter který je použit výše, můžete vidět zde:

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

Nyní můžete výše uvedenou vazbu zaregistrovat prostřednictvím konfigurace generátoru kódu:

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



  1. Postgresql Aktuální časové razítko při aktualizaci

  2. SQL dotaz na odstranění databáze v MySQL

  3. Jak make_date() funguje v PostgreSQL

  4. Jak změnit sloupec PG na hodnotu NULLABLE TRUE?