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>