当前 jOOQ 版本
jOOQ 对 JSON
和 JSONB
数据类型有原生支持,因此您不需要进行任何特定的操作。
历史回答
自 jOOQ 3.5 版本以来,您可以按照此处所述注册自己的自定义数据类型绑定到代码生成器中:
http://www.jooq.org/doc/latest/manual/code-generation/custom-data-type-bindings
与 Converter
不同,Binding
决定了在 jOOQ 的 JDBC 层面上如何处理您的数据类型,而 jOOQ 不知道您的实现方式。也就是说,您不仅将定义如何在 <T>
和 <U>
类型之间进行转换(T
= 数据库类型,U
= 用户类型),还将能够定义此类类型的:
- 作为 SQL 渲染
- 绑定到 PreparedStatements 上
- 绑定到 SQLOutput 上
- 作为 OUT 参数在 CallableStatements 中注册
- 从 ResultSets 中提取
- 从 SQLInput 中提取
- 作为 OUT 参数从 CallableStatements 中提取
下面是一个使用 Jackson 生成 JsonNode
类型的示例 Binding
:
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 {
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()));
}
@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>