Использование PreparedStatement для сохранения массива перечислений Java в массиве перечислений Postgres - PullRequest
3 голосов
/ 27 мая 2010

У меня есть 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[]
);

И, наконец, когда я запускаю свое приложение, у меня есть массив перечислений «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 ]

3 голосов
/ 27 мая 2010

Я столкнулся с этой проблемой и не смог найти хорошего решения.

Решение, на котором я остановился, заключалось в том, чтобы вставить массив String:

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

и для приведения в БД:

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.

3 голосов
/ 27 мая 2010

Вы должны прочитать это .

Я бы посоветовал, чтобы ваш код выглядел примерно так:

    // 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 голос
/ 27 мая 2010

Вы пытаетесь сделать две нестандартные вещи в простом JDBC: перечисления и массивы.Ни один из них не очень прост - хотя и то, и другое можно сделать.Но я советую против обоих: я предпочитаю использовать специальные-перечисления (просто целые числа в некоторой параметрической таблице) и избегать массивов внутри базы данных, за исключением очень особых случаев.Если вы настаиваете, атакуете одну проблему за раз.

Кстати, у вас есть две другие проблемы: идентификаторы (имена таблиц и столбцов) со смешанными регистрами (которые должны быть заключены в кавычки, чтобы избежать сворачивания postgresql в нижний регистр), истолбец с зарезервированным словом sql (дата) в качестве имени.Это неплохо, но, конечно, не облегчает жизнь вашему разработчику ... И еще: кстати: остерегайтесь этого места после \"equipment \"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...