在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();

}

}

程序运行结果:

生成记录的key为 :9

数据库的记录为:

1

+----+----------+------------+-------+

2

| id | name | birthday | money |

3

+----+----------+------------+-------+

4

| 9 | beck | 1949-10-01 | 60 |

5

+----+----------+------------+-------+

总结:这个API方法提供的好处就是不用重新再执行一次查询获得新记录的key值。减少了工作量和服务器的负担。

注意点,在执行executeUpdate方法的时候,要指定返回生成key的选项。

===========================================================

2种方法的java 代码

Java代码1

// 用这种方法能得到插入自增的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;

Java代码2

qRunner.update(conn,sql.toString(),pars);

Long zsysqID = (Long) qRunner.query(conn, "SELECT LAST_INSERT_ID()", new ScalarHandler(1));

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

java获取新insert数据自增id_java获取新insert数据自增id的实现方法相关推荐

  1. jdbc 3种获得mysql插入数据的自增字段值的方法_【JDBC】向数据表插入数据时,自动获取生成的主键...

    数据表设计时,一般都会有一个主键(Key)(自己指定),有时也可以使用联合主键: 有许多数据库提供了隐藏列为表中的每行记录分配一个唯一键值(如:rowid): 当我们没有指定哪一列作为主键key时,数 ...

  2. java stringbuffer 转数组_JAVA之旅(十七)——StringBuffer的概述,存储,删除,获取,修改,反转,将缓存区的数据存储到数组中,StringBuilder...

    JAVA之旅(十七)--StringBuffer的概述,存储,删除,获取,修改,反转,将缓存区的数据存储到数组中,StringBuilder 讲完String,我们来聊聊他的小兄弟 一.StringB ...

  3. Java通过steam实现数据去重、去重获取最新一条

    目录 1.添加依赖 2.测试实体类 3.三种方式去 1.添加依赖 <dependency><groupId>com.alibaba</groupId><art ...

  4. 怎么获取codeforces的数据_手把手教你学会新媒体运营——如何通过数据分析来优化新媒体运营...

    一般来说,我们希望运营的新媒体的每篇内容都可以获得高打开率和高分享率.但事实并不总是如愿,因此,在新媒体运营过程当中,我们需要不断地优化自身内容,以求可以获得更多的关注和流量.那么我们今天来讨论下如何 ...

  5. java获取xlsx某列数据_Java读取Excel指定列的数据详细教程和注意事项

    本文使用jxl.jar工具类库实现读取Excel中指定列的数据. jxl.jar是通过java操作excel表格的工具类库,是由java语言开发而成的.这套API是纯Java的,并不依赖Windows ...

  6. php新浪获取ip接口,【php】利用新浪api接口与php获取远程数据的步骤,获取IP地址,并获取相应的IP归属地...

    [php]利用新浪api接口与php获取远程数据的方法,获取IP地址,并获取相应的IP归属地 本文与<[Servlet]Javaweb中,利用新浪api接口,获取IP地址,并获取相应的IP归属地 ...

  7. Python爬虫新浪新闻网【使用selenium获取JS加载的动态数据】

    1 requests爬取网站html文本 使用requests模块的get方法,直接爬取新浪网站的html文本:需要注意的是 res.encoding = "utf-8",而不是r ...

  8. Java获取任务管理器内存、各磁盘内存、CPU使用率数据

    文章目录 1.获取任务管理器运行内存.各磁盘内存 2.获取CPU使用率 1.获取任务管理器运行内存.各磁盘内存 1.代码实现: /*** 获取内存使用情况*/public static void ge ...

  9. java阴阳师抽卡算法_阴阳师详解新的抽卡机制 全图鉴和SP获取更加简单

    原标题:阴阳师详解新的抽卡机制 全图鉴和SP获取更加简单 阴阳师随着大岳丸活动的临近,马上大家就要再次进入抽卡的热潮中了,而这次的新SSR大岳丸的获取,又一次更新了新的抽卡机制,本次就带来新抽卡机制详 ...

最新文章

  1. es任务 如何kill_kill进程的方法
  2. 定义一个有参宏SWAP(t,x,y),用以交换t类型的两个参数的值
  3. mono-3.4.0 源码安装时出现的问题 [do-install] Error 2 [install-pcl-targets] Error 1 解决方法
  4. 设计模式 — Overview
  5. Java自动化邮件中发送图表(四)之javafx Chart
  6. 学成在线--11.RabbitMQ快速入门
  7. 十五、CSS 3新特性详解(三)——3D转换(位移、旋转、呈现)、透视perspective、旋转rotateX、Y、Z、呈现transform-style
  8. C编译: 使用gdb调试
  9. Linux/Centos源码安装python3任意版本
  10. ssh汉字乱码怎么办_LINUX SSH显示中文乱码,怎么解决?
  11. NYOJ260 - 数数小木块
  12. Java中抽象类和接口的区别 经典(转)
  13. appinventor认识
  14. 用C语言开发NES游戏(CC65) 简介
  15. JAVA逻辑推理题1-谁是凶手
  16. Failed to introspect annotated methods on class 异常
  17. 为什么delphi编译生成的exe文件这么大?
  18. HTML5-布局篇( 总结 )
  19. CentOS7 使用 kubeadm 搭建 kubernetes 集群(极速篇)
  20. 微服务系列笔记之Go-Micro

热门文章

  1. springboot idea debug 模式下启动特别忙,且无法访问
  2. 1.10.返回四舍五入后的值.round()
  3. 基于Promise对象的新一代Ajax API--fetch
  4. 黑马程序员-Java-面向对象篇上《二》
  5. ASP.NET抓取网页内容
  6. asp.net mvc 性能测试工具 - Glimpse
  7. SQL Serve 查询所有可用的数据库语句
  8. 让redhat5以yum方式安装软件
  9. UVa1422 Processor
  10. 小隐隐于野:基于TCP反射DDoS攻击分析