MySQL 中的 LAST_INSERT_ID() 函数详解

news2024/10/23 5:24:12

全文目录:

    • 开篇语
    • 前言
    • 摘要
    • 简介
    • 概述
      • `LAST_INSERT_ID()` 函数的用途
      • `LAST_INSERT_ID()` 函数的基本用法
      • 注意事项
    • 核心源码解读
      • 插入数据并获取自增 ID 的 Java 示例代码
    • 案例分析
      • 案例1:订单系统中的应用
    • 应用场景演示
      • 场景1:博客系统的文章和评论关系
      • 场景2:社交媒体平台的用户注册流程
    • 优缺点分析
      • 优点
      • 缺点
    • 类代码方法介绍及演示
    • 测试用例
      • 测试结果预期
    • 测试代码分析
    • 小结
    • 总结
    • 寄语
    • 文末

开篇语

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言

在数据库操作中,常常需要获取刚刚插入的一条数据的主键值,尤其是在表的主键是自增的场景中。MySQL 提供了 LAST_INSERT_ID() 函数,它可以帮助我们获取最近一次插入操作生成的自增主键。本文将详细介绍 LAST_INSERT_ID() 函数的使用方法及其在 Java 开发中的应用。

摘要

LAST_INSERT_ID() 是 MySQL 中一个非常有用的函数,它返回由上一次 INSERT 操作生成的自增 ID。该函数在处理多表关联、插入数据后需要获取主键等场景中尤为重要。本文将以 Java 语言为例,结合实际代码,详细讲解 LAST_INSERT_ID() 的用法以及其注意事项。

简介

LAST_INSERT_ID() 函数是 MySQL 提供的一个内置函数,它返回最近一次 INSERT 操作生成的自增 ID 值。这个函数只针对当前会话有效,因此可以在多用户环境中避免 ID 冲突。同时,LAST_INSERT_ID() 通常与自增列(AUTO_INCREMENT)配合使用,尤其在需要获取新插入记录的主键时,显得十分方便。

概述

LAST_INSERT_ID() 函数的用途

LAST_INSERT_ID() 函数通常用于以下场景:

  • 插入记录后需要立即获取其生成的主键值。
  • 当表的主键为自增列时,用于记录关联插入。
  • 应用程序中需要通过新插入的记录 ID 来处理后续操作(如插入子表、关联其他记录)。

LAST_INSERT_ID() 函数的基本用法

LAST_INSERT_ID() 函数返回当前会话中最后一次插入操作生成的自增 ID。它的典型使用场景如下:

INSERT INTO users (name, email) VALUES ('John', 'john@example.com');
SELECT LAST_INSERT_ID();

上面的 SQL 语句在插入 users 表后,返回新插入记录的自增 ID。

注意事项

  1. LAST_INSERT_ID() 只对当前会话有效,不会受到其他用户的插入操作影响。
  2. 如果执行了多次 INSERTLAST_INSERT_ID() 只会返回最后一次操作生成的自增 ID。
  3. 如果没有进行自增列的插入,LAST_INSERT_ID() 会返回 0。

核心源码解读

在 Java 开发中,可以通过 JDBC 执行 INSERT 操作并获取 LAST_INSERT_ID() 的返回值。下面是基本的操作流程:

  1. 插入一条记录到自增主键的表。
  2. 使用 Statement.getGeneratedKeys() 或执行 SELECT LAST_INSERT_ID() 语句获取生成的 ID。

插入数据并获取自增 ID 的 Java 示例代码

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

public class LastInsertIdExample {
    private static final String DB_URL = "jdbc:mysql://localhost:3306/mydb";
    private static final String USER = "root";
    private static final String PASSWORD = "your_password";

