Drools规则引擎(七):决策表

一:简介

Drools规则文件支持.drl和.xls两种格式,并支持两种格式的文件互相转换,xls格式的文件(Excel)通常称为决策表(decision table),决策表是一个“精确而紧凑的”表示条件逻辑的方式,非常适合商业级别的规则。

在这里插入图片描述

testRule.xls决策表Excel下载

二:语法

关键字说明是否必须
RuleSet相当于drl文件中的package必须,只能有一个。如果没有设置RuleSet对应的值则使用默认值rule_table
Sequential取值为Boolean类型。true表示规则按照表格自上到下的顺序执行,false表示乱序可选
Import相当于drl文件中的import,如果引入多个类则类之间用逗号分隔可选
Variables相当于drl文件中的global,用于定义全局变量,如果有多个全局变量则中间用逗号分隔可选
RuleTable它指示了后面将会有一批rule,RuleTable的名称将会作为以后生成rule的前缀必须
CONDITION规则条件关键字,相当于drl文件中的when。下面两行则表示 LHS 部分,第三行则为注释行,不计为规则部分,从第四行开始,每一行表示一条规则每个规则表至少有一个
ACTION规则结果关键字,相当于drl文件中的then每个规则表至少有一个
NO-LOOP相当于drl文件中的no-loop可选
AGENDA-GROUP相当于drl文件中的agenda-group可选

在决策表中还经常使用到占位符,语法为$后面加数字,用于替换每条规则中设置的具体值。

上面的决策表例子转换为drl格式的规则文件内容如下:

package rules;
//generated from Decision Table
import com.example.springbootdrools.entity.Person;
import java.util.List;

global java.util.List listRules;

// rule values at B10, header at B5
rule "personCheck_10"
	salience 65535
	agenda-group "sign"
	when
		$person : Person(sex != "男")
	then
		listRules.add("性别不对");
end

// rule values at B11, header at B5
rule "personCheck_11"
	salience 65534
	agenda-group "sign"
	when
		$person : Person(age < 22 || age > 25)
	then
		listRules.add("年龄不合适");
end

// rule values at B12, header at B5
rule "personCheck_12"
	salience 65533
	agenda-group "sign"
	when
		$person : Person(salary < 10000)
	then
		listRules.add("工资太低了");
end

三:集成

3.1 pom.xml

<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-decisiontables</artifactId>
    <version>7.10.0.Final</version>
</dependency>

drools-decisiontables 已经集成了其它依赖,所以只需要引入这一个依赖就行了,drools-core、drools-compiler等不需要再引入。
在这里插入图片描述

3.2 entity

public class Person {
    private String sex;
    private int age;
    private double salary;
}    

3.3 util

package com.example.springbootdrools.util;

import org.drools.decisiontable.InputType;
import org.drools.decisiontable.SpreadsheetCompiler;
import org.kie.api.builder.Message;
import org.kie.api.builder.Results;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.KieSession;
import org.kie.internal.utils.KieHelper;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.List;

public class KieSessionUtils {
    private KieSessionUtils() {
    }
    
    // 把xls文件解析为String
    public static String getDRL (String realPath) throws FileNotFoundException {
        File file = new File(realPath);
        InputStream is = new FileInputStream(file);
        SpreadsheetCompiler compiler = new SpreadsheetCompiler();
        String drl = compiler.compile(is, InputType.XLS);
        System.out.println(drl);
        return drl;
    }
    
    // drl为含有内容的字符串
    public static KieSession createKieSessionFromDRL(String drl) throws Exception{
        KieHelper kieHelper = new KieHelper();
        kieHelper.addContent(drl, ResourceType.DRL);
        Results results = kieHelper.verify();
        if (results.hasMessages(Message.Level.WARNING, Message.Level.ERROR)) {
            List<Message> messages = results.getMessages(Message.Level.WARNING, Message.Level.ERROR);
            for (Message message : messages) {
                System.out.println("Error: "+message.getText());
            }
            // throw new IllegalStateException("Compilation errors were found. Check the logs.");
        }
        return kieHelper.build().newKieSession();
    }

    // realPath为Excel文件绝对路径
    public static KieSession getKieSessionFromXLS(String realPath) throws Exception {
        return createKieSessionFromDRL(getDRL(realPath));
    }
}

3.4 test

@RequestMapping("/test3")
public void test3() throws Exception {
    String realPath = "/Users/xxx/Desktop/testRule.xls";
    KieSession session = KieSessionUtils.getKieSessionFromXLS(realPath);

    Person person = new Person();
    person.setSex("男");
    person.setAge(35);
    person.setSalary(1000);

    List<String> list = new ArrayList<String>();
    session.setGlobal("listRules",list);

    session.insert(person);
    session.getAgenda().getAgendaGroup("sign").setFocus();
    session.fireAllRules();

    for (String s : list) {
        System.out.println(s);
    }
    session.dispose();
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

风流 少年

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

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

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

打赏作者

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

抵扣说明:

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

余额充值