如何在使用Spring JDBCTemplate将新数据记录插入数据库后获取生成的ID?

16

在使用Spring JDBCTemplate时,我遇到了一个非常常见的问题。我想在将新数据记录插入数据库后获取ID值,该ID值将被引用到另一个相关表中。我尝试使用以下方式进行插入,但总是返回1而不是实际的唯一ID。(我使用MySQL作为数据库)

public int insert(BasicModel entity) {
    String insertIntoSql = QueryUtil.getInsertIntoSqlStatement(entity);

    log.info("SQL Statement for inserting into: " + insertIntoSql);

    return this.jdbcTemplate.update(insertIntoSql);
}
3个回答

16

JdbcTemplate.update()返回:

受影响的行数。

对于INSERT语句,这个值总是1。不同的数据库以不同的方式支持生成的键的提取,但大多数JDBC驱动程序都将其抽象出来,并且JdbcTemplate也支持此功能。引用12.2.8检索自动生成的键

一个update()方便方法支持检索数据库生成的主键。此支持是JDBC 3.0标准的一部分;有关详细信息,请参见规范的第13.6章。

基本上,您需要更加详细的语句如下:

final String insertIntoSql = QueryUtil.getInsertIntoSqlStatement(entity);
KeyHolder keyHolder = new GeneratedKeyHolder();

jdbcTemplate.update(
  new PreparedStatementCreator() {
    public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
      return connection.prepareStatement(insertIntoSql, new String[] {"id"});
    }
  }, keyHolder);

return keyHolder.getKey().intValue();

1
嗨Tomasz,我尝试了你的方法,但在我的地方没有起作用。我已经长时间研究它,但是无法得到解决方案。请给予指导。http://stackoverflow.com/questions/24567633/get-back-the-primary-key-value-after-insertion-to-db2-table-by-keyholder - Panadol Chong
我们如何在批量更新中执行相同的操作? - PAA

7
你可以使用@Tomasz Nurkiewicz的答案,它肯定有效,但你不需要这样做: Spring提供了SimpleJdbcInsert,它“提供元数据处理以简化构建基本插入语句所需的代码”。
@Repository
public class UserDao {

    private JdbcTemplate jdbcTemplate;
    private SimpleJdbcInsert insertIntoUser;

    @Autowired
    public UserDao(DataSource datasource) {
        jdbcTemplate = new JdbcTemplate(datasource);
        insertIntoUser = new SimpleJdbcInsert(jdbcTemplate).withTableName("user").usingGeneratedKeyColumns("id_user");
    }

    public Number insertUser(User u) {
        final Map<String, Object> parameters = new HashMap<>();
        parameters.put("name", u.getName());

        return insertIntoUser.executeAndReturnKey(parameters);
    }
}


insertUser返回的“Number”是为用户插入生成的id_user。

谢谢,我喜欢这种方法,它起作用了。 - Codigo Morsa
文档:使用SimpleJdbc类简化JDBC操作 - David Tonhofer

6

@panadol-chong,需要对@tomasz-nurkiewicz的代码进行小修改才能在此处正常运行。

final String SQL = "INSERT INTO ... RETUNING id";

KeyHolder keyHolder = new GeneratedKeyHolder();

jdbcTemplate.update(connection -> {
    PreparedStatement ps = connection.prepareStatement(SQL, 
                           Statement.RETURN_GENERATED_KEYS);

    return ps;
}, keyHolder);

return keyHolder.getKey().intValue();

主要区别在于Statement.RETURN_GENERATED_KEYS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接