spring jdbc和复合主键

时间:2010-06-28 15:22:54

标签: java spring jdbc

在插入行时,sp​​ring jdbc中是否有一种方法可以返回复合主键。 此复合主键由来自单独序列的值组成

非常感谢任何帮助

此致 达明

4 个答案:

答案 0 :(得分:3)

这是一个完整的例子(在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上。它实际上返回整行,就好像您在刚插入的行上执行select一样)。相同的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;
    }

}

答案 1 :(得分:0)

以下是单个密钥的基本概念。最后的长id是关键。如果您有多个序列,我建议您只使用两个单独的语句来获取每个生成的密钥。

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();

答案 2 :(得分:0)

您使用的数据库服务器是什么? MySQL每个表只允许一个auto_increment字段,我想这通常就是这种情况,但不知道你的设置很难说。假设表中只有一个auto_generated字段,那么INSERT必须知道进入第二个PK字段的值。 Robert的代码应该用于检索生成的键值,而最干净的解决方案可能是在事后使用生成的键和您已经拥有的值执行SELECT。

答案 3 :(得分:0)

我认为你需要的是GeneratedKeyHolder.getKeys()。代码看起来像this example,除非您必须致电

keyHolder.getKeys()

而不是

keyHolder.getKey()