用Java进行动态公式处理

来源:互联网 发布:人工智能的主要技术 编辑:程序博客网 时间:2024/05/24 00:58
最近有个需求是通过动态的配置公式 对表数据进行一些逻辑计算 
目前采用的是JEP这个开源类库 目前2.4版是免费的 3.0开始收费不过功能更强大更多可配置的东西.
公式实体(Formula) 配置的时候需要记录 表名(tableCode) 条件表达式(conditionExpr) 公式表达式(formulaExpr) 所需要赋的值(evaluate) 顺序号(orderNum)
复制代码
/** * Created by Teddy on 2017/10/23. */public class ExpressionUtil {    /**     * 计算List<Bean>配置了公式的值     * @param beanList     * @return     */    public static List<Map> workOutListBean(List<? extends BaseEntity> beanList){        if(CollectionUtils.isEmpty(beanList)){            return Collections.EMPTY_LIST;        }else {            Class<? extends BaseEntity> beanClass = beanList.get(0).getClass();            Table table = beanClass.getAnnotation(Table.class);//在实体中通过JPA注解获取表名            String tableCode = table.name();            if(StringUtil.isEmpty(tableCode)){                System.out.println("无法计算,该bean没有表名信息");            }            List<Map> mapList = BeanUtil.convertBeansToMaps(beanList);            FormulaService formulaService = SpringContext.getBean(FormulaService.class);            List<Formula> formulas = formulaService.queryByTableCode(tableCode);            for (Map map : mapList) {                JEP jep = getJEP(map);                for (Formula formula : formulas) {                    String conditionExpr = formula.getConditionExpr();                    String formulaExpr = formula.getFormulaExpr();                    String evaluate = formula.getEvaluate();                    workOutKey(jep,map,conditionExpr,formulaExpr,evaluate);                }            }            return mapList;        }    }    /**     * 非动态配置公式方式     * @param mapList     * @param conditionExpr     * @param formulaExpr     * @param evaluate     */    public static void workOutListMap(List<Map> mapList,String conditionExpr,String formulaExpr, String evaluate){        for (Map map : mapList) {            JEP jep = getJEP(map);            workOutKey(jep,map,conditionExpr,formulaExpr,evaluate);        }    }    /**     * 计算出表达式并填充     * @param jep     * @param map     * @param conditionExpr     * @param formulaExpr     * @param evaluate     */    private static void workOutKey(JEP jep,Map map,String conditionExpr, String formulaExpr, String evaluate){        //如果没有条件        if(StringUtil.isEmpty(conditionExpr)){            map.put(evaluate,workOutSingle(jep,formulaExpr));            //如果有条件 且条件为true        }else if(workOutBool(jep,conditionExpr)){            map.put(evaluate,workOutSingle(jep,formulaExpr));        }    }    /**     * 判断条件表达式     * @param jep     * @param expression     * @return     */    private static boolean workOutBool(JEP jep,String expression){        return (Double)workOutSingle(jep,expression) > 0;    }    /**     * 计算表达式的值     * @param jep     * @param expression     * @return     */    private static Object workOutSingle(JEP jep,String expression){        Object result = null;        try { //执行            Node parse = jep.parse(expression);            result = jep.evaluate(parse);        } catch (ParseException e) {            throw new BaseRunTimeException("公式表达式解析失败",e);        }        if(result == null){            throw new BaseRunTimeException("公式表达式解析失败");        }        return result;    }    /**     * 获取填充好变量的JEP对象     * @param param     * @return     */    private static JEP getJEP(Map param){        JEP jep = new JEP();        Set<Map.Entry> set = param.entrySet();        for (Map.Entry entry : set) {            Object entryValue = entry.getValue();            String entryKey = (String) entry.getKey();            jep.addVariable(entryKey, entryValue);        }        return jep;    }}
复制代码

以下是示例Demo:

分类: Java
原创粉丝点击