简体   繁体   English

插入行并获取生成的ID

[英]insert row and get generated ID

I'm trying to use Spring's JdbcTemplate class to insert a row into a MySQL table named transaction and get the generated ID. 我正在尝试使用Spring的JdbcTemplate类将一行插入名为transaction的MySQL表中并获取生成的ID。 The relevant code is: 相关代码是:

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;
}

But the following exception is thrown by the call to getJdbcTemplate().update 但是调用getJdbcTemplate().update会抛出以下异常

java.sql.SQLException: Generated keys not requested. java.sql.SQLException:未请求生成的密钥。 You need to specify Statement.RETURN_GENERATED_KEYS to Statement.executeUpdate() or Connection.prepareStatement(). 您需要将Statement.RETURN_GENERATED_KEYS指定为Statement.executeUpdate()或Connection.prepareStatement()。

Can I insert the row and get the generated ID, without abandoning JdbcTemplate ? 我可以插入行并获取生成的ID,而不放弃JdbcTemplate吗? I'm using Spring 2.5, MySQL 5.5.27 and MySQL Connector 5.1.26. 我使用的是Spring 2.5,MySQL 5.5.27和MySQL Connector 5.1.26。

There is an easier way to get that behaviour: 有一种更简单的方法来获得这种行为:

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

Then you create a Map called parameters which conmtains the values for each column name in your table and insert a record like this: 然后创建一个名为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();

Just prepare your Statement as follows 请准备好您的Statement ,如下所示

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

The underlying JDBC driver (used indirectly through the Spring's JdbcTemplate here) requires a hint that you would like to retrieve the generated keys. 底层JDBC驱动程序(在这里间接通过Spring的JdbcTemplate )需要提示您要检索生成的密钥。 This can be done either while preparing a PreparedStatement as 这可以在准备PreparedStatement完成

connection.prepareStatement(strSQL, Statement.RETURN_GENERATED_KEYS);

or, at the time of executing a Statement as 或者,在执行Statement

statement.executeUpdate(strSQL, Statement.RETURN_GENERATED_KEYS);

This is what your java.sql.SQLException is pointing at as well. 这也是java.sql.SQLException指向的内容。

You can retrieve the next sequence number like in step 1, then it can passed in the insert statement as in the step 2: 您可以像在步骤1中一样检索下一个序列号,然后它可以像在步骤2中那样在insert语句中传递:

1- 1-

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

2- 2-

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM