Drools决策表+SpringBoot使用及语法详解

SpringBoot+Drools决策表的使用

    • 简介
    • Drools决策表
      • 决策表部分关键字
      • 规则部分关键字
      • 总结
    • SpringBoot 项目中决策表的使用
      • pom配置
      • 验证决策表格式是否正确
      • 利用KieHelper执行drl文件
      • 测试整合后的效果

简介

本人最近在研究SpringBoot使用Drools规则引擎实现自动流程审批功能,期间遇到过很多坑,最终选定Drools决策表的功能,决策表方便业务人员进行规则的添加就修改操作,清晰明了,以下纯属个人学习记录,欢迎学习交流。

Drools决策表

决策表是drl规则文件的变形,以excel 格式完成对规则的匹配,通俗的讲,决策表就是向电子表格输入特点的值,并加载到Drools规则库中,可以用特定的类对表格进行转换,转换为drl文件,从而用程序进行解析。废话不多说,先来一张做完的Drools决策表如下图,Drools决策表大体包含两部分,灰色部分是决策表部分,浅蓝色部分为规则部分,下面详细说明每个关键字的作用
Drools决策表+SpringBoot使用及语法详解_第1张图片

决策表部分关键字

关键字 是否必填 说明
RuleSet String 在这个单元格右侧包含RuleSet的名称,与drl文件中的package一样的
Sequential true/false true则代表表格从上到下顺序执行,false 代表乱序执行
Import String 导入所需的引用的类或方法,多个类用逗号隔开
Functions String 功能与标准的drl 文件中函数相同,多个函数在每个函数后用逗号隔开,有无返回值都可以
Variables String 全局变量,多个变量用逗号隔开
Queries String 定义查询函数,多个用逗号隔开
RuleTable String 表示规则名称,在RuleTable 后面直接写规则名称,不要另起一列,规则名以逗号隔开

规则部分关键字

关键字 是否必填 说明
CONDITION String 指明该列为判断条件,相当于drl文件中的when 部分,每个规则至少有一个CONDITION
ACTION String 指明该列为结果,每行如果符合前面的所有CONDITION,既执行此行的ACTION,相当于drl文件中的then
PRIORITY int 指明该列的值将被设置为该规则的‘lalience’(规则执行先后顺序,值越大执行顺序越靠前),但注意,若在ruleSet 下设置了sequential 为true,则PRIORITY不生效,设置为false或不设置,则PRIORITY生效
NAME String 指明该列的值将会被设置为从那行产生的规则名称
NO-LOOP true/false 指明这个规则不允许循环,与drl文件中no-loop功能一样
ACTIOVATION-GROUP String 在这个列中单元格的值,指出该规则行属于特定的活动分组。一个活动分组以为这在命名组中的规则只有一条会被引用(首条规则触发哦,中止其他规则活动)与drl中含义一样
AGENDA-GROUP String 在这个列中单元格的值,指出该规则行属于特定的议程组,可以理解成获取焦点(这是一种在规则组之间控制流的方法),与drl文件中含义一样
RULEFLOW-GROUP String 在这个列中单元格的值,指出该规则行属于特定的规则流组

总结

决策表必不可少的俩部分RuleSetRuleTable,RuleSet 后面填写转换为drl 文件的包名,一般和实体类包名一致,Import需要注意的是,在Java开发中,String,Boolean这些类型是不需要在类中Import,但是在决策表中需要Import,否则会找不到类;股则RuleTable部分主要是CONDITIONACTION两个关键字,相当于 when … then … 当条件CONDITION满足时就执行ACTION后的动作。

SpringBoot 项目中决策表的使用

我目前使用的是通过Drools工具类KieHelper来调用决策表;大体分为以下几步:
1.pom引入所需Drools Mvn库
2.验证决策表转换drl文件是否正确
3.利用KieHelper执行drl文件

pom配置

引入drools版本配置,我使用的是7.5.0Final,引入以下6个基本上满足开发需求了

	<properties>
        <drools.version>7.5.0.Final</drools.version>
	</properties>
   <dependencies>
		<!-- drools -->
        <dependency>
            <groupId>org.kie</groupId>
            <artifactId>kie-api</artifactId>
            <version>${drools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-core</artifactId>
            <version>${drools.version}</version>
        </dependency>
        <!-- compiler 必须引用的包,用于对规则的编译、构建 -->
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-compiler</artifactId>
            <version>${drools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-decisiontables</artifactId>
            <version>${drools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-templates</artifactId>
            <version>${drools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.kie</groupId>
            <artifactId>kie-ci</artifactId>
            <version>${drools.version}</version>
        </dependency>
	</dependencies>

验证决策表格式是否正确

/**
	 * 验证决策表格式是否正确
	 * 正确返回DRL文件
	 * 错误返回 NULL字符串
	 * @param filePath 文件存储地址
	 * @param fileType 文件类型  XLS 和 CSV 两种
	 * @return 返回DRL文件内容
	 */
	public static String ValidationecisionTable(String filePath,String fileType) {
		String drl =null;
		try {
			File file = new File(filePath);
			InputStream is = new FileInputStream(file);
			// DRL 解析类 :compile 方法解析文件 可以解析 XLS 和 CSV 两种文件格式
			SpreadsheetCompiler conCompiler = new SpreadsheetCompiler();
			if("XLS".equals(fileType)) {
				drl = conCompiler.compile(is, InputType.XLS);
			}else if("CSV".equals(fileType)){
				drl = conCompiler.compile(is, InputType.CSV);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return drl;
	}

利用KieHelper执行drl文件

/**
	 * 执行drl文件并返回结果集
	 * @param drl  drl文件内容
	 * @param obj  所需执行的对象
	 * @return 返回对象执行后的结果
	 */
	public static Object ExecuteDRLFile(String drl,Object obj) {
		if(drl!=null) {
			KieHelper helper = new KieHelper();
			helper.addContent(drl, ResourceType.DRL);
			KieSession kieSession = helper.build().newKieSession();
			kieSession.insert(obj);
			int i = kieSession.fireAllRules();
			System.out.println("规则执行了"+i+"次");
		}else {
			System.out.println("文件解析错误,请检查决策表");
		}
		return obj;
		
	}

测试整合后的效果

只需以上三步即可完成初步的实现,下面来调用一下试试!代码如下
决策表中用到的实体类

/**
 *
 * @Author Miracle hezp
 * @Date 2020/5/7 13:49:50
 * @Version 1.0
 */
@Data
public class LockApproval implements java.io.Serializable {

    static final long serialVersionUID = 1L;

    @org.kie.api.definition.type.Label("锁ID")
    @JSONField(name = "lock_id")
    private String lockId;

    @org.kie.api.definition.type.Label("锁类型")
    @JSONField(name = "lock_type")
    private String lockType;
    @org.kie.api.definition.type.Label("锁模式")
    @JSONField(name = "lock_mode")
    private String lockMode;

    @org.kie.api.definition.type.Label("业务类型")
    @JSONField(name = "business_type")
    private String businessType;

    @org.kie.api.definition.type.Label("分支")
    @JSONField(name = "org_name")
    private String orgName;

    @org.kie.api.definition.type.Label("基础包月数")
    @JSONField(name = "base_package_months")
    private int basePackageMonths;

    @org.kie.api.definition.type.Label("不可独立购买")
    @JSONField(name = "category")
    private List<String> category;

    @org.kie.api.definition.type.Label("本分支产品")
    @JSONField(name = "is_own_org_product")
    private String isOwnOrgProduct;

    @org.kie.api.definition.type.Label("是否跳过节点")
    @JSONField(name = "result")
    private Boolean result = false;

}

根据实际业务编写,我这个例子主要是用于判断是否可以自动审批流程,根据传入的实体类信息,返回是可以自动审批结果,结果存入result字段中,决策表中ACTION执行的动作如下;
Drools决策表+SpringBoot使用及语法详解_第2张图片
Service 方法中直接调用DRL验证方法ValidationecisionTable,执行DRL文件即可

 LockApprovalVo lockApprovalVo = new LockApprovalVo();
        String drl = DRLUtil.ValidationecisionTable("E:\\LockApproval.xlsx", "XLS");
        System.out.println(drl);
        if (drl != null) {
           lockApproval = (LockApproval) DRLUtil.ExecuteDRLFile(drl, lockApproval);
        } else {
            System.out.println("文件解析错误,请检查决策表");
        }

执行后打印出drl转换结果如下示例
Drools决策表+SpringBoot使用及语法详解_第3张图片
可以看到规则被执行了,获取类中的值,getResult()结果成功被修改为true.
Drools决策表+SpringBoot使用及语法详解_第4张图片
到此SpringBoot结合Drl决策表配置及简单开发示例已完成,欢迎交流指正!

你可能感兴趣的:(决策表,SpringBoot)