标签:
使用JDBC,或者通过hibernate,mybatis等orm框架,执行insert语句,要怎么得到新生成记录的主键呢?
大体有两种方式,1. 在执行insert前,生成主键,那么主键和普通的列就没有区别,2. 执行insert后,通过某种方式得到新生成的主键;严格的说,还有第三种方式,没有主键;
对于第一种方式,常见的是使用oracle的sequence,在执行insert前,通过select <seq>.nextval from dual 得到主键;或者使用UUID的方式,或者其他可以保证唯一主键的方式,生成主键,作为普通的一列数据插入数据库;
在hibernate中,可以使用如下的方式配置一个genrator:
<id name="propertyName" type="typename" column="column_name" unsaved-value="null|any|none|undefined|id_value" access="field|property|ClassName"> node="element-name|@attribute-name|element/@attribute|." <generator class="generatorClass"/> </id>
或者使用sequence
<id name="id" type="long" column="person_id"> <generator class="sequence"> <param name="sequence">person_id_sequence</param> </generator> </id>
在mybatis中,可以使用 selectKey设置
<selectKey keyProperty="id" resultType="int" order="BEFORE" statementType="PREPARED">
第二种方式,一般用于mysql auto increment key,或者 (oracle) insert into xxx (id, ...) values (<seq>.nextval, ...);
如果使用这种方式,大体的策略就是insert完以后,通过select获得主键,不同的数据库有不同的方式
oracle:
insert into mytable (...) values (...)returning id into v_id;
这个只能用于pl/sql;
或者使用
select <seq>.currval from dual;
这个方式我自己没有用过,网上搜索了一下,在同一个session里面,使用同一个connection,可以保证currval就是刚刚使用的sequence。有机会实验一下,再回来更新;
mysql:
select last_insert_id()
sql server:
SELECT SCOPE_IDENTITY()
如果使用mybatis,同样可以通过selectKey得到主键,不过别忘了把order设置为after
<selectKey resultType="long" order="AFTER" keyProperty="returnedId"> SELECT LAST_INSERT_ID() as returnedId </selectKey>
如果使用mysql auto increment类似的自动主键生成策略,jdbc提供了如下的api,执行insert时,得到主键:
int autoIncKeyFromApi = -1; stmt.executeUpdate(insert, Statement.RETURN_GENERATED_KEYS); rs = stmt.getGeneratedKeys(); if (rs.next()) { autoIncKeyFromApi = rs.getInt(1); } else { // do what you have to do }
标签:
原文地址:http://my.oschina.net/u/922297/blog/483560