怎么在Mybatis中利用useGeneratedKeys获取自增主键

  介绍

这篇文章给大家介绍怎么在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获取自增主键