    public static void main(String[] args) {
        String insertSQL = "INSERT INTO users (name, email) VALUES (?, ?)";

        try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASSWORD);
             PreparedStatement pstmt = conn.prepareStatement(insertSQL, Statement.RETURN_GENERATED_KEYS)) {
             
            // 设置插入数据的参数
            pstmt.setString(1, "Alice");
            pstmt.setString(2, "alice@example.com");

            // 执行插入操作
            int affectedRows = pstmt.executeUpdate();

            // 确保插入成功
            if (affectedRows > 0) {
                // 获取插入操作的自增 ID
                try (ResultSet generatedKeys = pstmt.getGeneratedKeys()) {
                    if (generatedKeys.next()) {
                        long lastInsertId = generatedKeys.getLong(1);
                        System.out.println("Last Inserted ID: " + lastInsertId);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

案例分析

案例1:订单系统中的应用

在订单系统中,当插入订单主表后,通常需要获取该订单的主键 ID,然后再插入订单详情表。假设我们有一个 orders 表,它的主键是自增列。在插入订单记录后,我们可以使用 LAST_INSERT_ID() 来获取刚刚插入的订单 ID,以便插入订单详情表。

String insertOrderSQL = "INSERT INTO orders (order_date, customer_id) VALUES (?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(insertOrderSQL, Statement.RETURN_GENERATED_KEYS)) {
    pstmt.setDate(1, new java.sql.Date(System.currentTimeMillis()));
    pstmt.setInt(2, customerId);
    pstmt.executeUpdate();
    
    try (ResultSet rs = pstmt.getGeneratedKeys()) {
        if (rs.next()) {
            int orderId = rs.getInt(1);
            System.out.println("Inserted Order ID: " + orderId);
        }
    }
}

应用场景演示

场景1:博客系统的文章和评论关系

在博客系统中,当用户发表文章后,我们需要获取该文章的主键 ID,以便为后续的评论插入做好准备。LAST_INSERT_ID() 可以帮助我们获取刚刚发表的文章 ID,从而关联后续的评论和其他操作。

场景2:社交媒体平台的用户注册流程

在社交媒体平台上,当用户注册成功后,系统会生成一个唯一的用户 ID。我们可以使用 LAST_INSERT_ID() 获取新用户的 ID,并将该 ID 用于后续的用户数据初始化操作。

优缺点分析

优点

  1. 高效便捷LAST_INSERT_ID() 提供了简便的方式来获取新插入记录的自增主键值,减少了查询的复杂性。
  2. 避免冲突:因为它只在当前会话中有效,能够避免在并发环境下的 ID 混淆问题。
  3. 灵活使用:可以与任何自增主键的表配合使用,且支持多种数据库操作场景。

缺点

  1. 仅适用于自增主键LAST_INSERT_ID() 只能返回自增列的值,如果表没有使用自增主键,这个函数就无效。
  2. 会话依赖:它依赖于当前会话,无法跨会话获取结果,因此在某些复杂场景下可能需要额外的处理逻辑。

类代码方法介绍及演示

以下是封装 LAST_INSERT_ID() 操作的一个类示例,展示如何在插入数据后获取生成的自增 ID:

public class UserDAO {
    private static final String DB_URL = "jdbc:mysql://localhost:3306/mydb";
    private static final String USER = "root";
    private static final String PASSWORD = "your_password";

    public long insertUser(String name, String email) throws Exception {
        String insertSQL = "INSERT INTO users (name, email) VALUES (?, ?)";
        try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASSWORD);
             PreparedStatement pstmt = conn.prepareStatement(insertSQL, Statement.RETURN_GENERATED_KEYS)) {
             
            pstmt.setString(1, name);
            pstmt.setString(2, email);
            pstmt.executeUpdate();

            try (ResultSet rs = pstmt.getGeneratedKeys()) {
                if (rs.next()) {
                    return rs.getLong(1);
                }
            }
        }
        return -1;
    }
}

测试用例

以下是使用 UserDAO 类插入用户并获取自增 ID 的测试用例:

public class UserDAOTest {
    public static void main(String[] args) {
        UserDAO userDAO = new UserDAO();
        
        try {
            long userId = userDAO.insertUser("Bob", "bob@example.com");
            System.out.println("Inserted user ID: " + userId);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

测试结果预期

执行以上代码后,控制台将输出新插入的用户 ID。若插入成功,输出格式应为:

Inserted user ID: 101

测试代码分析

在测试用例中,通过调用 UserDAO.insertUser() 方法插入数据后,我们使用 getGeneratedKeys() 来获取 LAST_INSERT_ID() 的结果。测试代码通过插入一条记录,打印输出新生成的用户主键值。

小结

通过 LAST_INSERT_ID() 函数,我们可以高效地获取 MySQL 数据库中的自增主键值。无论是用户系统还是订单系统,这个函数都能简化数据库操作,避免复杂的查询逻辑。本文展示了如何通过 Java 代码实现对 LAST_INSERT_ID() 的调用,并结合实际

应用场景进行了解析。

总结

LAST_INSERT_ID() 是 MySQL 中一个非常实用的函数,特别适用于需要获取自增主键值的场景。在 Java 开发中,我们可以通过 JDBC 提供的 getGeneratedKeys() 方法来获取相同的结果。希望通过本文的讲解,大家能够更好地掌握并应用 LAST_INSERT_ID() 函数,优化数据库操作。

寄语

技术的精进离不开对细节的打磨。在每一次开发中,合理利用数据库的工具与函数,能为我们带来更高效、更简洁的代码。愿你在今后的项目中,能够从容应对数据库的每一个挑战。

… …

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

… …

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。

⭐️若有疑问,就请评论留言告诉我叭。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2221341.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

尚硅谷spark学习

p4 快速上手 -开发环境准备

基于工业互联网平台的智能工厂辅助制造企业数字化转型

制造业数字化转型已是大势所趋,工业互联网平台对于制造业数字化转型的支撑作用将会越来越强,其应用为制造企业生产和运营优化的能力提升提供了探索应用模式和路径。平台的不断创新和应用突破,将不断为制造业的升级转型赋能。实施制造业数字化…

C#线程详解及应用示例

简介 在编写应用程序实现业务功能过程中,为解决吞吐量和响应效率的问题,我们会用到多线程、异步编程两项重要的技术。通过它们来提高应用程序响应和高效。应用程序每次运行都会启动一个进程(进程是一种正在执行的程序)&#xff0…

基于node.js宜家宜业物业管理系统【附源码】

基于node.js宜家宜业物业管理系统 效果如下: 系统首页界面 业主登录界面 停车位页面 小区公告页面 管理员登录界面 管理员功能界面 物业管理员管理界面 缴费信息管理界面 物业管理员功能界面 研究背景 近年来互联网技术飞速发展,给人们的生活带来了极…

【数据分享】全国金融业-股票发行量和筹资额(1991-2021年)

数据介绍 一级标题指标名称单位金融业股票发行量亿股金融业A股发行量亿股金融业H股,N股发行量亿股金融业B股发行量亿股金融业股票筹资额亿元金融业A股筹资额亿元金融业配股筹资额亿元金融业H股,N股筹资额亿元金融业B股筹资额亿元 注:本文中的数据仅为示例&#xf…

Burp Suite Professional 2024.9 for macOS x64 ARM64 - 领先的 Web 渗透测试软件

Burp Suite Professional 2024.9 for macOS x64 & ARM64 - 领先的 Web 渗透测试软件 世界排名第一的 Web 渗透测试工具包 请访问原文链接:https://sysin.org/blog/burp-suite-pro-mac/ 查看最新版。原创作品,转载请保留出处。 作者主页&#xff1…

【数据结构】分治算法经典: 快速排序详解

快速排序(Quicksort)是一种高效的排序算法,最早由Tony Hoare在1960年提出。它采用了分治(Divide and Conquer)策略,平均时间复杂度为 O ( n log ⁡ n ) O(n \log n) O(nlogn),在大多数实际应用…

双十一开启极速达夜派;黑神话获泰国年度最佳游戏;AI 模型可帮助识别 17000 多种疾病的候选药物....| 网易数智日报

双 11 菜鸟在北京、上海、广州、杭州等城市开启「预售极速达夜派」服务 10 月 21 日,菜鸟在北京、上海、广州、杭州等城市开启「预售极速达夜派」服务,批量大促包裹实现小时级送达。 据介绍,在消费者支付尾款前,菜鸟供应链就已经…

项目结构(后端+前端)(若依)

项目结构(后端前端) 文章目录 项目结构(后端前端)前言一、后端结构1.若依 二、前端结构1. 总结 前言 方便了解项目结构 提示:以下是本篇文章正文内容: 一、后端结构 1.若依 com.ruoyi ├── ruoyi-adm…

【C++干货篇】——类和对象的魅力(四)

【C干货篇】——类和对象的魅力(四) 1.取地址运算符的重载 1.1const 成员函数 将const修饰的成员函数称之为const成员函数,const修饰成员函数放到成员函数参数列表的后面。const实际修饰该成员函数隐含的this指针(this指向的对…

Flutter Container容器组件实战案例

The Container widget is your design toolkit. It’s like the master builder that helps you structure and style your UI elements with precision. Whether you’re creating simple designs or complex layouts, the Container is your trusty tool for the job. “容器…

全能大模型GPT-4o体验和接入教程

GPT-4o体验和接入教程 前言一、原生API二、Python LangchainSpring AI总结 前言 Open AI发布了产品GPT-4o,o表示"omni",全能的意思。 GPT-4o可以实时对音频、视觉和文本进行推理,响应时间平均为 320 毫秒,和人类之间对…

【C++篇】深度解析类与对象(上)

目录 引言 一、类的定义 1.1类定义的基本格式 1.2 成员命名规范 1.3 class与struct的区别 1.4 访问限定符 1.5 类的作用域 二、实例化 2.1 类的实例化 2.2 对象的大小与内存对齐 三、this 指针 3.1 this指针的基本用法 3.2 为什么需要this指针? 3.3 t…

Java毕业设计 基于SpringBoot发卡平台

Java毕业设计 基于SpringBoot发卡平台 这篇博文将介绍一个基于SpringBoot发卡平台,适合用于Java毕业设计。 功能介绍 首页 图片轮播 商品介绍 商品详情 提交订单 文章教程 文章详情 查询订单  查看订单卡密 客服   后台管理 登录 个人信息 修改密码 管…

成都爱尔胡建斌院长讲解年纪大眼花?小心黄斑变性!

中老年朋友觉得年龄增加后,眼睛出现模糊是常态,但是眼花不止“老花眼”一种,要小心的是眼底病变! 眼花的形式有很多种,如果视线中间出现暗点视物变得模糊,很难看清周围的人脸,在看书看手机这种…

MATLAB(Octave)混电动力能耗评估

🎯要点 处理电动和混动汽车能耗的后向和前向算法模型(simulink),以及图形函数、后处理函数等实现。构建储能元数据信息:电池标称特性、电池标识符等以及静止、恒定电流和恒定电压等特征阶段。使用电流脉冲或要识别的等效电路模型类型配置阻抗…

jmeter学习(6)逻辑控制器-循环

循环执行 1、循环读取csv文件的值 2、foreach 读取变量,变量数字后缀有序递增,通过counter实现 ${__V(typeId${typeIdNum})} beansell断言 String typeIdNum vars.get("typeIdNum"); String response prev.getResponseDataAsString(); …

MAC 安装HomeBrew-亲自尝试,100%会成功

文章来自这里: https://zhuanlan.zhihu.com/p/620975942 安装指令: /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"执行完成后,输入下列命令验证 brew --version

AcWing 875:快速幂

【题目来源】https://www.acwing.com/problem/content/877/【题目描述】 给定 组 ,对于每组数据,求出 的值。【输入格式】 第一行包含整数 。 接下来 行,每行包含三个整数 。【输出格式】 对于每组数据,输出一个结果&#xff0…

初阶数据结构【3】--单链表(比顺序表还好的一种数据结构!!!)

本章概述 前情回顾单链表实现单链表彩蛋时刻!!! 前情回顾 咱们在上一章博客点击:《顺序表》的末尾,提出了一个问题,讲出了顺序表的缺点——有点浪费空间。所以,为了解决这个问题,我…