树结构转规则

文章描述了一种通过前端插件生成二叉树结构JSON来表示复杂指标规则的方法。在Java中,这些JSON串被转换为对象模型,然后通过中序遍历转换为可执行的查询规则。解析过程涉及递归遍历树结构,构建SQL查询条件。
摘要由CSDN通过智能技术生成

需求描述

在开发过程中,会遇到通过界面添加指标,然后指标嵌套添加 or 或者 and,比较符 >= <= ==

!= 等,使用前端插件,直接生成二叉树结构的json串,保存起来,然后通过该json串,计算是否有对应的指标达到规则,然后进行报警预警等。

实现

1、生成的json串

例如:

{
    "relation": "and",
    "firstRule": {
        "relation": "and",
        "firstRule": {
            "value": "10",
            "operator": ">=",
            "ruleName": "A1"
        },
        "secondRule": {
            "value": "20",
            "operator": "==",
            "ruleName": "B1"
        }
    },
    "secondRule": {
        "relation": "and",
        "firstRule": {
            "relation": "and",
            "firstRule": {
                "value": "10",
                "operator": ">=",
                "ruleName": "A21"
            },
            "secondRule": {
                "value": "20",
                "operator": "==",
                "ruleName": "A22"
            }
        },
        "secondRule": {
            "relation": "and",
            "firstRule": {
                "value": "10",
                "operator": ">=",
                "ruleName": "B21"
            },
            "secondRule": {
                "value": "20",
                "operator": "==",
                "ruleName": "B22"
            }
        }
    }
}

2、在java中创建对象,将json串转为java对象

Java对象:

@Data
public class CombinationRule {

    private CombinationRule firstRule;

    private String relation;

    private CombinationRule secondRule;

    private String ruleName;

    private String operator;

    private Double value;
}

将json串转为对象

//定义一个typeReference 全局实例对象
private final TypeReference<CombinationRule> typeReference = new TypeReference<CombinationRule>() {
    };
ObjectMapper objectMapper = new ObjectMapper();
//读取json,将json转为之前定义的对象,发现就是一颗二叉树,读取的对象为root节点
root = objectMapper.readValue(moduleAlarmManagement.getAlarmRule(), this.typeReference);

3、解析二叉树,采用中序遍历,左子树开始遍历时添加左括号,右子树遍历结束时,添加右括弧,根节点不添加,叶子节点自行组织结构

例如上述json转为规则后的结果:

((yy>=10.0)and(ty>=20.0))and(((scty>=10.0)or(jkyl=20.0))and((jkhy>=10.0)and(jkwd=20.0)))

叶子节点也需要添加括弧,在遍历到叶子节点时,直接拼接就可以

解析代码:

//参数传入了root节点,为了获取到解析后的规则,传入一个StringBuilder ,传入节点深度,根节点为1,递归遍历
private void preNode(CombinationRule combinationRule, StringBuilder rule, StringBuilder ruleNames, Integer deep){
        if(Objects.isNull(combinationRule)){
            return;
        }
        //叶子节点
        else if(Objects.isNull(combinationRule.getFirstRule()) && Objects.isNull(combinationRule.getSecondRule())){
            String operation;
            if(Objects.equals(combinationRule.getOperator(), "==")){
                operation = "=";
            }else {
                operation = combinationRule.getOperator();
            }
            rule.append("(").append(PingYinUtil.getPinYinHeadChar(combinationRule.getRuleName()))
                    .append(operation).append(combinationRule.getValue()).append(")");
            ruleNames.append(combinationRule.getRuleName()).append(",");
        }else {
            if(deep > 1){
                rule.append("(");
            }
            if(Objects.nonNull(combinationRule.getFirstRule())){
                CombinationRule first = combinationRule.getFirstRule();
                preNode(first, rule, ruleNames, deep+1);
            }
            if(Objects.nonNull(combinationRule.getRelation())){
                rule.append(combinationRule.getRelation());
            }
            if(Objects.nonNull(combinationRule.getSecondRule())){
                CombinationRule second = combinationRule.getSecondRule();
                preNode(second, rule, ruleNames, deep+1);
            }
            if(deep > 1){
                rule.append(")");
            }
        }

4、最终实现了json转为数结构,然后树结构转为可以直接进行sql查询的规则

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿小木的愤怒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值