mysql获取自增主键last_insert_id()和getGeneratedKey()

时间:2024-03-18 14:44:11

mysql获取自增主键有两种方式:

1.last_insert_id()是MYSQL提供的返回当前客户端(其实就是和Connection相关)最后一个insert或update中设置为AUTO_INCREMENT列的值。

2.getGeneratedKey()

 

二者区别以及使用场景介绍:

selectKey和useGeneratedKeys的异同

概括来说selectKey用于单个记录返回主键,useGeneratedKeys单记录多记录都能返回主键。

返回主键的方式用useGeneratedKeys是最佳实践,selectKey在某些情况下(单记录)不会返回主键。

具体坑如下:

1.insertOrUpdate时,selectKey只能正确返回插入时主键,无法正确返回更新时主键,useGenerateKeys在插入或者更新的情况下都能正确的返回主键。所以在insertOrUpdate时采用useGeneratedKey更具通用性。

2.批量insertOrUpdate时,在任何情况下都无法正确返回主键,所以程序逻辑请不要依赖批量insertOrUpdate返回主键。

 

具体使用:

  • last_insert_id()方式

Mybatis实践:【Mybatis默认是PrepareStatement,若要使用Statement 加标签 STATEMENT】

mysql获取自增主键last_insert_id()和getGeneratedKey()

JDBC实践:

同一个Connection执行插入后执行查询就可以啦。代码略

 

 

  • getGeneratedKey()方式

Mybatis实践:

mysql获取自增主键last_insert_id()和getGeneratedKey()

JDBC实践:(需要注意设置autoGeneratedKeys)

对于Statement来说:

Statement stmt = conn.createStatement();

String sql = "insert into user_info(username,age) values('tom',22)"; stmt.executeUpdate(sql,Statement.RETURN_GENERATED_KEYS);

ResultSet rs = stmt.getGeneratedKeys();

if(rs.next()){

    int key = rs.getInt(0);

}

对于PreparedStatement来说:

大多数数据库返回主键方式,例如Mysql

Connection connection = DriverUtils.getConnection();

String sql = "INSERT INTO user_info(name) VALUES (?)";

PreparedStatement preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); preparedStatement.setString(1, "1234");

preparedStatement.executeUpdate();

ResultSet generatedKeys = preparedStatement.getGeneratedKeys();

while (generatedKeys.next()) {

   long generateKey = generatedKeys.getLong(1);

}

Oracle方式返回主键,当然也可以用于mysql等数据库

由于Oracle生成主键的方式比较特别, Oracle 是采用序列方式产生主键的,所以上面的方式并不适用于Oracle,在返回时需要使用 String[] columnNames 指定所返回的列名。

Connection connection = DriverUtils.getConnection();

String sql = "INSERT INTO user_info(name) VALUES (?)";

String[] keysName = {"id"};

PreparedStatement preparedStatement = connection.prepareStatement(sql, keysName);

preparedStatement.setString(1, "1234");

preparedStatement.executeUpdate();

ResultSet generatedKeys = preparedStatement.getGeneratedKeys();

while (generatedKeys.next()) {

    long generateKey = generatedKeys.getLong(1);

}

 

补充:之所以需要设置autoGeneratedKeys原因是因为不指定会报错呀:

java.sql.SQLException: Generated keys not requested. You need to specify Statement.RETURN_GENERATED_KEYS to Statement.executeUpdate(), Statement.executeLargeUpdate() or Connection.prepareStatement().

从5.1.7版本之后的mysql-connector增加了返回GeneratedKeys的条件,若需要返回GeneratedKeys,则Statement.executeUpdate(), Statement.executeLargeUpdate() 或者Connection.prepareStatement().需要显示添加一个参数Statement.RETURN_GENERATED_KEYS 。

 

参考了下列文章:

https://blog.csdn.net/qq_27680317/article/details/81118070 很详尽的MyBatis返回自增主键实验