朋也的博客 » 首页 » 文章
作者:朋也
日期:2019-07-09
类别:java学习笔记
版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
drools翻译过来是
流口水
,不知道jboss为啥要起这个名字这货作用不是做校验的,它是做复杂运算的(比如保费的计算,商场活动打折等)
注意:它不是做校验的工具(虽然它也可以做校验)
下面来介绍一下这货的用法
创建一个普通的maven项目即可,添加drools依赖
pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>7.23.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>7.23.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>7.23.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-templates</artifactId>
<version>7.23.0.Final</version>
</dependency>
</dependencies>
接文原链: https://atjiu.github.io/2019/07/09/drools-tutorial/
首先创建一个实体类
Demo.java
public class Demo {
private int a;
private int b;
private int c;
// 计算的和
private int total;
// 放错误信息的列表
private List<String> errorMsg = new ArrayList<>();
// getter, setter, toString
}
drools的文件后缀是 drl
,在 src/main/resources
下创建一个文件夹 rules
,然后在这个文件夹里创建一个规则文件 test-rule.drl
,内容如下
package com.example.demo
import com.example.drools.Demo
rule "校验总额"
no-loop true // 不循环执行
salience 1 // 优先级,越大优先级越高
when
$demo:Demo(a + b != c)
then
$demo.getErrorMsg().add("a + b 与 c 不相等");
end
rule "计算总和"
no-loop true // 不循环执行
salience 2 // 优先级,越大优先级越高
when
$demo:Demo()
then
$demo.setTotal($demo.getA() + $demo.getB() + $demo.getC());
end
rule "按条件计算"
no-loop true // 不循环执行
salience 3 // 优先级,越大优先级越高
when
$demo:Demo(a>5,b>3) // 当a > 5 && b > 3 时才进行计算
then
$demo.setTotal($demo.getA() + $demo.getB() + $demo.getC());
end
这里我写了三个规则的demo
写一个 test 方法
//加载规则文件处理逻辑
@Test
public void test() {
// 构建KieSession, 这部分写法是固定的
KieServices kieServices = KieServices.Factory.get();
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
kieFileSystem.write(ResourceFactory.newClassPathResource("rules/test-rule.drl"));
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
kieBuilder.buildAll();
KieModule kieModule = kieBuilder.getKieModule();
KieSession kieSession = kieServices.newKieContainer(kieModule.getReleaseId()).newKieSession();
// 构建实体类对象
Demo demo = new Demo();
demo.setA(6);
demo.setB(4);
demo.setC(4);
// 将要过规则的类传进 kieSession 中
kieSession.insert(demo);
// 调用 fireAllRules() 方法进行规则处理,同时可以得知走了几个规则
int count = kieSession.fireAllRules();
System.out.println("总共触发了: " + count + " 条规则");
System.out.println(demo);
}
结果
总共触发了: 3 条规则
Demo{a=6, b=4, c=4, total=14, errorMsg=[a + b 与 c 不相等]}
先给一张图
下面来解释一下每一行都什么意思
CONDITION
可以有多个CONDITION
下的是条件,ACTION
下的是结果,我这给这一行也定成了表头并起了相应的名字,如果不想定表头的话,这一行要为空行代码如下
文原接链: https://atjiu.github.io/2019/07/09/drools-tutorial/
//把excel翻译成drl文件
@Test
public void test2() {
SpreadsheetCompiler compiler = new SpreadsheetCompiler();
// 最后一个参数是excel里 sheet 的名称
String rules = compiler.compile(ResourceFactory.newClassPathResource("rules" + File.separator + "rule.xlsx", "UTF-8"), "Sheet1");
try {
BufferedWriter out = new BufferedWriter(new FileWriter("src/main/resources/rules/test-rule-excel.drl"));
out.write(rules);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
上面excel里的规则生成的文件内容如下
package com.example.demo;
//generated from Decision Table
import com.example.drools.Demo;
function int count(Demo $demo) {
return $demo.getA() + $demo.getB() + $demo.getC();
}
// rule values at A10, header at A5
rule "条件计算1"
when
$demo:Demo(a>3,b>4)
then
$demo.setTotal(count($demo));
end
// rule values at A11, header at A5
rule "条件计算2"
when
$demo:Demo(c<3)
then
$demo.setTotal($demo.getA() + $demo.getB());
end
上面介绍了读取excel生成rule文件,然后再通过读取规则文件来处理业务,这样比较麻烦,下面来介绍一下直接读取excel,然后处理业务逻辑
代码如下
//读取excel规则处理逻辑
@Test
public void test1() {
KieServices kieServices = KieServices.Factory.get();
Resource dt = ResourceFactory.newClassPathResource("rules/rule.xlsx", getClass());
KieFileSystem kieFileSystem = kieServices.newKieFileSystem().write(dt);
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
kieBuilder.buildAll();
KieModule kieModule = kieBuilder.getKieModule();
KieSession kieSession = kieServices.newKieContainer(kieModule.getReleaseId()).newKieSession();
Demo demo = new Demo();
demo.setA(6);
demo.setB(5);
demo.setC(4);
kieSession.insert(demo);
int count = kieSession.fireAllRules();
System.out.println("总共触发了: " + count + " 条规则");
System.out.println(demo);
}
总共触发了: 1 条规则
Demo{a=6, b=5, c=4, total=15, errorMsg=[]}
jboss还提供了一个网站,能直接在网页上配置出来规则,更加方便了,不过对于程序员来说,写drl文件应该是首选,对于业务人员写excel应该是首选