sql >> Database >  >> RDS >> PostgreSQL

Hoe een bij te werken record met JSON-kolom in PostgreSQL in te voegen met JOOQ?

Huidige jOOQ-versies

jOOQ heeft native ondersteuning voor JSON en JSONB gegevenstypen, dus u hoeft niets specifieks te doen.

Historisch antwoord

Sinds jOOQ 3.5 kunt u uw eigen aangepaste gegevenstypebindingen registreren bij de codegenerator, zoals hier wordt beschreven:

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

In tegenstelling tot een Converter , een Binding dicteert hoe uw gegevenstype wordt afgehandeld op JDBC-niveau binnen jOOQ, zonder dat jOOQ iets weet van uw implementatie. Dat wil zeggen, u bepaalt niet alleen hoe u moet converteren tussen <T> en <U> typen (T =databasetype, U =gebruikerstype), maar u kunt ook definiëren hoe dergelijke typen zijn:

  • Weergegeven als SQL
  • Gebonden aan PreparedStatements
  • Gebonden aan SQLOutput
  • Geregistreerd in CallableStatements als OUT-parameters
  • Opgehaald uit ResultSets
  • Opgehaald uit SQLInput
  • Opgehaald uit CallableStatements als OUT-parameters

Een voorbeeld Binding voor gebruik met Jackson om JsonNode te produceren typen wordt hier gegeven:

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

En de Converter die hierboven wordt gebruikt, is hier te zien:

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

U kunt de bovenstaande binding nu registreren via de configuratie van de codegenerator:

<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. NOT NULL beperking over een set kolommen

  2. Hoe de serverstatus in MySQL Workbench te controleren met behulp van de GUI

  3. MyBatis RowBounds beperkt de resultaten van zoekopdrachten niet

  4. SQLite waar