You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

数据库重复值处理:存在时添加递增计数器的实现问题

解决方案

问题根源

你当前的代码只统计完全匹配原标题的记录数量,导致第一次生成「bar1」后,后续再尝试添加「bar」时,findByTitle("bar")返回的结果数还是1,所以会重复生成「bar1」,无法递增到「bar2」「bar3」。

修复思路

需要统计所有以原标题开头的记录(包括原标题本身和带数字后缀的),提取其中最大的计数器值,再生成新的递增标题:

  1. 查询所有标题以原标题开头的记录
  2. 解析这些标题的后缀数字,找出最大的计数器
  3. 根据最大计数器生成新标题:原标题不存在则直接用;存在则用「原标题 + 最大计数器+1」

代码实现

假设你的实体类是Quote,先在Repository中添加查询方法:

// Spring Data JPA 仓库接口
public interface NewQuoteRepository extends JpaRepository<Quote, Long> {
    List<Quote> findByTitleStartingWith(String prefix);
}

然后修改业务逻辑代码:

String originalTitle = data.getTitle();
List<Quote> existingQuotes = newQuoteRepository.findByTitleStartingWith(originalTitle);

int maxCounter = 0;
boolean originalTitleExists = false;

for (Quote quote : existingQuotes) {
    String title = quote.getTitle();
    if (title.equals(originalTitle)) {
        originalTitleExists = true;
        continue;
    }
    // 提取后缀部分并尝试转为数字
    String suffixPart = title.substring(originalTitle.length()).trim();
    try {
        int counter = Integer.parseInt(suffixPart);
        if (counter > maxCounter) {
            maxCounter = counter;
        }
    } catch (NumberFormatException e) {
        // 后缀不是有效数字,跳过该记录
        continue;
    }
}

// 生成最终标题
if (originalTitleExists) {
    data.setTitle(originalTitle + " " + (maxCounter + 1));
}
// 如果原标题不存在,直接保留原标题即可

并发场景注意事项

如果有多个请求同时添加同标题的记录,可能会出现重复生成相同后缀的情况,你可以通过以下方式避免:

  • 给title字段添加唯一约束,当插入重复标题时捕获SQL异常,重新查询计数器后再次尝试插入
  • 使用悲观锁:在查询时锁定相关记录,比如修改Repository方法为:
    @Lock(LockModeType.PESSIMISTIC_WRITE)
    List<Quote> findByTitleStartingWith(String prefix);
    
    确保同一时间只有一个线程能处理同标题的生成逻辑

内容的提问来源于stack exchange,提问作者xRay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 08:55:17