新建一张表,表的ID是自增的,如何在新增时返回这条数据生成的主键ID。
这个有实际使用案例,比如多表之间有关系时,下面的表要使用上面表的主键,那么就必须获得上面新增数据的主键。
有两种方式,第一种是查询这个表下一个要生成的ID,比如现在数据库有一条数据,那下一个ID是2,多次查询不使用的情况下一直返回2。如果新增了一个数据2但是删除的话,再查询返回3。
select AUTO_INCREMENT as id from INFORMATION_SCHEMA.TABLES where TABLE_NAME='test';
写一个JDBC来测试下:
package com.test;import java.sql.*;public class Test2 { // MySQL 8.0 以下版本 - JDBC 驱动名及数据库 URL // static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; // static final String DB_URL = "jdbc:mysql://localhost:3306/test"; // MySQL 8.0 以上版本 - JDBC 驱动名及数据库 URL static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver"; static final String DB_URL = "jdbc:mysql://localhost:3306/test?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC"; // 数据库的用户名与密码,需要根据自己的设置 static final String USER = "root"; static final String PASS = "111111"; public static void main(String[] args) { Connection conn = null; PreparedStatement pstmt = null; try { // 注册 JDBC 驱动 Class.forName(JDBC_DRIVER); // 打开链接 System.out.println("连接数据库..."); conn = DriverManager.getConnection(DB_URL, USER, PASS); String sql = "select AUTO_INCREMENT as id from INFORMATION_SCHEMA.TABLES where TABLE_NAME='test';"; pstmt = conn.prepareStatement(sql); ResultSet rs = pstmt.executeQuery(); while(rs.next()){ System.out.println("ID: " + rs.getInt("id")); } // 完成后关闭 pstmt.close(); conn.close(); System.out.println("执行结束"); } catch (Exception e) { e.printStackTrace(); } finally { try { if (pstmt != null) pstmt.close(); } catch (Exception ce) { } try { if (conn != null) conn.close(); } catch (Exception ce) { } } }}
上面代码会返回查询到的数据库主键。
还有一种方式我查了一下15年就写了,地址:http://www.javacui.com/java/342.html,就是新增时指定Statement.RETURN_GENERATED_KEYS,然后getGeneratedKeys()获得主键。
那使用了SpringJDBC时怎么操作?
SpringJDBC就是JdbcTemplate的操作方式,因为JdbcTemplate封装了对于JDBC的操作,如下代码演示了返回主键的操作,注意要使用数据库连接池。
package com.ruoyi;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.PreparedStatementCreator;import org.springframework.jdbc.support.GeneratedKeyHolder;import org.springframework.jdbc.support.KeyHolder;public class Test3 { public static void main(String[] args) { com.alibaba.druid.pool.DruidDataSource base = new com.alibaba.druid.pool.DruidDataSource(); base.setDriverClassName("com.mysql.cj.jdbc.Driver"); base.setUrl("jdbc:mysql://localhost:3306/test?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC"); base.setUsername("root"); base.setPassword("111111"); base.setInitialSize(1); base.setMaxActive(5); JdbcTemplate jdbcTemplate = new JdbcTemplate(base); final String sql="INSERT INTO `test` (`name`, `age`, `birthday`, `money`) VALUES (?, ?, ?, ?);"; KeyHolder keyHolder = new GeneratedKeyHolder(); jdbcTemplate.update(new PreparedStatementCreator() { @Override public PreparedStatement createPreparedStatement(Connection connection) throws SQLException{ PreparedStatement ps = connection.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS); ps.setInt(1, 10); ps.setInt(2, 10); ps.setString(3, "2021-5-11 23:23:59"); ps.setInt(4, 10); return ps; } }, keyHolder); System.out.println(keyHolder.getKey().intValue()); }}
如果是指定Statement.RETURN_GENERATED_KEYS的话,那就是一个简单查询。
那使用了MyBatis时怎么操作?
mybatis针对以上的不同生成策略以及不同的sql主键配置类型,将插入数据返回主键的解决方案分为一下几个情况:
1. 如果使用的数据库支持自动生成主键(如:MySQL 和 SQL Server),那么您就可以简单地将 useGeneratedKeys 设置为”true”,然后使用 keyProperty 设置你希望自动生成主键的字段就可以了。
<insert id="insertTest" parameterType="domain.Test" useGeneratedKeys=”true” keyProperty=”id”> insert into test (name) values (#{username})</insert>
MyBatis 还有另外一种方式为不支持自动生成主键的数据库及 JDBC 驱动来生成键值,下面展示一个能够随机生成 ID 的例子
<insert id="insertTest" parameterType="domain.Test"> <selectKey keyProperty="id" resultType="java.lang.integer" order="BEFORE"> select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1 </selectKey> insert into test (id,name) values (#{id},#{username})</insert>
把握住order的设置,在sql语句执行前(BEFORE)或者执行后(AFTER),执行selectKey 语句来获得主键就可以了,如上面例子selectKey首先执行,生成随机的主键,这时候Test对象中的id首先被赋值了,然后才会调用insert 语句。这相当于在您的数据库中自动生成键值,不需要编写复杂的 java 代码。
当然如果主键为字符也可以使用UUID。
<selectKey resultType="java.lang.String" order="BEFORE" keyProperty="id"> SELECT uuid()</selectKey>
END