пружина jdbc и составные первичные ключи

Есть ли путь пружиной jdbc для возврата составного первичного ключа, когда строка вставляется. Этот составной первичный ключ составлен из значений от отдельных последовательностей

Любая справка значительно ценится

Отношения Damien

5
задан skaffman 28 June 2010 в 19:56
поделиться

4 ответа

Вот полный пример (протестирован на PostgreSQL 8.4):

Моя таблица:

CREATE TABLE test
(
  id serial NOT NULL,
  otherid serial NOT NULL,
  val text,
  CONSTRAINT test_pkey PRIMARY KEY (id, otherid)
)

Вот как вы получаете ключи обратно:

public void doStuff() {
    KeyHolder keyHolder = new GeneratedKeyHolder();
    jdbcTemplate.update(
            new PreparedStatementCreator() {
                public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
                    PreparedStatement ps = connection.prepareStatement("insert into test(val) values (?)", Statement.RETURN_GENERATED_KEYS);
                    ps.setInt(1, 42);
                    return ps;
                }
            },
            keyHolder);

    keyHolder.getKeys().get("id");
    keyHolder.getKeys().get("otherid");
}

Теперь, если вы хотите получить свой Составной ключ как экземпляр какого-то класса прямо из keyHolder, это не просто.

JdbcTemplate использует ColumnMapRowMapper для сопоставления сгенерированных ключей (сгенерированные ключи возвращаются как набор результатов, по крайней мере, в PostgreSQL. На самом деле он возвращает всю строку, как если бы вы выполняли выбор для только что вставленной строки). Тот же ColumnMapRowMapper используется в ряде других мест в JdbcTemplate.

Единственная возможная точка расширения здесь - это сам KeyHolder. Вот что вы можете сделать:

public void doStuff() {
    CompositeKeyHolder keyHolder = new CompositeKeyHolder();
    ... same code here ...

    keyHolder.getCompositeKey();
}


class CompositeKeyHolder extends GeneratedKeyHolder {
    private boolean converted;

    public CompositeKey getCompositeKey() {
        return new CompositeKey((Integer)this.getKeys().get("id"), (Integer)this.getKeys().get("otherid"));
    }
}


class CompositeKey {

    private Integer id;

    private Integer otherId;

    CompositeKey(Integer id, Integer otherId) {
        this.id = id;
        this.otherId = otherId;
    }

    public Integer getId() {
        return id;
    }

    public Integer getOtherId() {
        return otherId;
    }

}
4
ответ дан 15 December 2019 в 00:49
поделиться

Вот основная идея для одного ключа. Длинный идентификатор в конце - это ключ. Если у вас несколько последовательностей, я бы рекомендовал просто использовать два отдельных оператора для получения каждого сгенерированного ключа.

JdbcTemplate template = getJdbcTemplate();
KeyHolder keyHolder = new GeneratedKeyHolder();
template.update(
    new PreparedStatementCreator() {
        public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
            PreparedStatement ps = connection.prepareStatement(...);
            return ps;
        }
    },
    keyHolder);
long id = keyHolder.getKey().longValue();
0
ответ дан 15 December 2019 в 00:49
поделиться

Думаю, вам понадобится GeneratedKeyHolder.getKeys () . Код будет выглядеть как в этом примере , за исключением того, что вам нужно будет позвонить

keyHolder.getKeys()

вместо

keyHolder.getKey()
0
ответ дан 15 December 2019 в 00:49
поделиться

Какой сервер баз данных вы используете? MySQL допускает только одно поле auto_increment для каждой таблицы, и я предполагаю, что это часто имеет место, но, не зная вашей настройки, трудно сказать. Предполагая, что в вашей таблице есть только одно поле auto_generated, ваш INSERT должен был бы знать значение, входящее во второе поле PK. Код Роберта должен работать для получения сгенерированного значения ключа, и самым чистым решением, вероятно, было бы выполнить SELECT постфактум, используя этот сгенерированный ключ и значение, которое вы уже удерживали.

0
ответ дан 15 December 2019 в 00:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: