Текущи версии на jOOQ
jOOQ има естествена поддръжка за JSON
и JSONB
типове данни, така че не е нужно да правите нищо конкретно.
Исторически отговор
От jOOQ 3.5 можете да регистрирате свои собствени персонализирани обвързвания с тип данни към генератора на код, както е документирано тук:
http://www.jooq.org/doc/latest/manual/code-generation/custom-data-type-bindings
За разлика от Converter
, a Binding
диктува как вашият тип данни се обработва на ниво JDBC в рамките на jOOQ, без jOOQ да знае за вашата реализация. Тоест, не само ще дефинирате как да конвертирате между <T>
и <U>
типове (T
=тип база данни, U
=тип потребител), но също така ще можете да дефинирате как са тези типове:
- Предадено като SQL
- Обвързан с PreparedStatements
- Обвързан към SQLOutput
- Регистриран в CallableStatements като OUT параметри
- Извлечено от ResultSets
- Извлечено от SQLInput
- Извлечено от CallableStatements като OUT параметри
Пример за Binding
за използване с Jackson за създаване на JsonNode
типове е даден тук:
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();
}
}
И Converter
който се използва по-горе може да се види тук:
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;
}
}
Вече можете да регистрирате горното обвързване чрез конфигурацията на генератора на код:
<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>