重新 mybatis plus 的 saveOrUpdate 方法,实现根据自定义字段插入或者修改
本文介绍了在MyBatis中实现基于name和content字段的批量保存或更新操作。通过重写saveOrUpdateBatch方法,先查询是否存在相同name和content的记录,存在则更新,不存在则插入。文章指出该方法本质是先查后改,高并发场景需谨慎使用。同时提到MyBatis版本差异导致entityClass访问方式不同,并讨论了另一种解决方案:使用MySQL的ON DUPLICATE K
我希望数据能根据name和content作为唯一索引,如果 数据库中的数据, name和content相同,就更新记录,如果不同,就插入记录。
废话不多说,直接上代码。
@Override
@Transactional(rollbackFor = Exception.class)
public boolean saveOrUpdateBatch(Collection<FulfillmentItem> entityList) {
return SqlHelper.saveOrUpdateBatch(
this.getEntityClass(),
this.currentMapperClass(),
super.log,
entityList,
DEFAULT_BATCH_SIZE,
(sqlSession, entity) -> {
Wrapper<FulfillmentItem> queryWrapper = Wrappers.<FulfillmentItem>lambdaQuery()
.eq(FulfillmentItem::getName, entity.getName())
.eq(FulfillmentItem::getContent, entity.getContent());
Map<String, Object> map = new HashMap<>();
map.put(Constants.WRAPPER, queryWrapper);
return CollectionUtils.isEmpty(sqlSession.selectList(this.getSqlStatement(SqlMethod.SELECT_LIST), map));
},
(sqlSession, entity) -> {
Wrapper<FulfillmentItem> lambdaUpdateWrapper = Wrappers.lambdaUpdate(FulfillmentItem.class)
.eq(FulfillmentItem::getName, entity.getName())
.eq(FulfillmentItem::getContent, entity.getContent());
Map<String, Object> map = new HashMap<>();
map.put(Constants.ENTITY, entity);
map.put(Constants.WRAPPER, lambdaUpdateWrapper);
sqlSession.update(getSqlStatement(SqlMethod.UPDATE), map);
});
}
注意点:
saveOrUpdateBatch 本质是先查后改,高并发业务请谨慎取用。
mybatis 旧版本略有不同,没有 this.getEntityClass() 方法。
原因是旧版本中,entityClass 属性是 protectd 类型,可以直接用,
springboot 3 后的版本,改成了 private 类型。
源码:
private Class<T> entityClass; // 旧版本是 protected类型
public Class<T> getEntityClass() {
if (this.entityClass == null) {
this.entityClass = GenericTypeUtils.resolveTypeArguments(this.getMapperClass(), BaseMapper.class)[0];
}
当然,这里也可以根据 name 和 content 作为唯一索引,用 MySQL 的 ON DUPLICATE KEY UPDATE 来做判断。
但是由于我content是text类型,无法用作索引列。
如果高并发下,非要用 DUPLICATE KEY UPDATE,可以加一列:content_hash.
通过存储 content 内容的哈希值,来做唯一索引,也能解决这个问题。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)