使用PreparedStatement将一系列Java Enum持久保存到Postgres Enums数组中

时间:2010-05-26 22:25:52

标签: java postgresql jdbc

我有一个Java Enum:

public enum Equipment { Hood, Blinkers, ToungTie, CheekPieces, Visor, EyeShield, None;}

和相应的Postgres枚举:

CREATE TYPE equipment AS ENUM ('Hood', 'Blinkers', 'ToungTie', 'CheekPieces', 'Visor', 'EyeShield', 'None');

在我的数据库中,我有一个表,其中包含一个包含“设备”项目数组的列:

CREATE TABLE "Entry" (
    id bigint NOT NULL DEFAULT nextval('seq'::regclass),
    "date" character(10) NOT NULL,
    equipment equipment[]
);

最后,当我运行我的应用程序时,我有一个“设备”枚举的数组,我希望使用Prepared Statement持久保存到数据库,并且对于我的生活,我无法弄清楚如何做到这一点

StringBuffer sb =  new StringBuffer("insert into \"Entry\" ");
sb.append("( \"date\", \"equipment \" )");
sb.append(" values ( ?, ? )");
PreparedStatement ps = db.prepareStatement(sb.toString());

ps.setString("2010-10-10");
ps.set???????????

3 个答案:

答案 0 :(得分:3)

您应该阅读this

我建议你的代码看起来更像这样:

    // A column named "date" is probably illegal and not very illustrative.  "date" is a keyword for most databases.
    // Building a string that never changes again and again is a waste of CPU and heap
    private static final String INSERT_SQL =  "insert into Entry(date,equipment) values(?,?)";

    PreparedStatement ps = db.prepareStatement(INSERT_SQL);

    // Use the type system properly.  Dates should be DATE type columns in a database.  Why string?    
    ps.setDate(entryDate);

    // You shouldn't want to insert an array of values; that's not normalized.
    ps.setString(equipmentEnumValue.name());

答案 1 :(得分:3)

我遇到了这个问题,但找不到一个好的解决方案。

我最终解决的解决方案是插入一个String数组:

conn.createArrayOf("varchar", elements.toArray());

并在DB中进行转换:

CREATE OR REPLACE FUNCTION cast_meal_array(src_str character varying[]) RETURNS meal_type[] AS $$
BEGIN
RETURN src_str::text[]::meal_type[];
END;
$$ LANGUAGE plpgsql;

DROP CAST IF EXISTS (character varying[] as meal_type[]);
CREATE CAST (character varying[] AS meal_type[]) WITH FUNCTION cast_meal_array(character varying[]) AS assignment;

我对此解决方案不满意,但它确实有效,并且不需要任何特定的JDBC魔法。

答案 2 :(得分:1)

您正在尝试在普通JDBC中执行两个非标准的事情:枚举和数组。它们都不是非常简单 - 尽管两者都可以完成。但我建议不要两者:我更喜欢使用ad-hoc-enums(只是某些参数表中的整数),并且避免在数据库中使用数组,除非是非常特殊的情况。如果你坚持,一次攻击一个问题。

顺便说一下,你还有另外两个问题:带有混合大小写的标识符(表和列名)(必须引用以避免postgresql折叠为小写),以及一个带有保留sql字(日期)作为名称的列。这不错,但它肯定不会让你的开发人员生活更轻松...... 更多BTW:在\"equipment \"

之后注意那个空间