JOOQ json绑定问题

时间:2019-04-09 15:06:06

标签: java postgresql jooq

我在转换postgresql jsonb时遇到问题 我按照教程中的说明创建了绑定:jooq tutorial 另外请注意,我没有使用Codegen 在我的仓库中,我有以下代码

Binding binding = new PostgresJSONGsonBinding();
Field<JsonElement> gsonObj = 
       DSL.field("gsonObj",SQLDataType.OTHER.asConvertedDataType(binding));

在方法中出现错误

com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Unterminated array at line 1 column 42 path $.factories[1]

有人可以帮忙了解我在做什么错

是的,我看到了其他问题:issue with jooq

1 个答案:

答案 0 :(得分:1)

工作代码

public class PostgresJSONGsonBinding implements Binding<Object, JsonElement> {
    // Binding <T> = Object (unknown JDBC type), and <U> = JsonElement (user type)

    private static final Logger LOGGER = LoggerFactory.getLogger(PostgresJSONGsonBinding.class);

    // The converter does all the work
    @Override
    public Converter<Object, JsonElement> converter() {
        return new Converter<Object, JsonElement>() {

            //Convert a database object to a user object
            @Override
            public JsonElement from(Object t) {
                return t == null ? JsonNull.INSTANCE : new Gson().fromJson(t.toString(), JsonElement.class);
            }

            // Convert a user object to a database object
            @Override
            public Object to(JsonElement u) {
                return u == null || u == JsonNull.INSTANCE ? null : new Gson().toJson(u);
            }

            @Override
            public Class<Object> fromType() {
                return Object.class;
            }

            @Override
            public Class<JsonElement> toType() {
                return JsonElement.class;
            }
        };
    }

    // Rending a bind variable for the binding context's value and casting it to the json type
    @Override
    public void sql(BindingSQLContext<JsonElement> ctx) throws SQLException {
        // Depending on how you generate your SQL, you may need to explicitly distinguish
        // between jOOQ generating bind variables or inlined literals.
        if (ctx.render().paramType() == ParamType.INLINED){
            ctx.render().visit(DSL.inline(ctx.convert(converter()).value())).sql("::json");
        }
        else{
            ctx.render().sql("?::json");
        }
    }

    // Registering VARCHAR types for JDBC CallableStatement OUT parameters
    @Override
    public void register(BindingRegisterContext<JsonElement> ctx) throws SQLException {
        ctx.statement().registerOutParameter(ctx.index(), Types.VARCHAR);
    }

    // Converting the JsonElement to a String value and setting that on a JDBC PreparedStatement
    @Override
    public void set(BindingSetStatementContext<JsonElement> ctx) throws SQLException {
        ctx.statement().setString(ctx.index(), Objects.toString(ctx.convert(converter()).value(), null));
    }

    // Getting a String value from a JDBC ResultSet and converting that to a JsonElement
    @Override
    public void get(BindingGetResultSetContext<JsonElement> ctx) throws SQLException {
        ctx.convert(converter()).value(ctx.resultSet().getString(ctx.index()));
    }

    // Getting a String value from a JDBC CallableStatement and converting that to a JsonElement
    @Override
    public void get(BindingGetStatementContext<JsonElement> ctx) throws SQLException {
        ctx.convert(converter()).value(ctx.statement().getString(ctx.index()));
    }

    // Setting a value on a JDBC SQLOutput (useful for Oracle OBJECT types)
    @Override
    public void set(BindingSetSQLOutputContext<JsonElement> ctx) throws SQLException {
        throw new SQLFeatureNotSupportedException();
    }

    // Getting a value from a JDBC SQLInput (useful for Oracle OBJECT types)
    @Override
    public void get(BindingGetSQLInputContext<JsonElement> ctx) throws SQLException {
        throw new SQLFeatureNotSupportedException();
    }
}