postgres jdbc 插入自定义类型数组

postgres jdbc insert array of custom type

我想用 jdbc.

将自定义类型的数组插入 postgres

我的 sql 架构:

CREATE TYPE element_pk_t AS (
    workspace_id   BIGINT,
    element_id     BIGINT,
    history_id     BIGINT
);

我的javaclass:

public class ElementPK {
    public Long workspaceId;

    public Long elementId;

    public Long historyId;
}

我应该如何在 javajdbc 中执行此操作?

我找到了关于自定义类型的教程 https://docs.oracle.com/javase/tutorial/jdbc/basics/sqlcustommapping.html,但自定义类型的数组对我来说仍然不清楚。

一种简单的方法是使用纯字符串样式 SQL 语句,但我仍然更喜欢将 PreparedStatementsetObjectsetArray

一起使用

如果我理解正确,那么,根据 Java 代码,您需要生成查询,例如,如下所示:

INSERT INTO parent_table(elements) 
VALUES (
ARRAY[
     row(1, 2, 3)::element_pk, 
     row(4, 5, 6)::element_pk, 
     row(7, 8, 9)::element_pk
]);

假设您 table 如下所示:

CREATE TABLE parent_table(
    id SERIAL PRIMARY KEY,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    elements element_pk[]
)

以及您描述的类型。如果我是你,我不会通过数组来实现它。我会改用 JSONB - 这样你就不会失去使用索引的能力。当然,还有java.sql.Array,你仍然可以通过以下方式进行:

Array array = connection.createArrayOf("public.element_pk", new ElementPK[]{
                new ElementPK(1, 2, 3),
                new ElementPK(9, 4, 6)
        });

然后将数组设置为 PgPreparedStatement,但问题是在内部 PgPreparedStatement 会将您的元素括在大括号内,这没问题,但每个元素都将由其 toString 方法调用结果表示。我的意思是,假设您的 ElementPK toString 看起来像这样:

    @Override
    public String toString() {
        return "This is how it is implemented, really?";
    }

然后你会得到 SQL 比如:

INSERT INTO parent_table (elements) VALUES ('{"This is how it is implemented, really?","This is how it is implemented, really?"}')

同样,也许 可以采用它,但从我的角度来看 - 至少在 toString 方法中包含你的逻辑并不是那么好,是吗? 腾出时间做以下事情:

CREATE TABLE via_jsonb(
    elements JSONB
);

然后简单地:

INSERT INTO via_jsonb VALUES(
'{
    "workspace_id" : 1,
    "element_id" : 2,
    "history_id" : 3
 }'
);

在 Java 代码中,我会简单地从您的对象创建 json 并将其设置为字符串。真的,开箱即用的 JSONB 上有 a lot of functions and cool features

希望对您有所帮助,祝您有愉快的一天!)

跟进@misha2045 回答的最后一部分。

如果您出于某种原因仍然拒绝使用 JSONB,则需要在 toString 方法的末尾和开头添加括号。

@Override
public String toString() {
    return "("+this.field1+ ", " + this.field2+")";
}

然后在prepared statement中设置数组

ps.setArray(1, con.createArrayOf("yourType", yourClassArray));