Aktuella jOOQ-versioner
jOOQ har inbyggt stöd för JSON
och JSONB
datatyper, så du behöver inte göra något specifikt.
Historiskt svar
Sedan jOOQ 3.5 kan du registrera dina egna anpassade datatypbindningar till kodgeneratorn som dokumenteras här:
http://www.jooq.org/doc/latest/manual/code-generation/custom-data-type-bindings
Till skillnad från en omvandlare
, en Bindning
dikterar hur din datatyp hanteras på JDBC-nivå inom jOOQ, utan att jOOQ känner till din implementering. Dvs du kommer inte bara att definiera hur du konverterar mellan
och typer (
T
=databastyp, U
=användartyp), men du kommer också att kunna definiera hur sådana typer är:
- Renderas som SQL
- Bunden till PreparedStatements
- Bund till SQLOutput
- Registrerad i CallableStatements som OUT-parametrar
- Hämtade från resultatuppsättningar
- Hämtad från SQLInput
- Hämtas från CallableStatements som OUT-parametrar
Ett exempel på Bindning
för användning med Jackson för att producera JsonNode
typer ges här:
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();
}
}
Och omvandlaren
som används ovan kan ses här:
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 registrera ovanstående bindning via kodgeneratorns 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>