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;
}
我应该如何在 java
和 jdbc
中执行此操作?
我找到了关于自定义类型的教程 https://docs.oracle.com/javase/tutorial/jdbc/basics/sqlcustommapping.html,但自定义类型的数组对我来说仍然不清楚。
一种简单的方法是使用纯字符串样式 SQL 语句,但我仍然更喜欢将 PreparedStatement
与 setObject
或 setArray
一起使用
如果我理解正确,那么,根据 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));
我想用 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;
}
我应该如何在 java
和 jdbc
中执行此操作?
我找到了关于自定义类型的教程 https://docs.oracle.com/javase/tutorial/jdbc/basics/sqlcustommapping.html,但自定义类型的数组对我来说仍然不清楚。
一种简单的方法是使用纯字符串样式 SQL 语句,但我仍然更喜欢将 PreparedStatement
与 setObject
或 setArray
如果我理解正确,那么,根据 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));