Drools 学习笔记(一)----stateless session(无状态会话) 的使用

关于Drools:
Drools是jboss的一款开源的业务规则引擎,具有速度快、效率高、易学习的特点。
本文内容参考自Drools 官方文档 7.9.0.Final版
https://docs.jboss.org/drools/release/7.9.0.Final/drools-docs/html_single/index.html
让我们从使用驾驶执照申请的一个非常简单的例子开始。
(1)首先我们需要创建一个maven项目,需要添加的依赖为:

<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-compiler</artifactId>
    <version>7.5.0.Final</version>
</dependency>

(2)接着我们需要创建一个POJO类

public class Applicant {
    private String name;
    private int age;
    private boolean valid;
    // getter and setter methods here
}

现在我们有了数据模型,我们可以开始编写第一条规则。由于这是一个简单的验证用例,我们将添加一条规则来取消任何年龄小于18岁的申请人的资格。

package org.drools.examples.helloworld.entity

rule "Is of valid age"
when 
    $a : Applicant(age>18)
then
    $a.setValid(true);
end

我们需要将上面的内容放到src\mian\resources目录下,并将其命名为 .drl格式的文件。
drl 即Drools Rule Language。在这里我们将其命名为license.drl,同时,在我们的maven项目中还需要创建一个kmodule.xml,这个文件需要放到resources\META-INF文件夹下,由于Drools 已为我们提供有意义的默认值,因此最简单的kmodule.xnl只需要包含一个空的kmodule标签即可,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://www.drools.org/xsd/kmodule"/>

我们接着看上面的drl文件,会发现它和java的语法非常类似。
package : 所用到的pojo类的位置
rule : 规则名称,这里可以是任意值,但需要保持唯一性
when…then…end : 当满足某种条件时,就如何如何,以end做结尾
$a$a是一个绑定变量,它允许我们的引用匹配的对象,美元字符$是可选的,用于区分变量名和字段名,在这里绑定一个变量用的是 “:”
Applicant( age < 18 ) : Applicant 则是我们的数据模型,age<18则是判断条件

(3)调用规则,使规则生效

KieServices kieServices = KieServices.Factory.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();

上面这段代码使我们在类路径下找到所有的DRL文件,并将此编译的结果kiemodule放到 kieContainer中。如果没有错误,我们现在可以从kiecontainer中执行一些数据:

StatelessKieSession kieSession = kieContainer.newStatelessKieSession();
Applicant app = new Applicant();
app.setName("liuyang");
app.setAge(19);
Assert.assertFalse(app.isValid());
System.out.println("执行规则前:"+app.toString());
kieSession.execute(app);
System.out.println("执行规则后:"+app.toString());
Assert.assertTrue(app.isValid());

到此为止,未满18岁的申请人,都会被标记为无效。
这里写图片描述

上述例子只对申请人的年龄做了处理,若此时想对申请日期做判断的话该如何处理呢?Drools实现了对多个实例对象的判断。此时我们将Applicant中的valid移到Application中。

public class Applicant {
    private String name;
    private int age;
// 省略 get set
}
public class Application {
    private String dateApplied;
    private boolean valid;
// 省略 get set
}

我们再添加另一条规则来验证其申请日期是否在我们规定的范围。

package org.drools.examples.helloworld.exam2


rule "Is of valid age"
when 
    Applicant( age > 18 )
    $a : Application()
then
    $a.setValid(true);
end

rule "Application was made this year"
when 
    $a : Application(dateApplied > "2018-01-01" )
then 
    $a.setValid(false);
end

通过Arrays.asList(…)将这两个实例放入集合中,按照放入的顺序执行drl中的规则

public class MyTest {
    public static void main(String[] args) {
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieContainer = kieServices.getKieClasspathContainer();

        StatelessKieSession kieSession = kieContainer.newStatelessKieSession();
        Applicant applicant = new Applicant("liuyang", 20);
        Application application = new Application();
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        application.setDateApplied(df.format(new Date()));
        System.out.println("执行规则前:" + application.toString());
        kieSession.execute(Arrays.asList(applicant , application ));
        System.out.println("执行规则后:" + application.toString());
    }
}

由于Arrays.asList中先放入的是applicant,因此会先执行”Is of valid age”这条规则,因为20>18,因此此时的valid为true。接着执行”Application was made this year”这条规则,此时日期为2018-08-11,大于规则中的2018-01-01,因此valid为false.
这里写图片描述

猜你喜欢

转载自blog.csdn.net/ly690226302/article/details/81583738