欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-07 21:54:22
...

关于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 学习笔记(一)----stateless session(无状态会话) 的使用

上述例子只对申请人的年龄做了处理,若此时想对申请日期做判断的话该如何处理呢?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.
Drools 学习笔记(一)----stateless session(无状态会话) 的使用

相关标签: Drools