检查表数据是否循环依赖


前言

`需求如下:
有一张依赖表,记录了数据之间的依赖关系。
但是数据在insert这张表之前,需要检查,将要插入表中的依赖数据,是否会引起循环依赖。


一、什么是循环依赖

在这里插入图片描述
如图所示:
1 指向 2
2 指向 3
3 指向 1
形成了有向闭环,此时就循环了
如果这个数据保存在数据库中,需要根据1找到所有依赖的数据(会造成死循环)。

二、循环检查

1:先造数据

数据库中的数据
在这里插入图片描述

对应生成的图
在这里插入图片描述

2:循环检查实现

    

    @PostMapping(value = "check/cyclic")
    public BaseResponse checkDependenceCyclic(@RequestBody DependenceSaveRequest request) throws CheckException {

        checkCyclic(request.getSourceId(), Collections.singletonList(request.getDependenceId()));

        return new BaseResponse(Msg.SUCCESS);
    }

    /**
     * 递归检查,是否存在循环依赖
     */
    private void checkCyclic(Long sourceId, List<Long> dependenceIds) throws CheckException {

        List<Long> dependenceIdsBySourceIds = getDependenceIdsBySourceIds(dependenceIds);
        if (CollectionUtils.isEmpty(dependenceIdsBySourceIds)) {
            return;
        }

        if (dependenceIdsBySourceIds.contains(sourceId)) {
            throw new CheckException(Msg.ERROR, "数据循环依赖");
        }

        checkCyclic(sourceId, dependenceIdsBySourceIds);

    }


    private List<Long> getDependenceIdsBySourceIds(List<Long> sourceIds) {

        if (CollectionUtils.isEmpty(sourceIds)) {
            return Collections.emptyList();
        }

        return dependenceService.list(new LambdaQueryWrapper<Dependence>()
                .eq(Dependence::getDelFlag, 0)
                .in(Dependence::getSourceId, sourceIds))
                .stream()
                .map(Dependence::getDependenceId)
                .distinct()
                .collect(Collectors.toList());
    }

//单条新增数据 请求对象
@Data
public class DependenceSaveRequest extends BaseQuery {

    /**
     * 原数据id
     **/
    private Long sourceId;

    /**
     * 依赖id
     **/
    private Long dependenceId;

}

//数据库对象
@Data
public class Dependence {
    /**
     * 主键id
     **/
    private Long id;

    /**
     * 原数据id
     **/
    private Long sourceId;

    /**
     * 依赖id
     **/
    private Long dependenceId;

    /**
     * 是否删除:0-否,1-是
     **/
    @TableLogic
    @TableField(fill = FieldFill.INSERT)
    private Integer delFlag;

}


3:验证结果

插入: 9 指向 8
在这里插入图片描述

插入: 6 指向 3
在这里插入图片描述

插入: 2 指向 6
在这里插入图片描述

插入: 9 指向 10
在这里插入图片描述

总结:

这里只实现了:单条数据 插入前的检查。

还有批量数据 插入前的检查(需要返回出哪条数据导致的循环依赖)。
检查依赖表中是否已存在循环依赖的数据(需要指出造成循环依赖的数据有哪些)。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值