JAVA动态表达式:Antlr4 表达式树解析

news2025/9/18 11:53:35

接上面

JAVA动态表达式:Antlr4 G4 模板 + 读取字符串表达式结构树-CSDN博客

 目前已经实现了常量及分组常规表达式的解析。

String formula = "'啦啦啦'=='1' and 1==1 and '2'=='3' and '1123' contains '1' and '23455' notcontains '5'";
String formula = "'啦啦啦'=='1' and (1==1 or 2==2) and '1123' contains '1' and '23455' notcontains '5'";
String formula = "'啦啦啦'=='1' and (1 contains 1 or 2 notcontains 2) ";
String formula = "(1==1 or 2==2) and '啦啦啦'=='1'";
String formula = "((1==1) or (2==2)) and '啦啦啦'=='1'";
String formula = "((1==1 and (2==2 or 3==3)) or (2==2 or 3==3)) and '啦啦啦'=='1'";

实现思路通过Antlr4把解析得到表达式树:

下面的RuleEntity rule对象,就是把上面的结构树给拿到了。

// 构建字符流
CodePointCharStream charStream = CharStreams.fromString(formula);
// 从字符流分析词法, 解析为token
ExprLexer lexer = new ExprLexer(charStream);
// 从token进行分析
ExprParser parser = new ExprParser(new CommonTokenStream(lexer));
// 使用监听器,遍历语法树,根据语法定义,prog为语法树的根节点
ParseTree progTree = parser.expression();

if (((ExprParser.ExpressionContext) progTree).exception != null) {
            throw new Exception("输入的表达式不符合解析规则");
}
// 遍历语法树节点
RuleEntity rule = traverseTree(progTree, name, new RuleEntity());

这样通过循环你就能得到这串表达式的每个值:((1==1 and (2==2 or 3==3)) or (2==2 or 3==3)) and '啦啦啦'=='1'

