如何用iBatis2.3.4获取DB2中插入记录的自增主键ID?
解决iBatis 2.3.4获取DB2自增主键的问题
核心问题原因
在AQT中能拿到IDENTITY_VAL_LOCAL()的结果,是因为插入和查询在同一个数据库会话里;而iBatis配置失效,大概率是插入和selectKey不在同一个会话/事务,或者配置细节没到位导致的。
可行解决方法
方法1:修正selectKey的配置(确保同会话执行)
把selectKey嵌套在insert标签内部,并指定order="AFTER",确保插入完成后立即执行主键查询,且两者复用同一个数据库连接。
完整配置示例:
<insert id="insertYourEntity" parameterClass="com.yourcompany.YourEntity"> <!-- 你的插入语句 --> INSERT INTO YOUR_TABLE (COLUMN1, COLUMN2) VALUES (#column1#, #column2#) <!-- 嵌套selectKey,指定order=AFTER --> <selectKey resultClass="int" keyProperty="id" order="AFTER"> SELECT IDENTITY_VAL_LOCAL() AS ID FROM SYSIBM.SYSDUMMY1 </selectKey> </insert>
同时要注意:
- 确保调用插入方法时处于事务中(比如通过Spring事务管理,或者手动开启事务后再提交),避免自动提交导致连接提前释放。
- 实体类
YourEntity的id字段必须有对应的setId()方法,iBatis需要通过setter把主键值回写。
方法2:使用JDBC的getGeneratedKeys特性
如果你的DB2 JDBC驱动版本(建议4.0以上)支持getGeneratedKeys,可以直接在insert标签中开启该特性,无需写selectKey:
<insert id="insertYourEntity" parameterClass="com.yourcompany.YourEntity" useGeneratedKeys="true" keyProperty="id"> INSERT INTO YOUR_TABLE (COLUMN1, COLUMN2) VALUES (#column1#, #column2#) </insert>
这种方式更简洁,依赖JDBC原生能力,避免手动写查询语句的问题。
方法3:用DB2原子复合语句强制同会话
如果前两种方法都无效,可以把插入和主键查询合并成一个DB2原子语句,确保在同一个执行块里完成:
<insert id="insertYourEntity" parameterClass="com.yourcompany.YourEntity"> BEGIN ATOMIC INSERT INTO YOUR_TABLE (COLUMN1, COLUMN2) VALUES (#column1#, #column2#); SET #id# = IDENTITY_VAL_LOCAL(); END ATOMIC </insert>
这里通过BEGIN ATOMIC把两个操作绑定成一个原子块,iBatis会把id参数作为输出参数回写,需要确保实体类的id字段是可写入的。
额外排查点
- 检查DB2 JDBC驱动版本,过于老旧的驱动可能对IDENTITY函数支持有问题,建议升级到适配你DB2版本的最新驱动。
- 确认表的主键确实是
IDENTITY类型(比如ID INTEGER GENERATED ALWAYS AS IDENTITY),而非其他自增方式。
内容的提问来源于stack exchange,提问作者Rajesh Swain
相关产品推荐
相关产品推荐

