分析如下for循环的写法不同之处

方式1:

fjList.forEach(examQuestionattachment -> {                                               
    ExamQuestionAttachment examQuestionAttachment = new ExamQuestionAttachment();        
    examQuestionAttachment.setQuestionSmallId(examQuestionSmall.getId());                
    examQuestionAttachment.setType(examQuestionattachment.getAttachmenttype()); // 类型    
    examQuestionAttachment.setPath(copyUrl + examQuestionattachment.getPath()); // 地址    
    examQuestionAttachmentMapper.insertSelective(examQuestionAttachment);                
});                                                                                      

方式2:

    ExamQuestionAttachment examQuestionAttachment = new ExamQuestionAttachment();        
    examQuestionAttachment.setQuestionSmallId(examQuestionSmall.getId()); 
fjList.forEach(examQuestionattachment -> {
    examQuestionAttachment.setType(examQuestionattachment.getAttachmenttype()); // 类型    
    examQuestionAttachment.setPath(copyUrl + examQuestionattachment.getPath()); // 地址    
    examQuestionAttachmentMapper.insertSelective(examQuestionAttachment);                
});                                                                                      

某次任务中,采用的是方式2的循环方式,结果程序报错,提示是主键重复。记录分析过程如下:

  1. 理论分析,既然是主键重复,说明循环开始,要不然不可能会重复。
  2. 主键重复,说明第二次插入的对象的id和第一次的相同,也就是examQuestionAttachment这个对象在第一次插入数据后得到了一个id,并且在循环的时候,到了第二次插入的对象中。
  3. mybatis中涉及到数据插入返回主键的配置是:configuration下的use-generated-keys,当use-generated-keys=true时,数据插入后会得到一个id,并返回到插入的对象当中,所有我们来继续验证。
  4. use-generated-keys=true在方式2中会报错,so 设置use-generated-keys=false,然后重新启动项目,运行之前程序,数据插入正常。
  5. 方式1不用多说,在for循环中new新对象,不管id返回与否,数据插入都没有问题。

总结:use-generated-keys=true时要注意new对象的操作是否在for循环中,确保id不重复。

猜你喜欢

转载自blog.csdn.net/qq_32218457/article/details/80729060