sql >> Database teknologi >  >> RDS >> PostgreSQL

Hvordan indsætter man en opdaterbar post med JSON-kolonne i PostgreSQL ved hjælp af JOOQ?

Nuværende jOOQ-versioner

jOOQ har indbygget understøttelse af JSON og JSONB datatyper, så du ikke behøver at gøre noget specifikt.

Historisk svar

Siden jOOQ 3.5 kan du registrere dine egne brugerdefinerede datatypebindinger til kodegeneratoren, som det er dokumenteret her:

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

I modsætning til en konverter , en Bindende dikterer, hvordan din datatype håndteres på JDBC-niveau i jOOQ, uden at jOOQ kender til din implementering. Det vil sige, at du ikke kun vil definere, hvordan du konverterer mellem og typer (T =databasetype, U =brugertype), men du vil også være i stand til at definere, hvordan sådanne typer er:

  • Gengivet som SQL
  • Bundet til Prepared Statements
  • Bundet til SQLOutput
  • Registreret i CallableStatements som OUT-parametre
  • Hentet fra resultatsæt
  • Hentet fra SQLInput
  • Hentet fra CallableStatements som OUT-parametre

Et eksempel på Binding til brug med Jackson til at producere JsonNode typer er angivet her:

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

Og konverteren som er brugt ovenfor kan ses her:

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

Du kan nu registrere ovenstående binding via kodegeneratorens konfiguration:

<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. Del 1:Billedklassificering med MariaDB Server og TensorFlow – en oversigt

  2. Hvordan kan jeg opdele en lang, enkelt SQLiteOpenHelper i flere klasser, en for hver tabel

  3. Hvad er fordelene ved et datastyringssystem?

  4. Hvad er det bedste PostgreSQL High Availability Framework? PAF vs. repmgr vs. Patroni Infographic