详解mysql插⼊数据后返回⾃增ID的七种⽅法
引⾔
mysql 和 oracle 插⼊的时候有⼀个很⼤的区别是:
oracle ⽀持序列做 id;
mysql 本⾝有⼀个列可以做⾃增长字段。
mysql 在插⼊⼀条数据后,如何能获得到这个⾃增 id 的值呢?
⼀:使⽤ last_insert_id()
SELECT LAST_INSERT_ID();
1. 每次 mysql 的 query 操作在 mysql 服务器上可以理解为⼀次“原⼦”操作, 写操作常常需要锁表,这⾥的锁表是 mysql 应⽤服务器锁表不是我们的应⽤程序锁表。
2. 因为 LAST_INSERT_ID 是基于 Connection 的,只要每个线程都使⽤独⽴的 Connection 对象,LAST_INSERT_ID 函数将返回该 Connection 对 AUTO_INCREMENT列最新的 insert or update* 作⽣成
的第⼀个 record 的ID。这个值不能被其它客户端(Connection)影响,保证了你能够回⾃⼰的 ID ⽽不⽤担⼼其它客户端的活动,⽽且不需要加锁。使⽤单INSERT 语句插⼊多条记录, LAST_INSERT_ID 返回⼀个列表。
3. LAST_INSERT_ID 是与 table ⽆关的,如果向表 a 插⼊数据后,再向表 b 插⼊数据,LAST_INSERT_ID 会改变。
⼆:使⽤ max(id)
如果不是频繁的插⼊我们也可以使⽤这种⽅法来获取返回的id值
select max(id) from user;
这个⽅法的缺点是不适合⾼并发。如果同时插⼊的时候返回的值可能不准确。
三:创建⼀个存储过程
在存储过程中调⽤先插⼊再获取最⼤值的操作。
DELIMITER $$
DROP PROCEDURE IF EXISTS `test` $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `test`(in name varchar(100),out oid int)
BEGIN
insert into user(loginname) values(name);
select max(id) from user into oid;
select oid;
END $$
DELIMITER ;
call test('gg',@id);
四:使⽤ @@identity
select @@IDENTITY
@@identity 是表⽰的是最近⼀次向具有 identity 属性(即⾃增列)的表插⼊数据时对应的⾃增列的值,是系统定义的全局变量。⼀般系统定义的全局变量都是以@@开头,⽤户⾃定义变量以@开头。⽐如有个表 A,它的⾃增列是 id,当向 A 表插⼊⼀⾏数据后,如果插⼊数据后⾃增列的值⾃动增加⾄ 101,则通过select @@identity得到的值就是 101。使⽤@@identity的前提是在进⾏ insert 操作后,执⾏ select @@identity 的时候连接没有关闭,否则得到的将是 NULL 值。
五:是使⽤ getGeneratedKeys()
Connection conn = ;
Serializable ret = null;
PreparedStatement state = .;
ResultSet rs=null;
try {
rs = GeneratedKeys();
if (rs.next()) {
ret = (Serializable) rs.getObject(1);
}
} catch (SQLException e) {
}
return ret;
总结:在 mysql 中做完插⼊之后获取 id 在⾼并发的时候是很容易出错的。另外 last_insert_id 虽然是基于 session 的但是不知道为什么没有测试成功。
六:selectkey:
其实在 ibtias 框架⾥使⽤ selectkey 这个节点,并设置 insert 返回值的类型为 integer,就可以返回这个 id 值。
SelectKey 在Mybatis中是为了解决 Insert 数据时不⽀持主键⾃动⽣成的问题,他可以很随意的设置⽣成
主键的⽅式。
不管 SelectKey 有多好,尽量不要遇到这种情况吧,毕竟很⿇烦。
SelectKey 需要注意 order 属性:
Mysql ⼀类⽀持⾃动增长类型的数据库中,order 需要设置为 after 才会取到正确的值。
Oracle 这样取序列的情况,需要设置为 before,否则会报错。
xml 的例⼦:
<insert id="insert" parameterType="map">
insert into table1 (name) values (#{name})
<selectKey resultType="java.lang.Integer" keyProperty="id">
SELECT LAST_INSERT_ID() AS id
</selectKey>
</insert>
上⾯ xml 的传⼊参数是 map,selectKey 会将结果放到⼊参数 map 中。⽤ POJO 的情况⼀样,但是有⼀点需要注意的
是,keyProperty 对应的字段在 POJO 中必须有相应的 setter ⽅法,setter 的参数类型还要⼀致,否则会报错。
注解的形式:
@Insert("insert into table2 (name) values(#{name})")
@SelectKey(statement="call identity()", keyProperty="nameId", before=false, resultType=int.class)
int insertTable2(Name name);
⽅法七:使⽤<insert 中的useGeneratedKeys 和 keyProperty 两个属性
drop table if exists user1.在Mybatis Mapper⽂件中添加属性 “useGeneratedKeys”和“keyProperty”,其中 keyProperty 是 Java 对象的属性名,⽽不是表格的字段名。
<insert id="insert" parameterType="Spares"
useGeneratedKeys="true" keyProperty="id">
insert into system(name) values(#{name})
</insert>
2.Mybatis 执⾏完插⼊语句后,⾃动将⾃增长值赋值给对象 systemBean 的属性id。因此,可通过 systemBean 对应的 getter ⽅法获取!
int count = systemService.insert(systemBean);
int id = Id(); //获取到的即为新插⼊记录的ID
【注意事项】
1.Mybatis Mapper ⽂件中,“useGeneratedKeys” 和 “keyProperty” 必须添加,⽽且 keyProperty ⼀定得和 java 对象的属性名称⼀直,⽽不是表格的字段名。
2. java Dao中的 Insert ⽅法,传递的参数必须为 java 对象,也就是 Bean,⽽不能是某个参数。
到此这篇关于详解mysql插⼊数据后返回⾃增ID的七种⽅法的⽂章就介绍到这了,更多相关mysql插⼊返回⾃增ID内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论