查找insert后的主键id。

本文介绍了在Mysql和Sql Server中如何获取最新插入记录的ID。在Mysql中,通过LAST_INSERT_ID()函数可以获取到当前连接下最新一次insert或update操作生成的第一个record的ID;而在Sql Server中,则可以通过@@IDENTITY获取类似的信息。

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

Mysql中:在连接关闭前:select LAST_INSERT_ID; LAST_INSERT_ID是基于Connection的,只要每个线程都使用独立的Connection对象,LAST_INSERT_ID函数将返回该Connection对AUTO_INCREMENT列最新的insert or update操作生成的第一个record的ID。这个值不能被其它客户端(Connection)影响,保证了你能够找回自己的 ID 而不用担心其它客户端的活动,而且不需要加锁

 Sql Server中:有类似的@@IDENTITY

select @@IDENTITY;

### 如何在 SQL 中实现 `INSERT` 操作时自动生成唯一主键 ID #### 使用数据库内置功能生成主键 许多关系型数据库提供了内置的功能用于生成唯一的主键字段。例如,在 MySQLSQL Server 中可以使用 `AUTO_INCREMENT` 或者 `IDENTITY` 属性来定义列,使其能够自动增加并保持唯一性。 对于 MySQL 数据库而言,可以通过设置某一列为 `PRIMARY KEY AUTO_INCREMENT` 来实现这一目标[^1]: ```sql CREATE TABLE example_table ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255) NOT NULL ); ``` 当向上述表格插入数据时无需指定 `id` 值,数据库会自动为其分配一个递增的整数值作为主键。 #### 利用 MyBatis 插件机制实现主键生成逻辑 如果项目中采用了 MyBatis 作为持久层框架,则还可以借助插件的方式来自定义主键生成策略。具体来说就是创建一个拦截器类继承 `org.apache.ibatis.plugin.Interceptor` 接口,并重写其中的方法完成对原始对象的操作前后的处理工作[^2]。 下面是一个简单的例子展示了如何通过编写自定义拦截器来为新增记录动态填充 UUID 类型字符串形式的主键值: ```java @Intercepts(value={ @Signature(type = Executor.class, method="update", args={MappedStatement.class, Object.class}) }) public class AutoIdInterceptor implements Interceptor { private static final Logger logger = LoggerFactory.getLogger(AutoIdInterceptor.class); public Object intercept(Invocation invocation) throws Throwable { MappedStatement mappedStmt = (MappedStatement)invocation.getArgs()[0]; String sqlCommandType = mappedStmt.getSqlCommandType().name(); if ("INSERT".equalsIgnoreCase(sqlCommandType)){ Object parameterObject = invocation.getArgs()[1]; MetaObject metaParamObj = SystemMetaObject.forObject(parameterObject); Field[] fields = parameterObject.getClass().getDeclaredFields(); boolean hasPrimaryKeyField=false; for(Field f :fields){ Column column=f.getDeclaredAnnotation(Column.class); Id id=f.getDeclaredAnnotation(Id.class); if(id!=null && !metaParamObj.hasGetter(f.getName())){ String generatedValue=UUID.randomUUID().toString(); metaParamObj.setValue(f.getName(),generatedValue ); break; } } } return invocation.proceed(); } } ``` 此代码片段中的核心部分在于遍历参数实体的所有属性查找标记有 JPA 注解 `@Id` 的成员变量;一旦发现符合条件的目标字段尚未被赋初值则随机生成一段独一无二的文字串赋予之。 #### 获取刚插入行所产生的主键值 除了让 DBMS 自动计算外键之外有时我们也希望能够在应用程序层面捕获到刚刚成功提交的新纪录对应的主键编号以便进一步操作关联子项等内容。此时可利用 JDBC API 提供的相关方法达成目的[^3]: ```java PreparedStatement pstmt = conn.prepareStatement( "INSERT INTO orders(order_date,customer_id,status)" + "VALUES(CURDATE(),?,?)", Statement.RETURN_GENERATED_KEYS ); pstmt.setInt(1, customerId); pstmt.setString(2,"PENDING"); int affectedRows=pstmt.executeUpdate(); if(affectedRows==0 ){ throw new SQLException("Creating user failed,no rows affected."); } ResultSet rs=pstmt.getGeneratedKeys(); long orderId=-1; if(rs.next()){ orderId=rs.getLong(1); }else{ throw new SQLException("Cannot obtain auto-generated key"); } System.out.println("New Order Created With ID:"+orderId); ``` 上面这段程序演示了怎样调用 PreparedStatement 对象上的 getGeneratedKeys() 函数检索最近一次执行 DML 指令之后产生的新条目所携带的关键字信息。 #### 定义非连续字符类型的主键约束条件 最后值得注意的一点是在设计模式允许的情况下也可以考虑采用固定长度或者变长但是具备一定规律性的文本序列充当主键角色而不是单纯依赖于数字累加方式构建索引结构。比如下述范例就规定了一个名为 `id` 的字段接受最多一百个字母组成的任意组合并且附加说明该栏位需满足唯一性校验标准[^4]: ```sql CREATE TABLE users ( `id` varchar(100) COLLATE utf8_estonian_ci NOT NULL COMMENT '唯一不重复', username VARCHAR(50), password_hash CHAR(60), -- Assuming bcrypt hash length is fixed at 60 chars. email_address TEXT UNIQUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, CONSTRAINT pk_user PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ; ``` 这样做的好处是可以有效避免因频繁更新而引发的数据迁移成本同时也便于跨平台移植以及与其他系统的集成对接等工作场景下的应用需求匹配问题解决思路探讨.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值