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】
JDBC实践:
同一个Connection执行插入后执行查询就可以啦。代码略
- getGeneratedKey()方式
Mybatis实践:
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返回自增主键实验