springboot+mybatisPlus 开发 新增数据是进行是否重复校验
我们进行CRUD是经常需要判断新增数据是否重复,以下是校验工具类:
package com.minex.web.assets.util; import cn.hutool.core.collection.CollectionUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import com.baomidou.mybatisplus.extension.service.IService; import com.minex.common.exception.ExceptionFactory; import com.minex.web.common.util.SecurityUtils; import com.minex.web.tenant.service.TenantService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.util.Collection; import java.util.HashSet; import java.util.Map; import java.util.Set; /** * 资产名称重复校验工具类 * * @author gch * @since 2025-05-06 */ @Component @Slf4j @RequiredArgsConstructor public class AssetNameDuplicateChecker { private final TenantService tenantService; /** * 检查Excel中名称是否重复 * * @param name 名称 * @param excelNames Excel中的名称集合 * @param rowIndex 当前行号 * @return 错误信息,如果为null则表示没有重复 */ public String checkExcelDuplicate(String name, Set<String> excelNames, int rowIndex) { if (excelNames.contains(name)) { return String.format("第%d行名称[%s]在Excel中重复", rowIndex, name); } excelNames.add(name); return null; } /** * 检查数据库中名称是否重复 * * @param name 名称 * @param dbNames 数据库中的名称集合 * @param rowIndex 当前行号 * @return 错误信息,如果为null则表示没有重复 */ public String checkDbDuplicate(String name, Set<String> dbNames, int rowIndex) { if (dbNames.contains(name)) { return String.format("第%d行名称[%s]在数据库中已存在", rowIndex, name); } return null; } /** * 检查保存或更新时名称是否重复 * * @param service 服务类 * @param name 名称 * @param id 主键ID(更新时使用) * @param assetType 资产类型(用于错误提示) * @param nameGetter 名称字段的getter方法引用 * @param firmCodeGetter 公司编码字段的getter方法引用 * @param idGetter ID字段的getter方法引用 * @param <T> 实体类型 */ public <T> void checkSaveOrUpdateDuplicate(IService<T> service, String name, Long id, String assetType, SFunction<T, String> nameGetter, SFunction<T, String> firmCodeGetter, SFunction<T, Long> idGetter, String firmCode) { LambdaQueryWrapper<T> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(nameGetter, name) .eq(firmCodeGetter, firmCode); if (id != null) { wrapper.ne(idGetter, id); } if (service.count(wrapper) > 0) { throw ExceptionFactory.bizException(assetType + "名称已存在"); } } /** * 校验保存或更新时是否存在重复数据(支持多个字段的“或”逻辑校验) * * @param service 服务接口 * @param id ID(用于排除当前记录) * @param assetType 资产类型(用于异常提示) * @param firmCodeGetter 租户代码字段的 getter * @param idGetter ID 字段的 getter * @param fieldMap 字段 Map(格式:字段 getter -> 字段值),支持“或”逻辑校验 */ public <T> void checkSaveOrUpdateDuplicate( IService<T> service, Long id, String assetType, SFunction<T, String> firmCodeGetter, SFunction<T, Long> idGetter, Map<SFunction<T, Object>, Object> fieldMap, String firmCode ) { // 构建查询条件 LambdaQueryWrapper<T> wrapper = new LambdaQueryWrapper<>(); // 必须满足的租户条件 wrapper.eq(firmCodeGetter, firmCode); // 添加额外字段的 OR 条件(包裹在同一个括号内) if (fieldMap != null && !fieldMap.isEmpty()) { wrapper.and(wrapper1 -> { for (Map.Entry<SFunction<T, Object>, Object> entry : fieldMap.entrySet()) { wrapper1.or().eq(entry.getKey(), entry.getValue()); } }); } // 排除当前记录(更新场景) if (id != null) { wrapper.ne(idGetter, id); } // 校验是否存在重复数据 if (service.count(wrapper) > 0) { throw ExceptionFactory.bizException(assetType + "信息已存在"); } } /** * 初始化数据库中的名称集合 * * @param service 服务类 * @param nameGetter 名称字段的getter方法引用 * @param firmCodeGetter 公司编码字段的getter方法引用 * @param <T> 实体类型 * @return 数据库中的名称集合 */ public <T> Set<String> initDbNames(IService<T> service, SFunction<T, String> nameGetter, SFunction<T, String> firmCodeGetter) { Set<String> dbNames = new HashSet<>(); String firmCode = tenantService.getUserSelectedTenantInfo(SecurityUtils.getLoginUser()).getCode(); Collection<T> list = service.lambdaQuery() .eq(firmCodeGetter, firmCode) .list(); if (CollectionUtil.isNotEmpty(list)) { list.forEach(item -> { try { String name = nameGetter.apply(item); if (name != null) { dbNames.add(name); } } catch (Exception e) { // 忽略异常 log.error("初始化数据库中的名称集合时发生异常", e); } }); } return dbNames; } }
调用 checkSaveOrUpdateDuplicate 方法进行多个字段校验
使用示例:
@Override public void validateAndSave(FaultIndicator info) { Map<SFunction<FaultIndicator, Object>, Object> fieldMap = new HashMap<>(); fieldMap.put(FaultIndicator::getAssetsName, info.getAssetsName()); if (StrUtil.isNotEmpty(info.getCode())) { fieldMap.put(FaultIndicator::getCode, info.getCode()); } assetNameDuplicateChecker.checkSaveOrUpdateDuplicate(this, info.getId(), "故障指示器", FaultIndicator::getFirmCode, FaultIndicator::getId, fieldMap, tenantService.getUserSelectedTenantInfo(SecurityUtils.getLoginUser()).getCode()); this.saveOrUpdate(info); }
⎛⎝官萧何⎠⎞一只快乐的爪哇程序猿;邮箱:1570608034@qq.com

浙公网安备 33010602011771号