比如,第一个是( ,第二个是(,第三个是1,第四个是==......

这样你就需要通过逻辑去拼接成这样的对象:

{"id":"rule_2o0S3Ar37K","name":"","tierIndex":"1","conditionList":[{"id":"HK3e6pbRh8","type":"group","tierIndex":"2","conditionList":[{"id":"GmaIWw94NU","type":"group","tierIndex":"3","conditionList":[{"id":"gqx7N9E8p6","type":"single","leftOperatorExpression":{"id":"Constant_ZE0K2xEU82","type":"1","valueType":"double","value":"1","label":"数字"},"compareOperation":"1","rightOperatorExpression":{"id":"Constant_35054671Wu","type":"1","valueType":"double","value":"1","label":"数字"},"describe":""},{"id":"MOsI066Zys","type":"symbol","formulaRelation":"and"},{"id":"R364030W6T","type":"group","tierIndex":"4","conditionList":[{"id":"KtCN58q1Qj","type":"single","leftOperatorExpression":{"id":"Constant_3v9x4vQ716","type":"1","valueType":"double","value":"2","label":"数字"},"compareOperation":"1","rightOperatorExpression":{"id":"Constant_20I9PuvuLE","type":"1","valueType":"double","value":"2","label":"数字"},"describe":""},{"id":"1JViMLz2L0","type":"symbol","formulaRelation":"or"},{"id":"5PQD6ZU2a2","type":"single","leftOperatorExpression":{"id":"Constant_K6626YX2ya","type":"1","valueType":"double","value":"3","label":"数字"},"compareOperation":"1","rightOperatorExpression":{"id":"Constant_27885U5143","type":"1","valueType":"double","value":"3","label":"数字"},"describe":""}]}]},{"id":"D5dnzS9162","type":"symbol","formulaRelation":"or"},{"id":"F15k4S12AZ","type":"group","tierIndex":"3","conditionList":[{"id":"gJS0jy1Kl7","type":"single","leftOperatorExpression":{"id":"Constant_Z5v3vD9ky6","type":"1","valueType":"double","value":"2","label":"数字"},"compareOperation":"1","rightOperatorExpression":{"id":"Constant_W6ZlHv110E","type":"1","valueType":"double","value":"2","label":"数字"},"describe":""},{"id":"K967v6PJ8E","type":"symbol","formulaRelation":"or"},{"id":"99L0cJj55g","type":"single","leftOperatorExpression":{"id":"Constant_8VM6MJlQ08","type":"1","valueType":"double","value":"3","label":"数字"},"compareOperation":"1","rightOperatorExpression":{"id":"Constant_4bKLn5xQsA","type":"1","valueType":"double","value":"3","label":"数字"},"describe":""}]}]},{"id":"685x2JL36x","type":"symbol","formulaRelation":"and"},{"id":"tt104S829A","type":"single","leftOperatorExpression":{"id":"Constant_52nUmF4dmO","type":"1","valueType":"string","value":"啦啦啦","label":"字符串"},"compareOperation":"1","rightOperatorExpression":{"id":"Constant_08q1K2KO6s","type":"1","valueType":"string","value":"1","label":"字符串"},"describe":""}]}

 然后下面是用到的实现逻辑:

POM文件

<!--JSON-->
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.2.3</version>
            <classifier>jdk15</classifier>
        </dependency>
        <!--动态表达式-->
        <dependency>
            <groupId>org.antlr</groupId>
            <artifactId>antlr4</artifactId>
            <version>4.10.1</version>
        </dependency>
@Test
    public void Test00() throws Exception {
        //String formula="@prices == 1 and (@val >=1 or @name<=4) and 1==1 and '2'=='3' and '1123' contains '1' and '23455' notcontains '5'";//这个逻辑暂时没开发
        //String formula = "'啦啦啦'=='1' and 1==1 and '2'=='3' and '1123' contains '1' and '23455' notcontains '5'";
        //String formula = "'啦啦啦'=='1' and (1==1 or 2==2) and '1123' contains '1' and '23455' notcontains '5'";
        //String formula = "'啦啦啦'=='1' and (1 contains 1 or 2 notcontains 2) ";
        //String formula = "(1==1 or 2==2) and '啦啦啦'=='1'";
        //String formula = "((1==1) or (2==2)) and '啦啦啦'=='1'";
        String formula = "((1==1 and (2==2 or 3==3)) or (2==2 or 3==3)) and '啦啦啦'=='1'";
        String json = FormulaToJson.formulaToJson("", formula);
        System.out.println(json);

    }
package com.java.core.web.antlr4.util;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.java.core.web.antlr4.ExprLexer;
import com.java.core.web.antlr4.ExprParser;
import com.java.core.web.antlr4.param.AbnormalParameter;
import com.java.core.web.antlr4.param.DeletionParameter;
import com.java.core.web.antlr4.param.Parameter;
import com.java.core.web.antlr4.param.ParameterPojo;
import com.java.core.web.antlr4.pojo.*;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CodePointCharStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.TerminalNode;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

public class FormulaToJson {

    /**
     * 遍历语法树节点
     *
     * @param tree
     */
    public static RuleEntity traverseTree(ParseTree tree, String name, RuleEntity rule) {
        //自定义变量
        // public String type; //类型 1-属性 2-值 (由比较操作符决定)
        // public String group; //组 0-不用添加组 1-需要添加组 (有一个小括号)
        // public String bracket;//括号 判断是否是组 (小括号的数量记录)
        // public String isObject;//是否new object (条件对象 0-不创建 1-创建 由逻辑运算符决定 如 and/or)
        if (tree instanceof TerminalNode) {
            TerminalNode terminalNode = (TerminalNode) tree;
            //得到树节点
            String text = terminalNode.getText().replace("'", "");
            //获取条件组
            List<Condition> list = rule.getConditionList();
            //判断节点类型 (比较操作符/逻辑运算符号/小括号/中括号/@符)
            int res = CheckSymbolOptions.getNameOrValue(text);
            if (res == 1) { //比较操作符
                rule.setType("2");
                rule.setEndBracket("0");
                if (rule.getGroup() == null || rule.getGroup().equals("0")) {
                    if (list.size() > 0) {
                        Condition condition = list.get(list.size() - 1);
                        String symbolOptions = SymbolOptions.getNameOrValue(text);
                        condition.setCompareOperation(symbolOptions);//比较操作(操作符)
                    }
                } else {
                    //取当前分组的最后一条数据
                    Condition condition = getLastGroupCondition(list, rule);
                    ;
                    condition = condition.getConditionList().get(condition.getConditionList().size() - 1);

                    String symbolOptions = SymbolOptions.getNameOrValue(text);
                    condition.setCompareOperation(symbolOptions);//比较操作(操作符)
                }

            } else if (res == 2) { //逻辑运算符
                if (rule.getGroup() == null || rule.getGroup().equals("0")) {
                    //添加条件对象
                    Condition condition = addCondition(name, "symbol", text);
                    list.add(condition);
                    rule.setIsObject("1");//需要添加条件对象  0-不添加 1-添加
                    rule.setType("1");
                } else {
                    //获得当前组的对象
                    Condition cond = getLastGroupCondition(list, rule);
                    List<Condition> conditionList = cond.getConditionList();
                    //添加条件对象
                    Condition condition = addCondition(name, "symbol", text);
                    conditionList.add(condition);
                    rule.setIsObject("1");//需要添加条件对象  0-不添加 1-添加
                }
            } else if (res == 3) { //括号标识符
                if (text.equals("(")) {
                    if (rule.getId() == null) {
                        //设置rule属性
                        rule.setId(generateId("rule"));//id需要自动生成 rule_xxxxxxxxxx(10位数)
                        rule.setName(name);
                        rule.setSubscript("1");//记录索引
                        rule.setTierIndex("1");//层级索引 需要确定来源
                    }
                    rule.setType("1");
                    if (rule.getBracket() == null || rule.getBracket().equals("0")) {
                        rule.setBracket("1");
                    }
                    int va = Integer.valueOf(rule.getBracket()) + 1;
                    rule.setBracket(String.valueOf(va));

                    //创建对象
                    Condition condition = addCondition(name, "group", null);
                    rule.setGroup("1");
                    if (rule.getGroupIds() == null || rule.getGroupIds().size() == 0) {
                        rule.setGroupIds(new ArrayList<>());
                    }

                    condition.setDescribe(null);
                    if (rule.getSubscript() == null) {
                        rule.setSubscript("1");
                    }
                    int endva = Integer.valueOf(rule.getSubscript()) + 1;
                    rule.setSubscript(String.valueOf(endva));//记录下标
                    condition.setTierIndex(String.valueOf(endva));
                    rule.setIsObject("0");//添加对象后回复初始状态
                    if (list == null) {
                        list = new ArrayList<>();
                        list.add(condition);
                        rule.setConditionList(list);
                    } else if (rule.getGroupIds().size() == 0) {
                        list.add(condition);
                    } else {
                        //保证每个分组都是最后一个
                        Condition cond = getLastGroupCondition(list, rule);
                        condition.setTierIndex(String.valueOf(Integer.valueOf(cond.getTierIndex()) + 1));
                        if (cond.getConditionList() == null) {
                            cond.setConditionList(new ArrayList<>());
                        }
                        cond.getConditionList().add(condition);
                    }
                    //更新新的分组ID
                    rule.getGroupIds().add(condition.getId());
                    rule.setBracket("0");

                }
                if (text.equals(")")) {
                    //判断上一层是否是分组,如果不是分组则设置不是分组的标记
                    if (rule.getGroupIds().size() > 0) {
                        //现在使用的组
                        rule.getGroupIds().remove(rule.getGroupIds().size() - 1);
                    }
                    if (rule.getGroupIds().size() == 0) {
                        rule.setGroup("0");
                    }
                }
            } else if (res == 4 || text.lastIndexOf("@") >= 0) { //@ 参数标识
                rule.setType("1");
            } else {
                //初始化对象与集合
                if (list == null || list.size() == 0) {
                    list = new ArrayList<>();
                    Condition condition = addCondition(name, "single", null);
                    list.add(condition);
                    rule.setConditionList(list);
                }
                if (rule.getGroup() == null || rule.getGroup().equals("0")) {
                    if (rule.getIsObject() != null) {
                        if (rule.getIsObject().equals("1")) {
                            //创建对象
                            Condition condition = addCondition(name, "single", null);
                            list.add(condition);
                            rule.setIsObject("0");//添加对象后回复初始状态
                        }
                    }
                } else {
                    if (rule.getIsObject() != null && rule.getIsObject().equals("1")) {
                        Condition cond = getLastGroupCondition(list, rule);
                        List<Condition> conditionList = cond.getConditionList();
                        //创建对象
                        Condition addCondition = addCondition(name, "single", null);
                        conditionList.add(addCondition);
                        rule.setIsObject("0");//添加对象后回复初始状态
                        rule.setType("1");//添加左边值
                    }
                }
                Condition condition = null;

                if (rule.getGroup() != null && rule.getGroup().equals("1")) {
                    condition = getLastGroupCondition(list, rule);
                    //获取最后的分组对象
                    List<Condition> conditionList = condition.getConditionList();
                    Condition cond = null;
                    //初始化对象与集合
                    if (conditionList == null || conditionList.size() == 0) {
                        conditionList = new ArrayList<>();
                        cond = addCondition(name, "single", null);
                        setCondition(cond, text, rule);
                        conditionList.add(cond);
                        condition.setConditionList(conditionList);
                    } else {
                        cond = conditionList.get(conditionList.size() - 1);
                        setCondition(cond, text, rule);
                    }
                } else {
                    condition = list.get(list.size() - 1);
                    setCondition(condition, text, rule);
                }
            }
        }
        //递归 循环遍历
        for (int i = 0; i < tree.getChildCount(); i++) {
            traverseTree(tree.getChild(i), name, rule);
        }
        return rule;
    }

    //获取最后一个分组对象
    private static Condition getLastGroupCondition(List<Condition> list, RuleEntity rule) {
        String groupId = rule.groupIds.get(rule.groupIds.size() - 1);
        Condition cond = list.get(list.size() - 1);
        while (true) {
            if (cond.getId().equals(groupId)) {
                break;
            }
            cond = cond.getConditionList().get(cond.getConditionList().size() - 1);
        }
        return cond;
    }

    private static void setCondition(Condition condition, String text, RuleEntity rule) {
        //获取属性详情,判断属性是否存在,如果存在拿到属性名称、类型等信息
        String type = DataType.getDataType(text);
        if (condition.getLeftOperatorExpression() == null || condition.getRightOperatorExpression() == null) {
            if (rule.getType() == null || rule.getType().equals("1")) {
                //创建左边运算符表达式
                LeftOperatorExpression left = addLeftOperatorExpression(type, text);
                condition.setLeftOperatorExpression(left);
                rule.setType("0");
            }
            if (rule.getType().equals("2")) {
                //创建右边运算符表达式
                RightOperatorExpression right = addRightOperatorExpression(type, text);
                condition.setRightOperatorExpression(right);
                rule.setType("0");
                rule.setBracket("0");
            }
            //如果都是常量,则进行类型对齐
            //一边是日期,一边是非日期,则全部改成字符串
            //一边是数字,一边非数字,则全部改成字符串
            //或者状态是contains和notcontains(7,8)也需要转成字符串
            if (condition.getLeftOperatorExpression() != null
                    && condition.getLeftOperatorExpression().getId().lastIndexOf("Constant") >= 0
                    && condition.getRightOperatorExpression() != null
                    && condition.getRightOperatorExpression().getId().lastIndexOf("Constant") >= 0
                    && (
                    !condition.getLeftOperatorExpression().getValueType().equals(condition.getRightOperatorExpression().getValueType())
                            || condition.getCompareOperation().equals("7") || condition.getCompareOperation().equals("8")
            )) {

                condition.getLeftOperatorExpression().setValueType("string");
                condition.getLeftOperatorExpression().setLabel(SymbolOptions.getNameOrValue("string"));

                condition.getRightOperatorExpression().setValueType("string");
                condition.getRightOperatorExpression().setLabel(SymbolOptions.getNameOrValue("string"));

            }


        }

    }

    /**
     * 创建 Condition 对象
     *
     * @param name
     * @param type
     * @return
     */
    public static Condition addCondition(String name, String type, String text) {
        //创建对象
        Condition condition = new Condition();
        //设置条件组属性
        condition.setFormulaRelation(text);
        condition.setId(generateId(""));//id需要自动生成 bc3369691d(10位数)
        condition.setType(type);//类型(单个的 如何获取??)
        if (text == null) {
            condition.setDescribe(name);//描述
        }
        if (type.equals("group")) {
            condition.setDescribe("");
        }
        return condition;
    }

    /**
     * 创建左边运算符表达式
     *
     * @param type
     * @param text
     * @return
     */
    public static LeftOperatorExpression addLeftOperatorExpression(String type, String text) {
        LeftOperatorExpression left = new LeftOperatorExpression();
        if (text.lastIndexOf("@") >= 0) {
            left.setId(generateId("Parameter"));//id需要自动生成 Parameter_xxxxxxxxxx(10位数)
            //是变量
            left.setType("6");
            left.setValue(text);//值
        } else {
            left.setId(generateId("Constant"));//id需要自动生成 Parameter_xxxxxxxxxx(10位数)
            //是常量
            left.setType("1");
            left.setValue(text);//值
        }
        left.setValueType(type);//值类型
        left.setLabel(SymbolOptions.getNameOrValue(type));//参数名称(属性值的名称 @ 如何定义?没有依据)
        return left;
    }

    /**
     * 创建右边运算符表达式
     *
     * @param type
     * @param text
     * @return
     */
    public static RightOperatorExpression addRightOperatorExpression(String type, String text) {
        RightOperatorExpression right = new RightOperatorExpression();
        if (text.lastIndexOf("@") >= 0) {
            right.setId(generateId("Parameter"));//id需要自动生成 Parameter_xxxxxxxxxx(10位数)
            //是变量
            right.setType("6");
            right.setValue(text);//值
        } else {
            right.setId(generateId("Constant"));//id需要自动生成 Parameter_xxxxxxxxxx(10位数)
            //是常量
            right.setType("1");
            right.setValue(text);//值
        }
        right.setValueType(type);//值类型
        right.setLabel(SymbolOptions.getNameOrValue(type));//参数名称(属性值的名称 @ 如何定义?没有依据)
        return right;
    }

    /**
     * 将公式转换成json
     *
     * @param name    公式名称
     * @param formula 公式
     * @return
     */
    public static String formulaToJson(String name, String formula) throws Exception {
        // 构建字符流
        CodePointCharStream charStream = CharStreams.fromString(formula);
        // 从字符流分析词法, 解析为token
        ExprLexer lexer = new ExprLexer(charStream);
        // 从token进行分析
        ExprParser parser = new ExprParser(new CommonTokenStream(lexer));
        // 使用监听器,遍历语法树,根据语法定义,prog为语法树的根节点
        ParseTree progTree = parser.expression();

        if (((ExprParser.ExpressionContext) progTree).exception != null) {
            throw new Exception("输入的表达式不符合解析规则");
        }
        // 遍历语法树节点
        RuleEntity rule = traverseTree(progTree, name, new RuleEntity());

        //设置自定义变量为null,做转换json忽略空置预处理
        if (rule != null) {
            rule.setType(null);
            rule.setIsObject(null);
            rule.setGroup(null);
            rule.setGroupIds(null);
            rule.setBracket(null);
            rule.setEndBracket(null);
            rule.setSubscript(null);
        }
        // 初始化Jackson的ObjectMapper
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // 忽略空值字段
        // 将对象转换为JSON字符串
        String json = null;
        try {
            json = objectMapper.writeValueAsString(rule);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        return json;
    }

    /**
     * 数字和字母随机组合10位数
     *
     * @param name
     * @return
     */
    public static String generateId(String name) {
        String generate = "";
        Random random = new Random();
        for (int i = 0; i < 10; i++) {
            // 输出字母还是数字
            String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
            // 字符串
            if ("char".equalsIgnoreCase(charOrNum)) {
                // 取得大写字母还是小写字母
                int choice = random.nextInt(2) % 2 == 0 ? 65 : 97;
                generate += (char) (choice + random.nextInt(26));
            } else if ("num".equalsIgnoreCase(charOrNum)) { // 数字
                generate += String.valueOf(random.nextInt(10));
            }
        }
        if (name == null || "".equals(name)) {
            return generate;
        }
        return name + "_" + generate;
    }

    /**
     * 根据属性ID 获取表单属性集合
     *
     * @param parameterId
     * @return
     */
    public static List<Parameter> getParameterById(Long parameterId) {
        //定义属性集合
        List<Parameter> parameterList = new ArrayList<>();
        if (parameterId != null) {
            //属性查询操作

            //获取属性值
            String jsonString = "{\"list\":[],\"config\":{\"layout\":\"horizontal\",\"labelCol\":{\"xs\":4,\"sm\":4,\"md\":4,\"lg\":4,\"xl\":4,\"xxl\":4},\"wrapperCol\":{\"xs\":18,\"sm\":18,\"md\":18,\"lg\":18,\"xl\":18,\"xxl\":18},\"view\":[{\"viewMode\":1,\"viewName\":\"发起视图\",\"controlList\":[]},{\"viewMode\":2,\"viewName\":\"审批视图\",\"controlList\":[]},{\"viewMode\":3,\"viewName\":\"查看视图\",\"controlList\":[]},{\"viewMode\":4,\"viewName\":\"打印视图\",\"controlList\":[]}],\"parameter\":[{\"name\":\"金额\",\"code\":\"Price\",\"describe\":\"结算金额\",\"value\":\"5000\",\"type\":\"string\",\"id\":\"793565f5314254944cdf1d79b2e20df6\"},{\"name\":\"数字\",\"code\":\"Price\",\"describe\":\"1\",\"value\":\"1\",\"type\":\"double\",\"id\":\"fea23b17d0d4f44de96cc0f01ce63abf\"}],\"cache\":false,\"hideRequiredMark\":false,\"hiddenFieldStrategy\":1,\"formStyle\":1,\"formStyleWidth\":\"95%\",\"formStyleBgColor\":\"#ecf2f7\",\"formStyleBg\":\"\",\"formHead\":\"\",\"formStyleTitle\":\"Test_Xiangfei\",\"formTitleStatus\":false,\"formSystemStyleId\":2,\"isShowHeader\":true,\"isFold\":false,\"isShowBoxIcon\":true,\"formStyleTitleCss\":{\"align\":\"center\",\"fontSize\":18,\"color\":\"#0c1b74\"},\"event\":{\"init\":null},\"eventList\":[],\"opinionExtra\":true}}";
            //通过fromObject将json字符串翻译成JSON对象(JSONObject)
            JSONObject jsonObject = JSONObject.parseObject(jsonString);
            //获取JSONObject对象值
            String config = jsonObject.getString("config");//结果就是简单的值类型
            if (config.length() > 0) {
                //二次转换将json对象值翻译成JSON对象
                JSONObject jsonConfig = JSONObject.parseObject(config);
                //获取JSONObject对象值
                String parameter = jsonConfig.getString("parameter");
                if (parameter.length() > 0) {
                    //将对象属性转换成属性集合
                    parameterList = JsonUtil.jsonToList(parameter, Parameter.class);
                }
            }
        }
        return parameterList;
    }

    //判断属性是否存在
    public static ParameterPojo checkParameter(String param, List<Parameter> list) {
        ParameterPojo parameterPojo = new ParameterPojo();
        //定义属性Code集合
        List<String> codeList = new ArrayList<>();
        if (list.size() > 0) {
            for (Parameter par : list) {
                if (par != null) {
                    codeList.add(par.getCode());
                }
            }
        }
        //判断属性
        int res = Collections.frequency(codeList, param);
        if (res == 1) {//存在属性
            Parameter parameter = new Parameter();
            for (Parameter par : list) {
                if (par.getCode().equals(param)) {

                }
            }
            parameter.setCode(param);
            parameterPojo.setParameter(parameter);
        } else if (res > 1) {//一对多属性 需要抛异常
            AbnormalParameter abnormalParameter = new AbnormalParameter();
            abnormalParameter.setCode(param);
            parameterPojo.setAbnormalParameter(abnormalParameter);
        } else {//缺失属性
            DeletionParameter deletionParameter = new DeletionParameter();
            deletionParameter.setCode(param);
            parameterPojo.setDeletionParameter(deletionParameter);
        }
        return parameterPojo;
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1822573.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于JSP技术的电子商城系统

开头语&#xff1a; 你好&#xff0c;我是计算机学长码农猫哥。如果你对电子商城系统感兴趣或有相关开发需求&#xff0c;欢迎联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;JSP技术 工具&#xff1a;Eclipse、Tomcat 系统展示 首页 管理…

算法007:三数之和

. - 力扣&#xff08;LeetCode&#xff09;. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/3sum/ 这个题相较于前几个题来说比较难&#xff0c;思想是前面一个题目…

【MySQL】mysql中常见的内置函数(日期、字符串、数学函数)

文章目录 案例表日期函数字符串函数数学函数其他函数 案例表 emp students 表 exam_result 表 日期函数 注意current_time和now的区别 案例一&#xff1a; 创建一张表用来记录生日&#xff0c;表结构如下 添加日期&#xff1a; insert tmp (birthday) values (2003-01-3…

Matrix->Matrix工具类获取Matrix的平移、缩放、错切数值

// 传入矩阵&#xff0c;获取矩阵数值 class MatrixValues(matrix: Matrix) {val scaleX: Floatval scaleY: Floatval transX: Floatval transY: Floatval skewX : Float val skewY : Floatinit {val fromValues FloatArray(9)matrix.getValues(fromValues)// 缩放数值scaleX …

1、MFC应用程序框架

MFC简介 MFCMFC样式 MFC应用程序框架单文档应用程序框架工程文件的组成结构 MFC应用程序框架分析SDK应用程序和MFC应用程序运行过程对比MFC应用程序框架主要类之间的关系 MFC消息映射机制概述消息消息映射机制Windows消息分类消息映射表 添加消息处理函数各种Windows消息的消息…

Linux 系统删除乱码文件

项目场景&#xff1a; 通过rm -rf 删除乱码文件&#xff0c;删除不了 问题描述 这时直接使用命令rm -rf 是删除不了的。只能通过删除 inode方法处理。 原因分析&#xff1a; 在Linux上传文件或文件夹时&#xff0c;由于出现连接中断&#xff0c;出现了大量的乱码文件&#…

顶顶通呼叫中心中间件(mod_cti基于FreeSWITCH)-通话时长限制

文章目录 前言联系我们场景运用机器人场景普通通话场景 前言 顶顶通呼叫中心中间件限制通话时长有两种写法&#xff0c;分别作用于机器人场景与普通通话场景。 普通场景可分为分机互打、分机外呼手机等。 联系我们 有意向了解呼叫中心中间件的用户&#xff0c;可以点击该链接…

Sping源码(九)—— Bean的初始化(非懒加载)— lookupMethod标签

序言 在继续深入Spring的对象创建流程之前&#xff0c;这篇文章先简单介绍一下lookupMethod标签的用法及作用。 准备的xml 自定义名为methodOverride.xml的配置文件。 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.s…

旅行者1号有什么秘密?飞行240多亿公里,为什么没发生碰撞?

旅行者1号有什么秘密&#xff1f;飞行240多亿公里&#xff0c;为什么没发生碰撞&#xff1f; 自古以来&#xff0c;人类就对浩瀚无垠的宇宙充满了好奇与向往。从最初的仰望星空&#xff0c;到如今的深空探测&#xff0c;人类探测宇宙的历史发展可谓是一部波澜壮阔的史诗。 在…

【Shopee】计算虾皮订单的各项支出和订单收入计算方法

虾皮订单成交截图 基础条件&#xff1a; 商品金额&#xff1a;11.92 [4x2.98] 商品原价&#xff1a;7.5 商品折后价&#xff1a;2.98 商品数量&#xff1a;4 优惠券与回扣&#xff1a; 店铺优惠券&#xff08;减10%&#xff09;&#xff1a;1.2 [11.92x10% 四舍五入了] 订单实…

基于软件在环的飞控机建模仿真

安全关键系统&#xff08;Safety-Critical System&#xff0c;SCS&#xff09;是指由于某些行为或组合行为能够引发整体系统失效&#xff0c;继而导致财物损失、人员受伤等严重影响的系统&#xff0c;诸多安全关键领域如航空航天、核电系统、医疗设备、交通运输等领域的系统都属…

redis 笔记2之哨兵

文章目录 一、哨兵1.1 简介1.2 实操1.2.1 sentinel.conf1.2.2 问题1.2.3 哨兵执行流程和选举原理1.2.4 使用建议 一、哨兵 1.1 简介 上篇说了复制&#xff0c;有个缺点就是主机宕机之后&#xff0c;从机只会原地待命&#xff0c;并不能升级为主机&#xff0c;这就不能保证对外…

Redis之线程IO模型

引言 Redis是个单线程程序&#xff01;这点必须铭记。除了Redis之外&#xff0c;Node.js也是单线程&#xff0c;Nginx也是单线程&#xff0c;但是他们都是服务器高性能的典范。 Redis单线程为什么能够这么快&#xff01; 因为他所有的数据都在内存中&#xff0c;所有的运算都…

❤ npm运行打包报错归纳

❤ 前端运行打包报错归纳 &#xff08;安装依赖&#xff09;Cannot read property ‘pickAlgorithm’ of null" npm uninstall //删除项目下的node_modules文件夹 npm cache clear --force //清除缓存后 npm install //重新安装 备用安装方式 npm install with --for…

英格索兰IC12D3A1AWS-A控制器过热维修

在现代工业生产中&#xff0c;拧紧控制器作为一种自动控制工具&#xff0c;被广泛应用于汽车、航空、电子等领域。然而&#xff0c;在使用过程中&#xff0c;可能会出现IngsollRang拧紧控制器过热故障&#xff0c;影响生产效率和产品质量。 【拧紧设备维修】【英格索兰IngsollR…

初始化三板斧 - centos7

1、关闭防火墙、关闭SELinux ① 立即关闭防火墙 systemctl stop firewalld ② 设置开机关闭防火墙 systemctl disable firewalld ③ 立即关闭SELinxu setenforce 0 ④ 设置开机关闭SELinux 将SELINUXenforcing 修改替换为 SELINUXdisabled vim /etc/selinux/config se…

M41T11M6F串行实时时钟-国产兼容RS4C411

RS4C411是一款低功耗串行实时时钟&#xff08;RTC&#xff09;&#xff0c;具有56字节的NVRAM。内置32.768 kHz振荡器&#xff08;外部晶体控制&#xff09;和RAM的前8字节用于时钟/日历功能&#xff0c;并以二进制编码十进制&#xff08;BCD&#xff09;格式配置。地址和数据通…

汽车金属管检测新方法,分度盘高速视觉检测机检测效果如何?

汽车金属管是指在汽车制造和维修中广泛使用的金属管道&#xff0c;用于传输流体、气体或其他介质。汽车金属管在汽车中扮演着重要的角色&#xff0c;用于传输液体&#xff08;如燃油、冷却液、润滑油&#xff09;、气体&#xff08;如空气、排气&#xff09;、制动系统、液压系…

利用three-csg-ts对做物体交互式挖洞

默认物体均为居中&#xff0c;如果指定位置没有发生偏移&#xff0c;可能是因为在执行布尔操作之前没有正确设置变换。确保在进行布尔运算之前应用所有必要的变换。以下是经过修正的完整代码示例&#xff0c;它会确保圆柱正确旋转并与盒子进行 CSG 操作。 安装依赖 首先&…

企业怎样管控员工外发文件,公司文件外发管控的方法

在数字化办公日益普及的今天&#xff0c;企业信息的安全管理成为了维护企业竞争力的关键一环。 员工在日常工作中外发文件的行为&#xff0c;如果不加以适当管控&#xff0c;很可能导致敏感信息泄露&#xff0c;影响企业运营乃至声誉。 因此&#xff0c;建立一套有效的文件外…