Drools规则引擎⼊门指南(⼀)
最近项⽬需要增加风控系统,在经过⼀番调研以后决定使⽤Drools规则引擎。因为项⽬是基于SpringCloud的架构,所以此次学习使⽤了SpringBoot2.0版本结合Drools7.14.0.Final版本。
引⼊依赖
1 2 3 4 5 6 7 8 9 10<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>    <version>7.14.0.Final</version> </dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-spring</artifactId>    <version>7.14.0.Final</version> </dependency>
创建配置类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57@Configuration
public class DroolsAutoConfiguration {
private static final String RULES_PATH = "rules/";
@Bean
@ConditionalOnMissingBean(KieFileSystem.class)
public KieFileSystem kieFileSystem() throws IOException {
KieFileSystem kieFileSystem = getKieServices().newKieFileSystem();
for (Resource file : getRuleFiles()) {
kieFileSystem.wClassPathResource(RULES_PATH + Filename(), "UTF-8"));        }
return kieFileSystem;
}
private Resource[] getRuleFiles() throws IOException {
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
Resources("classpath*:" + RULES_PATH + "**/*.*");
}
@Bean
@ConditionalOnMissingBean(KieContainer.class)
public KieContainer kieContainer() throws IOException {
final KieRepository kieRepository = getKieServices().getRepository();
kieRepository.addKieModule(new KieModule() {
public ReleaseId getReleaseId() {
DefaultReleaseId();
}
});
KieBuilder kieBuilder = getKieServices().newKieBuilder(kieFileSystem());
kieBuilder.buildAll();
return getKieServices().DefaultReleaseId());
}
@Bean
@ConditionalOnMissingBean(KieBase.class)
public KieBase kieBase() throws IOException {
return kieContainer().getKieBase();
}
@Bean
@ConditionalOnMissingBean(KieSession.class)
public KieSession kieSession() throws IOException {
KieSession kieSession = kieContainer().newKieSession();
return kieSession;
}
@Bean
@ConditionalOnMissingBean(KModuleBeanFactoryPostProcessor.class)
public KModuleBeanFactoryPostProcessor kiePostProcessor() {
return new KModuleBeanFactoryPostProcessor();
}
public KieServices getKieServices() {
System.setProperty("drools.dateformat","yyyy-MM-dd");
return ();
}
}
在这个时候我们的基本环境已经搭建好了,接下来我们⼀起来学习Drools吧
HelloWord
程序员的世界⾥,我们学习任何⼀门语⾔都是以HelloWord开启的,本次学习也不例外。
1.创建规则⽂件
Drools的规则⽂件是以*.drl结尾的⽂件,我们来看⼀个最简单的规则⽂件中都是包含什么。
通常来说,我们会把规则⽂件放在resources资源⽂件夹下,这⾥呢我们在resources⽂件夹下新建⼀个rules⽂件夹,然后再新建⼀个HelloWord.drl⽂件
1 2 3 4 5 6 7 8 9 10 11package rules;
ity.User;
import java.lang.String;
import java.util.List;
rule "hello,word"
when
eval(true)
then
end
1. 规则⽂件,就是我们新建的这个HelloWord.drl可以理解为⼀个Java类
2. package,这个跟Java中的包名是差不多的
3. import,此⽂件中需要的类。
4. rule,可以理解为给这个规则起的⼀个名字,⼀个规则⽂件中可以包含多个rule。
5. when,when下⾯可以放置⼀些条件判断的表达式以及定义⼀些变量什么的。如果⾥⾯内容为空的话则会默认添加⼀个eval(true)代表
⼀个为true的表达式
6. then,当when下⾯的表达式为true是then下⽅的代码才会执⾏,在这⾥可以直接编写Java代码(代码所需要的类通过import引⼊),
当然也可以使⽤when模块定义的⼀些变量
7. end 代表规则hello,word的结束。
2.Java调⽤
现在我们的规则⽂件写好以后就可以在Java中来进⾏调⽤了。
1. 新建⼀个测试类DroolsApplicationHelloWordTests
1 2 3 4 5 6 7 8@RunWith(SpringRunner.class)
@SpringBootTest
public class DroolsApplicationHelloWordTests {    @Autowired
KieSession kieSession;
}
上⽅注⼊的kieSession对象就是以后与Drools打交道最常⽤的⼀个对象了,通过它可以直接操作在配置类kieFileSystem⽅法中加载的所有的规则⽂件
2. 编写测试代码
1 2 3 4@Test
public void testHelloWord() {    kieSession.fireAllRules(); }
kieSession.fireAllRules⽅法是执⾏所有的规则,在运⾏了这个测试⽅法之后我们应该就可以看到控制台打印的⼀句hello,word!了基础学习
1. 向规则⽂件传参
1. 在entity包下新增⼀个User的实体类
1public class User {
1 2 3 4 5 6 7 8 9 10public class User {
private String name;
private int age;
public User(String name, int age) {        this.name = name;
this.age = age;
}
//省略getter,setter
}
2. 在hello,word规则下⽅再次新建⼀个规则user
1 2 3 4 5 6 7rule "user"
when
$u:User(name=="张三",age==18)
then
$u.setName("李四");
$u:User(name==“张三”,age==18)的意思就是当存在⼀个user对象,并且它的name属性等于张三age等于18时就把这个对象赋值给$u。在下⽅的then模块,如果上⽅的条件成⽴时就把$u的name属性更新⼀下,然后打印。
3. 编写测试代码
1 2 3 4 5 6 7@Test
public void testUser() {
User user=new User("张三",18);
kieSession.insert(user);
kieSession.fireAllRules();
我们可以使⽤kieSession.insert⽅法向规则⽂件中传参,然后在调⽤⽅法后你会发现在规则⽂件中更改的值在Java代码中也被更改了。
4. 存在的⼩问题
可能你会发现上⽅代码执⾏的时候连那句helloword也打印了,为什么呢,这是因为HelloWord那条规则没有验证条件再加上kieSession.fireAllRules()本来就是执⾏所有被加载的规则的。那么避免这种情况的办法就是执定本次执⾏的规则
1 2 3 4 5 6@Test
public void testOneRule() {
User user=new User("张三",18);
kieSession.insert(user);
kieSession.fireAllRules(new RuleNameEndsWithAgendaFilter("user"));    }
上⽅的user就是指定的本次执⾏的规则名称了。
5.扩展操作
上⽅我们通过RuleNameEndsWithAgendaFilter对象成功指定了需要执⾏的规则⽂件,其实通过查看此对象的源码我们发现这个对象是AgendaFilter的⼀个实现类,决定执不执⾏⼀个规则的条件是accept⽅法返回的boolean值决定的。
所以说如果我们希望可以⼀次批量匹配多个规则的话可以通过继承AgendaFilter重写accept⽅法哦
2. 常⽤运算符
1. 连接符
Drools中存在的三种连接符,上⽅的代码中我们已经使⽤过⼀个了,那就$u:User(name==“张三”,age==18)中的逗号,这⾥的逗号其实就是and的意思。另外的两个运算符就是&&和||,相信它们两个的意思不⽤我来介绍了吧。
不过有⼀点需要注意的是&&和|| 和逗号,不能同时出现。要不你选择⽤&&和||要不就只⽤逗号,。
2. 类型⽐较操作符
1.⾸先就是<,>,==,!=,>=,<=这六个
它们是配合eval使⽤的,⽐如上⽅我们使⽤的eval(true)就是直接返回的true。当我们⽐较常量时可以使⽤eval(u.age>b.age)
2. contains not contains
contains⽤于判断对象的某个字段是否包含另外⼀个对象
1 2 3 4 5 6 7rule "contains"
when
$s:String()
$u:User(name contains $s)
then
container什么意思1 2 3 4 5 6 7 8@Test
public void testContains() {
String name="张三";
User user=new User("张三",18);
kieSession.insert(name);
kieSession.insert(user);
kieSession.fireAllRules(new RuleNameEndsWithAgendaFilter("contains"));    }
not contains顾明思议就是不包含
3. memberOf not memberOf
memberOf⽤于判断对象的某个字段是否存在⼀个集合中
1 2 3 4 5 6 7rule "memberOf"
when
$list:List()
$u:User(name memberOf $list)
then
1 2 3 4 5 6 7 8 9 10@Test
public void testMemberOf() {
List list=new ArrayList();
list.add("张三");
list.add("李四");
User user=new User("李四",18);
kieSession.insert(list);
kieSession.insert(user);
kieSession.fireAllRules(new RuleNameEndsWithAgendaFilter("memberOf"));    }
not memberOf顾明思议就是不存在3. matches not matches
matches就是⽤于匹配正则表达式的了
1 2 3 4 5 6rule "matches"
when
$u:User(name matches "张.*")
then
1 2 3 4 5 6@Test
public void testMatches() {
User user=new User("张三",18);
kieSession.insert(user);
kieSession.fireAllRules(new RuleNameEndsWithAgendaFilter("matches"));  }
not matches不⽤我说了吧本⽂所有源码:
本⽂出⾃,转载请保留

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。