drl文件构成
drl文件构成,位于官网的第5章位置,也是drools作为规则引擎应用的最核心部分。
- Rule Language Reference
官网链接:https://docs.drools.org/7.73.0.Final/drools-docs/html_single/index.html#_droolslanguagereferencechapter
其中,package、rule end,是必须的,一般情况下import也少不了。
global、function、query则不是文件的必须项。
各模块解说
package
import
global // Optional
function // Optional
query // Optional
declare // Optional
rule "rule name"
// Attributes 属性
when
// Conditions 条件
then
// Actions 结果
end
rule "rule2 name"
...
package
类似于java类中的package,当drl文件存放的路径与drl文件中的package定义不同时,
例如drl文件存放路径为 resources/order,而drl文件中的package定义的是 rules
package rules;
使用kieheaper时,会报警告:
WARN 18656 — [nio-9531-exec-2] o.d.c.kie.builder.impl.KieBuilderImpl : File ‘order.drl’ is in folder "order’’ but declares package ‘rules’. It is advised to have a correspondance between package and folder names.
import
类似于java类中的import,可以引用java类,此时用法与java代码中的import一致,也可以引用静态方法,这点和java代码有区别。示例代码:
import java.util.Map
import com.dcy.drools.entity.Order
import com.dcy.drools.entity.Customer
global
全局变量,global定义的变量,可以在jvm内存和drools工作内存中进行共享。具体是kiesession会话与它的外部环境进行打通。
举例:
drl文件:
package rules;
import java.util.List;
global java.util.List myGlobalList;
rule "rule-g-1"
when
then
myGlobalList.add("rule-g-1");
System.out.println("global-rule-g-1。。");
end
test方法:
@Test
public void testGlobal() {
// 获取services
KieServices kieServices = KieServices.Factory.get();
// 获取container
KieContainer container = kieServices.getKieClasspathContainer();
// 获取session
KieSession kieSession = container.newKieSession();
List<String> list = new ArrayList<>();
list.add("testGlobal");
kieSession.setGlobal("myGlobalList", list);
// 触发规则
kieSession.fireAllRules();
kieSession.dispose();
System.out.println("global list:" + list);
}
执行输出结果:
global-rule-g-1。。
global list:[testGlobal, rule-g-1]
function
类似于java类中的私有方法,function只能在drl当前文件内调用,算是一种“私有”方法。
**function String format(String username) {
return "hello " + username;
}**
rule "Using a function"
when
// Empty
then
System.out.println( **format**( "James" ) );
end
query
和规则的区别是:规则是匹配到了条件之后,执行then后面的代码,query匹配到了之后将匹配到的fact对象返回到一个结果集,通过kie可以获取。也可以在rule中使用。
query可以有入参也可以无入参。
// 无入参的query query_1 也可以使用string,如"query-1"
query query_1
$person:Person(age > 30)
end
// 有入参的query
query query_2 (String username)
$person:Person(age > 30, username == name)
end
kie使用query得到满足条件的集合
@Test
public void testPerson() {
// 获取services
KieServices kieServices = KieServices.Factory.get();
// 获取container
KieContainer container = kieServices.getKieClasspathContainer();
// 获取session
KieSession kieSession = container.newKieSession();
Person p1 = new Person();
p1.setAge(33);
p1.setName("zhang san");
Person p2 = new Person();
p2.setAge(40);
p2.setName("li san");
kieSession.insert(p1);
kieSession.insert(p2);
// 执行查询
QueryResults query1 = kieSession.getQueryResults("query_1");
Iterator<QueryResultsRow> iterator = query1.iterator();
System.out.println("符合query-1查询结果如下:");
while (iterator.hasNext()) {
QueryResultsRow row = iterator.next();
Person person = (Person) row.get("$person");
System.out.println(person.getName());
}
QueryResults query2 = kieSession.getQueryResults("query_2", "li san");
Iterator<QueryResultsRow> iterator2 = query2.iterator();
System.out.println("符合query-2查询结果如下:");
while (iterator2.hasNext()) {
QueryResultsRow row = iterator2.next();
Person person = (Person) row.get("$person");
System.out.println(person.getName());
}
kieSession.dispose();
}
输出结果:
符合query-1查询结果如下:
zhang san
li san
符合query-2查询结果如下:
li san
在rule中使用query
rule "user query"
when
$person:Person(age > 30)
query_2("li san";)
then
System.out.println("在rule中使用query");
end
declare
declare 声明一个新类型,你所做的事是使用关键字 declare,紧接着是字段列表,和关键字 end
和java的定义类使用方法类似,且可以使用extends实现继承。
可以定义新类型(类似java的class)
也可以定义元数据
直接使用官网例子,实际使用中,不多用
declare Person
name : String
dateOfBirth : java.util.Date
address : Address
end
rule "Using a declared type"
when
$p : Person( name == "James" )
then // Insert Mark, who is a customer of James.
Person mark = new Person();
mark.setName( "Mark" );
insert( mark );
end
rule相关
鉴于篇幅问题,关于这部分,需要另起文章来总结了。