- 2024-12-13 11:11:33
- 1493 热度
- 0 评论
新建一张表,表的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
- Spring(403)
- Boot(208)
- Spring Boot(187)
- Java(82)
- Cloud(82)
- Spring Cloud(82)
- Security(60)
- Spring Security(54)
- Boot2(51)
- Spring Boot2(51)
- Redis(31)
- SQL(29)
- Mysql(25)
- IDE(24)
- Dalston(24)
- JDBC(22)
- IDEA(22)
- mongoDB(22)
- MVC(22)
- Web(21)
- CLI(20)
- Alibaba(19)
- SpringMVC(19)
- SpringBoot(17)
- Docker(17)
- Eclipse(16)
- Vue(16)
- Git(16)
- JPA(15)
- Apache(15)
- ORA(15)
- Oracle(14)
- jdk(14)
- Tomcat(14)
- Linux(14)
- HTTP(14)
- Mybatis(14)
- XML(13)
- JdbcTemplate(13)
- OAuth(13)
- Nacos(13)
- Pro(13)
- JSON(12)
- OAuth2(12)
- Data(12)
- stream(11)
- int(11)
- Myeclipse(11)
- not(10)
- Bug(10)
- maven(9)
- Map(9)
- Hystrix(9)
- ast(9)
- APP(8)
- Bit(8)
- API(8)
- session(8)
- Window(8)
- Swagger(8)
- JavaMail(7)
- Cache(7)
- File(7)
- IntelliJ(7)
- mail(7)
- windows(7)
- too(7)
- HTML(7)
- Github(7)
- Excel(6)
- Log4J(6)
- pushlet(6)
- apt(6)
- read(6)
- Freemarker(6)
- WebFlux(6)
- JSP(6)
- Bean(6)
- error(6)
- Server(6)
- nginx(6)
- ueditor(6)
- jar(6)
- ehcache(6)
- UDP(6)
- RabbitMQ(6)
- star(6)
- and(6)
- Struts(5)
- string(5)
- script(5)
- Syntaxhighlighter(5)
- Tool(5)
- Controller(5)
- swagger2(5)
- ldquo(5)
- input(5)
- Servlet(5)
- Config(5)
- discuz(5)