MySQL insert into添加数据并返回该条数据的id的方法

本文介绍在MyBatis中使用两种方法实现主键自动生成:一是通过配置insert标签的useGeneratedKeys和keyProperty属性;二是利用selectKey标签配合执行顺序属性order,确保在插入记录后能正确获取并设置自增主键。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在Mapper.xml中写SQL语句时添加

 1)insert按如下修改,添加属性 “useGeneratedKeys”和“keyProperty”,其中 keyProperty  Java 对象的属性名,而不是表格的字段名,通过该对象例如:keyword.getId()获取:
 <insert id="add" useGeneratedKeys="true"  keyProperty="id">
        insert into keybiao(name, type, time)  values (#{name},#{type},#{time})
    </insert>

 2)插入selectKey标签,获取同上
   <insert id="add">
    <!--selectKey  会将 SELECT LAST_INSERT_ID()的结果放入到传入的model的主键里面,
            keyProperty 对应的model中的主键的属性名,这里是 user 中的id,因为它跟数据库的主键对应
            order AFTER 表示 SELECT LAST_INSERT_ID() 在insert执行之后执行,多用与自增主键,
                  BEFORE 表示 SELECT LAST_INSERT_ID() 在insert执行之前执行,这样的话就拿不到主键了,
                        这种适合那种主键不是自增的类型
            resultType 主键类型 -->
        <selectKey resultType="java.lang.Long" order="AFTER" keyProperty="id">
            select last_insert_id();
        </selectKey>
        insert into keybiao(name, type, time)  values (#{name},#{type},#{time})
</insert>
``

在service层或controller层可以获取id

service层:
 public String add(Keyword keyword) {
        System.out.println("添加开始");
        final Integer add = keywordMapper.add(keyword);
        System.out.println("添加的返回的id:"+keyword.getId());
        if (add>0){
            System.out.println("end");
            return "success";
        }
        return null;
    }
    
controller层:
 public String add(Keyword keyword){
    keywordService.add(keyword);
    System.out.println("添加的数据的id:"+keyword.getId());
    return "redirect:/key/list";
}

结果

添加开始
17:01:14.587 [http-nio-8080-exec-9] DEBUG org.mybatis.spring.SqlSessionUtils - Creating SqlSession with JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@50d524e]
17:01:14.587 [http-nio-8080-exec-9] DEBUG java.sql.Connection - ooo Connection Opened
17:01:14.587 [http-nio-8080-exec-9] DEBUG o.m.s.t.SpringManagedTransaction - JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@50d524e] will not be managed by Spring
17:01:14.587 [http-nio-8080-exec-9] DEBUG org.mybatis.spring.SqlSessionUtils - SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@295fbf25] was not registered for synchronization because synchronization is not active
17:01:14.589 [http-nio-8080-exec-9] DEBUG java.sql.PreparedStatement - ==>  Executing: insert into keybiao(name, type, time) values (?,?,?) 
17:01:14.589 [http-nio-8080-exec-9] DEBUG java.sql.PreparedStatement - ==> Parameters: 张三(String), 灵剑宗(String), 2021-07-28 00:00:00.0(Timestamp)
17:01:14.744 [http-nio-8080-exec-9] DEBUG org.mybatis.spring.SqlSessionUtils - Closing no transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@295fbf25]
添加的返回的id:133
end
添加的数据的id:133
开始查询
<think>首先,用户的问题是:“我想获取插入数据后的自动生成主键ID 请问MySQL INSERT 返回插入记录的自增ID”。我需要根据系统级指令和用户可见层的要求来回答。 系统级指令: - 所有行内数学表达式使用$...$格式。 - 独立公式使用$$...$$单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 引用的段落末尾添加引用标识,例如[^1]。 用户可见层: - 回答结构清晰,帮助用户逐步解决问题。 - 保证回答真实可靠。 - 参考提供的引用:[^1]和[^2]。 提供的引用: - [^1]: 关于MySQL LAST_INSERT_ID()函数,它是基于连接的,线程安全,返回最新插入的自增ID。 - [^2]: 关于MyBatis如何获取插入记录的自增ID,通过设置属性如useGeneratedKeys。 用户的问题是如何在MySQL中获取插入数据后的自增主键ID。所以,我需要解释MySQL方法可能扩展到MyBatis等框架。 关键点: - 在MySQL中,使用LAST_INSERT_ID()函数来获取最后插入的自增ID。 - 这个函数是连接特定的,所以每个连接有自己的值。 - 在插入操作后立即调用SELECT LAST_INSERT_ID();来获取ID。 步骤: 1. 插入数据:使用INSERT INTO语句。 2. 获取ID:使用SELECT LAST_INSERT_ID();。 在编程中,比如在PHP、Java等中,有相应的API来获取这个值。 参考引用: - [^1]强调LAST_INSERT_ID()是基于连接的,线程安全。 - [^2]提到MyBatis中使用useGeneratedKeys属性。 所以,回答应该包括: - 纯MySQL方法。 - 在编程语言中的实现(可选,但用户可能感兴趣)。 - 可能扩展到ORM框架如MyBatis。 结构回答: - 逐步解释。 - 使用代码示例。 - 确保清晰。 生成相关问题: - 在回答结束后,添加相关问题部分。 数学表达式:用户问题不涉及数学,但如果有计算或公式,需要使用LaTeX。这里可能不需要,除非有示例。 回答结构: 1. 介绍:解释自增ID和LAST_INSERT_ID()函数。 2. 步骤:如何操作。 3. 代码示例:提供SQL示例。 4. 扩展:在编程中如何获取。 5. 相关问题。 使用中文回答。 最终回答应包括引用标识。</think>### 如何获取MySQL INSERT操作后的自增主键IDMySQL中,当表的主键设置为自增(AUTO_INCREMENT)时,插入数据后获取自动生成的主键ID是一个常见需求。MySQL提供了内置函数`LAST_INSERT_ID()`来安全地获取最新插入记录的自增ID值。以下我将逐步解释原理和实现方法,确保内容真实可靠,基于MySQL官方文档和常见实践[^1]。 #### 1. **核心原理:LAST_INSERT_ID()函数** - `LAST_INSERT_ID()`函数返回当前连接(Connection)中最新插入操作生成的自增ID值。 - 它是基于连接的,这意味着每个数据库连接独立维护自己的ID值,不会受其他客户端影响(线程安全)。 - 在插入单条记录时,它返回该记录的ID;在批量插入时,它返回第一条记录的ID[^1]。 - 公式:ID值满足自增序列,即如果当前最大ID为$n$,新插入记录的ID为$n+1$。 #### 2. **操作步骤:纯SQL方法** 在MySQL命令行或SQL客户端中,按顺序执行以下步骤: - **步骤1:插入数据** 使用`INSERT INTO`语句插入数据。例如,假设有一个表`users`,主键`id`为自增: ```sql INSERT INTO users (name, email) VALUES ('张三', 'zhangsan@example.com'); ``` - **步骤2:获取自增ID** 在同一个连接中立即执行: ```sql SELECT LAST_INSERT_ID(); ``` 这将返回一个标量值,如`1001`(具体值取决于当前自增状态)。 **注意事项**: - 必须在**同一个连接**中执行`SELECT LAST_INSERT_ID();`,否则可能返回错误值。 - 如果插入多条记录(如批量插入),`LAST_INSERT_ID()`只返回**第一条**记录的ID。例如: ```sql INSERT INTO users (name, email) VALUES ('李四', 'lisi@example.com'), ('王五', 'wangwu@example.com'); SELECT LAST_INSERT_ID(); -- 返回第一条记录(李四)的ID ``` - 在事务中,ID值在事务提交后才会持久化,但`LAST_INSERT_ID()`在插入后即可获取[^1]。 #### 3. **在编程语言中实现** 在应用中(如Java、Python、PHP),通过数据库驱动或ORM框架调用`LAST_INSERT_ID()`更高效。以下是常见语言的示例: - **Java (JDBC)** 使用`Statement.getGeneratedKeys()`方法: ```java try (Connection conn = DriverManager.getConnection(url, user, password); PreparedStatement stmt = conn.prepareStatement("INSERT INTO users (name, email) VALUES (?, ?)", Statement.RETURN_GENERATED_KEYS)) { stmt.setString(1, "张三"); stmt.setString(2, "zhangsan@example.com"); stmt.executeUpdate(); ResultSet rs = stmt.getGeneratedKeys(); if (rs.next()) { int id = rs.getInt(1); // 获取自增ID System.out.println("Generated ID: " + id); } } ``` - **Python (MySQL Connector)** 使用`lastrowid`属性: ```python import mysql.connector db = mysql.connector.connect(host="localhost", user="root", password="pass", database="test") cursor = db.cursor() cursor.execute("INSERT INTO users (name, email) VALUES (%s, %s)", ("张三", "zhangsan@example.com")) db.commit() id = cursor.lastrowid # 直接获取自增ID print(f"Generated ID: {id}") cursor.close() ``` - **PHP (PDO)** 使用`lastInsertId()`方法: ```php $pdo = new PDO("mysql:host=localhost;dbname=test", "root", "pass"); $stmt = $pdo->prepare("INSERT INTO users (name, email) VALUES (?, ?)"); $stmt->execute(["张三", "zhangsan@example.com"]); $id = $pdo->lastInsertId(); // 获取自增ID echo "Generated ID: " . $id; ``` #### 4. **在ORM框架中实现(如MyBatis)** 如果使用MyBatis等ORM工具,可以通过配置直接映射自增ID到实体对象[^2]: - **MyBatis配置**:在Mapper XML文件中,设置`useGeneratedKeys="true"`和`keyProperty`属性。 ```xml <insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="id"> INSERT INTO users (name, email) VALUES (#{name}, #{email}) </insert> ``` - **Java代码**:插入后,ID自动填充到实体对象的`id`属性。 ```java User user = new User(); user.setName("张三"); user.setEmail("zhangsan@example.com"); userMapper.insertUser(user); // 插入数据 int id = user.getId(); // 直接获取自增ID System.out.println("Generated ID: " + id); ``` 原理是MyBatis底层调用`LAST_INSERT_ID()`绑定到对象[^2]。 #### 5. **常见问题与优化** - **线程安全**:`LAST_INSERT_ID()`是连接级别的,确保每个线程使用独立连接即可避免发问题[^1]。 - **性能**:获取ID的操作是轻量级的,不影响插入性能。 - **错误处理**:如果插入失败(如主键冲突),`LAST_INSERT_ID()`可能返回0或上次成功值,需结合错误检查。 - **批量插入**:对于多记录插入,建议循环获取或使用框架支持(如MyBatis的`@Options`注解)。 通过以上方法,您可以高效、可靠地获取MySQL插入后的自增ID。实践时,优先使用编程语言或ORM的内置支持,以减少手动SQL调用[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值