这篇文章给大家介绍怎么在Mybatis中利用useGeneratedKeys获取自增主键,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
批量插入用户收藏
for (=tries 0;, tries & lt;, MAX_RETRY;,尝试+ +),{ ,final int result =, collectionMapper.insertCollections(集合); ,if (result ==, collections.size ()), { 打破才能; ,} } if (tries ==, MAX_RETRY), { ,throw new  RuntimeSqlException (“Insert collections error"); }//,依赖数据库生成的collectionid return 收藏;
collectionMapper。insertCollections方法
& lt; insert id=癷nsertCollections", parameterType=發ist", useGeneratedKeys=皌rue" keyProperty才能=癱ollectionId"祝辞 ,INSERT INTO 收集( userid,大敌;项目 ,) ,值 ,& lt; foreach 收集=發ist",项=癱ollection",分离器=?“在 ,,(# {collection.userId},, # {collection.item}) ,& lt;/foreach> ,提醒DUPLICATE KEY 更新 status =, 0 & lt;/insert>
不知道大家能不能发现其中的问题
<强>分析强>
问题有两个
<强>返回值结果的判断错误强>
使用<代码>复制关键代码>批量更新返回影响的行数是和插入的数不一样的。犯这种错主要在于想当然,不看文档
看下官网文档
写的很清楚
public synchronized ResultSet getGeneratedKeys (), throws SQLException { if 才能;(! this.retrieveGeneratedKeys), { ,,throw SQLError.createSQLException (Messages.getString (“Statement.GeneratedKeysNotRequested"),“S1009",, this.getExceptionInterceptor ()); },才能else if (this.batchedGeneratedKeys ==, null), { ,,//,批量走这边的逻辑 ,,return this.lastQueryIsOnDupKeyUpdate  ?, this.getGeneratedKeysInternal (1),:, this.getGeneratedKeysInternal (); ,,},{else ,,领域[],fields =, new 领域[]{new 字段(““,,“GENERATED_KEY",, 5日,17)}; ,,领域[0].setConnection (this.connection); ,,return ResultSetImpl.getInstance (this.currentCatalog、,字段,new RowDataStatic (this.batchedGeneratedKeys), this.connection,,这个,,假); ,,} 以前,}>
看下调用的方法this.getGeneratedKeysInternal ()
protected ResultSet getGeneratedKeysInternal (), throws SQLException { ,,,//,获取影响的行数 ,,,int numKeys =, this.getUpdateCount (); ,,,return this.getGeneratedKeysInternal (numKeys); 以前,,}>这里有个重要知识点了,首先获取本次批量插入的影响行数,然后再执行具体的获取id操作。
getGeneratedKeysInternal方法
protected synchronized ResultSet getGeneratedKeysInternal (int numKeys), throws SQLException { ,,,现场[],fields =, new 领域[]{new 字段(““,,“GENERATED_KEY",, 5日,17)}; ,,,字段[0].setConnection (this.connection); ,,,字段[0].setUseOldNameMetadata(真正的); ,,,ArrayList rowSet =, new ArrayList (); ,,,long beginAt =, this.getLastInsertID (); ,,,//,按照受影响的范围+递增步长 ,,,(int 小姐:=,0;,小姐:& lt;, numKeys;, + + i), { ,,,,,,if (beginAt 祝辞,0 l), { ,,,,,,,,,,,//,值塞进去 ,,,,,,,,,,,行[0],=,StringUtils.getBytes (Long.toString (beginAt)); ,,,,,,,,,} ,,,,,beginAt +=,(长)this.connection.getAutoIncrementIncrement (); ,,,} }迭代影响的行数,然后依次获取id。
所以批量插入是正确可以返回的。
但是批量insertOrUpdate就有问题了,批量insertOrUpdate的影响行数不是插入的数据行数,可能是0,1,2这样就导致了自增id有问题了。
比如插入3条数据,2条会更新1条会插入,这时候updateCount就是5,generateid就会5个了,mybatis然后取前3个塞到数据里,显然是错的。
以上是原理分析,如果想了解更详细的实验结果,可以看下实验
<强>总结强>
批量插入
& lt; insert id=癷nsertAuthor", useGeneratedKeys=皌rue" keyProperty才能=癷d"祝辞 ,insert into  Author (用户名,密码,电子邮件,,生物),值 ,& lt; foreach 项=癷tem",收集=發ist",分离器=?“在 null null null怎么在Mybatis中利用useGeneratedKeys获取自增主键