使用Spring JDBC新增记录如何返回自增主键值

  在项目中,我们经常遇到这样的情况,表主键值设置为自增长,也就是主键值不在应用层产生,而是在新增记录时,由数据库产生。当我们新增加一条记录时,为了唯一定位到该记录,我们需要获得该记录的主键值,而这需要在数据库保存数据后才能从数据库中返回主键值。当我们使用Hibernate作为持久化框架时,新对象在持久化之后,主键值会自动绑定到对象上,但是当我们使用JDBC的时候要如何获得主键值。

  在JDBC3.0规范中,当新增记录时,允许将数据库自动产生的主键值绑定到Statement或PreparedStatement中。使用Statement时,可以通过以下方法绑定主键值:

  int executeUpdate(String sql,int autoGeneratedKeys)

  也可以通过Connection创建绑定自增值的PreparedStatement:

  PreparedStatement prepareStatement(String sql,int autoGeneratedKeys)

  当autoGeneratedKeys参数设置为Statement.RETURN_GENERATED_KEYS值时即可绑定数据库产生的主键值,设置为Statement.NO_GENERATED_KEYS时,不绑定主键值。如下代码所示:

Statement stmt = conn.createStatement();
String sql = "insert into user(username,age) values('tom',22)";
stmt.executeUpdate(sql,Statement.RETURN_GENERATED_KEYS);
ResultSet rs = stmt.getGeneratedKeys();
if(rs.next()){
    int key = rs.getInt(0);
}

  Spring利用这一技术,提供了一个可以返回新增记录对应主键值的方法;

  int update(PreparedStatementCreator psc,KeyHolder generatedKeyHolder)

  org.springframework.jdbc.support.KeyHolder是一个回调接口,Spring使用它保存新增记录对应的主键,该接口的接口方法描述为:

  •   Number getKey() throws InvalidDataAccessApiUsageException

  当仅插入一行记录时,主键不是复合键而是数字类型时,通过该方法可以直接返回新的主键值。如果是复合主键,或者有多个主键返回时,该方法抛出InvalidDataAccessApiUsageException。

  •   Map<String,Object> getKeys() throws InvalidDataAccessApiUsageException

  如果是复合主键,则列名和列值构成Map中的一个Entry。如果返回的是多个主键,则该方法抛出InvalidDataAccessApiUsageException异常。

  •   List<Map<String ,Object>> getKeyList()

  如果返回多个主键,即PreparedStatement新增了多条记录,则每一个主键对应一个Map,多个Map构成一个List。

  Spring为KeyHolder接口指代了一个通用的实现类GenerateKeyHolder,该类返回新增记录时的自增长主键值。我们可以修改上面的代码使用Spring jdbc实现:

final String sql = "insert into user(username,age) values('tom',22)";
        KeyHolder keyHolder = new GeneratedKeyHolder();
        jdbcTemplate.update(new PreparedStatementCreator() {
            public PreparedStatement createPreparedStatement(Connection arg0)
                    throws SQLException {
                PreparedStatement ps = conn.prepareStatement(sql);
                return ps;
            }
        }, keyHolder);
System.out.println(
"新插入数据的主键是:" + keyHolder.getKey().intValue());

 

  

posted @ 2012-11-26 01:56  行在途中  阅读(8364)  评论(0编辑  收藏  举报