[转] Java 插入表记录后得到自增的id (附3种方法代码)
转自:https://blog.csdn.net/yaerfeng/article/details/7231093
在MySQL中,使用auto_increment类型的id字段作为表的主键,并用它作为其他表的外键,形成“主从表结构”,这是数据库设计中常见的用法。但是在具体生成id的时候,我们的操作顺序一般是:先在主表中插入记录,然后获得自动生成的id,以它为基础插入从表的记录。
这里面有个困难,就是插入主表记录后,如何获得它对应的id。通常的做法,是通过“select max(id) from tablename”的做法,但是显然这种做法需要考虑并发的情况,需要在事务中对主表加以“X锁“,待获得max(id)的值以后,再解锁。这种做法需要的步骤比较多,有些麻烦,而且并发性也不好。有没有更简单的做法呢?
答案之一是通过select LAST_INSERT_ID()这个操作。乍一看,它和select max(id)很象,但实际上它是线程安全的。也就是说它是具体于数据库连接的。下面通过实验说明:
1、在连接1中向A表插入一条记录,A表包含一个auto_increment类型的字段。
2、在连接2中向A表再插入一条记录。
3、结果:在连接1中执行select LAST_INSERT_ID()得到的结果和连接2中执行select LAST_INSERT_ID()的结果是不同的;而在两个连接中执行select max(id)的结果是相同的。
其实在MSSQL中SCOPE_IDENTITY()和IDENT_CURRENT()的区别和这里是类似的。使用SCOPE_IDENTITY()可以获得插入某个IDENTITY字段的当前会话的值,而使用IDENT_CURRENT()会获得在某个IDENTITY字段上插入的最大值,而不区分不同的会话。
注:使用select last_insert_id()时要注意,当一次插入多条记录时,只是获得第一次插入的id值,务必注意!
当然,我们还可以使用另一种更加便捷的方法:在JDBC追加记录后,使用API获得新追加记录的主键值。
这个实现使用了Statement的getGeneratedKeys方法,
当Statement追加了一条记录后,可以直接调用getGeneratedKeys方法获得新追加记录的key。
测试程序如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement; public class GetGenerateKey
{
public static void main(String[] args) throws Exception
{
create();
} public static void create() throws Exception
{
System.setProperty("jdbc.drivers", "com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc", "root", "");
Statement st = conn.createStatement();
String sql = "insert into user (name, birthday, money) values ('beck', '1949-10-01', 60)";
st.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
ResultSet rs = st.getGeneratedKeys();
if (rs.next())
{
int id = rs.getInt(1);
System.out.println ("生成记录的key为 :" + id);
}
st.close();
conn.close();
}
}
总结:这个API方法提供的好处就是不用重新再执行一次查询获得新记录的key值。减少了工作量和服务器的负担。
注意点,在执行executeUpdate方法的时候,要指定返回生成key的选项。
===========================================================
2种方法的java 代码
// 用这种方法能得到插入自增的id 很好用
PreparedStatement pstmt = conn.prepareStatement(sql.toString(),PreparedStatement.RETURN_GENERATED_KEYS);
for (int i = 0; i < pars.length; i++)
{
pstmt.setObject(i+1, pars[i]);
}
pstmt.executeUpdate(); long autoIncKeyFromApi = -1;
ResultSet rs = pstmt.getGeneratedKeys();
if (rs.next())
{
autoIncKeyFromApi = rs.getInt(1);
}
return autoIncKeyFromApi;
qRunner.update(conn,sql.toString(),pars);
Long zsysqID = (Long) qRunner.query(conn, "SELECT LAST_INSERT_ID()", new ScalarHandler(1));
[转] Java 插入表记录后得到自增的id (附3种方法代码)的更多相关文章
- 从数据表中随机抽取n条数据有哪几种方法(join实现可以先查数据然后再拼接)
从数据表中随机抽取n条数据有哪几种方法(join实现可以先查数据然后再拼接) 一.总结 一句话总结:最好的是这个:"SELECT * FROM table WHERE id >= (( ...
- java中把文件拷贝到指定目录下最简单几种方法
java中把文件拷贝到指定目录下最简单几种方法 String savePath = "D:/file";// 文件保存到d盘的file目录下 File savefile = n ...
- Spring中新建记录后返回自增主键的处理方法
接手一个旧系统改造的过程,要插入后立即返回自增值,不能重构guid类型主键,Spring提供了很优美的机制. Spring利用GeneratedKeyHolder,提供了一个可以返回新增记录对应主键值 ...
- Mybatis中,当插入数据后,返回最新主键id的几种方法,及具体用法
insert元素 属性详解 其属性如下: parameterType ,入参的全限定类名或类型别名 keyColumn ,设置数据表自动生成的主键名.对特定数据库(如PostgreSQL),若自动生成 ...
- 哈希表(一):解决hash冲突的几种方法
(一)线性探测法 线性探测法是最简单的处理冲突的方法. (1)插入元素:插入元素时,如果发生冲突,算法将从该槽位向后遍历哈希表,直到找到表中的下一个空槽,并将该值放入到空槽当中. (2)查找元素:查找 ...
- Android 记录和恢复ListView滚动的位置的三种方法
本文主要介绍记录和恢复listView滚动位置的3种方法(1)记录listView滚动到的位置的坐标(推荐)(2)记录listView显示在屏幕上的第一个item的位置(3)通知适配器数据改变. 有时 ...
- Android(java)学习笔记106:Android设置文本颜色的4种方法
1. Android设置文本颜色的4种方法: (1)利用系统自带的颜色类: tv.setTextColor(android.graphics.Color.RED); (2)数字颜色表示: tv.set ...
- mysql存储过程之遍历多表记录后插入第三方表中
自从学过存储过程后,就再也没有碰过存储过程,这是毕业后写的第一个存储过程. 因为项目里设备的种类比较多,分别存在不同的数据表中,java中对应不同的java bean对象,想要统一管理有点困难.最近正 ...
- 表设置了自增后往里面插入不自增的id时的处理方法
SET IDENTITY_INSERT 表名 ON 中间写insert语句,但是这里必须把列名更上 SET IDENTITY_INSERT 表名 OFF
随机推荐
- 如何用PYTHON代码写出音乐
什么是MIDI 博主本人虽然五音不全,而且唱歌还很难听,但是还是非常喜欢听歌的.我一直在做这样的尝试,就是通过人工智能算法实现机器自动的作词和编曲(在这里预告下,通过深度学习写歌词已经实现了,之后会分 ...
- MVC:@RenderBody、@RenderPage、@RenderSection用法
本文导读:在Razor引擎中没有了“母版页”,取而代之的是叫做“布局”的页面(_Layout.cshtml)放在了共享视图文件夹中.模板页:@RenderBody()占位符:局部页面:@RenderP ...
- VGG 19
关于VGG19的一些参考资料 http://www.cnblogs.com/vipyoumay/archive/2017/11/23/7884472.html https://cloud.tencen ...
- 面试题-mysql
Sql :UPDATE test SET sex = CASE sex WHEN 'm' THEN 'f' ELSE 'm' END;
- codeforces 468B two set(并查集)
链接 B. Two Sets 题意 给两个集合A B,两个数a b,n个数x,分配n个数到两个集合,要求x , a-x在同一个集合,x , b-x在同一个集合,属于A集合的数输出0,B的输出1,无解输 ...
- vc++如何创建程序-构造函数
如果给Animal带参,则提示没有缺省的构造函数了,缺省就是不带参数的 改进:从子类当中向基类传递代参的,这样他就会给Animal传递400,300 对一个常量来调用 #include<iost ...
- Javase 简单练习
public class Test10 { public static void main(String[] args) { System.out.println("------------ ...
- 使用maven创建springMVC时返回页面报错
这是由于你的 Maven 编译级别是 jdk1.5 或以下,而你导入了 jdk1.6 以上的依赖包 解决办法: <build> <finalName></finalNam ...
- 告诉你 SQL 数据库与 NoSQL 数据库的区别
简单来说 SQL 数据库和 NoSQL 数据库有着共同的目标:存储数据,但存储的方式不同 一. 表 SQL中的表结构具有严格的数据模式约束: 存储数据很难出错. NoSQL存储数据更加灵活自由:可能导 ...
- hdu 1556 线段树区间延迟更新好题
656mS #include<stdio.h> #include<stdlib.h> #define N 110000 struct node { int x,y,yanchi ...