插入行并获取生成的ID

时间:2013-09-30 13:51:41

标签: java jdbctemplate spring-jdbc

我正在尝试使用Spring的JdbcTemplate类将一行插入名为transaction的MySQL表中,并获取生成的ID。相关代码是:

public Transaction insertTransaction(final Transaction tran) {

    // Will hold the ID of the row created by the insert
    KeyHolder keyHolder = new GeneratedKeyHolder();

    getJdbcTemplate().update(new PreparedStatementCreator() {
        public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {

            PreparedStatement ps = connection.prepareStatement(INSERT_TRAN_SQL);
            ps.setString(1, tran.getTransactionType().toString());

            Date sqlDate = new Date(tran.getDate().getTime());
            ps.setDate(2, sqlDate);
            ps.setString(3, tran.getDescription());

            return ps;
        }
    }, keyHolder);

    tran.setId(keyHolder.getKey().longValue());
    return tran;
}

但调用getJdbcTemplate().update

会抛出以下异常
  

java.sql.SQLException:未请求生成的密钥。   您需要将Statement.RETURN_GENERATED_KEYS指定为   Statement.executeUpdate()或Connection.prepareStatement()。

我可以插入行并获取生成的ID,而不会放弃JdbcTemplate吗?我使用的是Spring 2.5,MySQL 5.5.27和MySQL Connector 5.1.26。

3 个答案:

答案 0 :(得分:9)

有一种更简单的方法来获得这种行为:

protected JdbcTemplate            jdbcTemplate;
private SimpleJdbcInsert          insert;

    this.jdbcTemplate = new JdbcTemplate(this.databaseSetup.getDataSource());
    this.insert = new SimpleJdbcInsert(this.jdbcTemplate).withTableName(this.tableName).usingGeneratedKeyColumns(this.pkColumn);

然后创建一个名为parameters的Map,它将表中每个列名的值包含在内并插入如下记录:

    final Map<String, Object> parameters = new HashMap<>();
    parameters.put("empName", employee.getName()); // store the String name of employee in the column empName
    parameters.put("dept", employee.getDepartment()); // store the int (as Integer) of the employee in the column dept
    final Number key = this.insert.executeAndReturnKey(parameters);
    final long pk = key.longValue();

答案 1 :(得分:7)

按照以下方式准备Statement

PreparedStatement ps = connection.prepareStatement(
                           INSERT_TRAN_SQL, Statement.RETURN_GENERATED_KEYS);

底层JDBC驱动程序(通过Spring JdbcTemplate间接使用)需要提示您要检索生成的密钥。这可以在准备PreparedStatement

时完成
connection.prepareStatement(strSQL, Statement.RETURN_GENERATED_KEYS);

或在执行Statement

时执行
statement.executeUpdate(strSQL, Statement.RETURN_GENERATED_KEYS);

这也是java.sql.SQLException指向的内容。

答案 2 :(得分:0)

您可以像在步骤1中一样检索下一个序列号,然后可以像在步骤2中那样在insert语句中传递:

1 -

Integer nextSeq = (Integer) getJdbcTemplate().queryForObject(
        "select SEQ_CUSTOMER_ID.nextVal from dual", new Object[] {}, Integer.class);

2 -

getJdbcTemplate().update(
        "INSERT INTO customer "
        + "(CUST_ID, NAME, UPDATED) VALUES (?, ?, ?)",
        new Object[] { nextSeq ,customer.getName(),
                customer.getUpdated() });