Drools入门之规则模板
规则引擎中,Drools提供了一个规则模板的概念,规则模板是指规则条件比较值是可变的,且可生成多个规则进行规则调用。规则模板可以分为两种:官方提到的以drt扩展名+xls(源数据)的方式和API模板赋值方式。
drt扩展名+xls方式
首选创建一个ExampleCheese.xls文件,其内容如下:
新建Cheese.drt,其内容如下:
template header
age
className
package rules.isDrt
import com.domain.Person
template "cheesefans"
rule "cheese fans_@{row.rowNumber}"
no-loop true
when
$p:Person(age==@{age})
then
$p.setClassName("@{className}");
update($p);
System.out.println($p);
end
end template
修改kmodule.xml配置文件
<kbase name="drt" packages="rules.isDrt">
<ruleTemplate dtable="rules/isDrt/ExampleCheese.xlsx" template="rules/isDrt/Cheese.drt" row="2" col="1"/>
<ksession name="testDrt"/>
</kbase>
创建测试方法:
@Test
public void testDrt() {
KieServices kieService = KieServices.Factory.get();
KieContainer kieContainer = kieService.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("testDrt");
Person person = new Person();
person.setName("张三");
person.setAge(30);
kieSession.insert(person);
kieSession.fireAllRules();
kieSession.dispose();
}
规则模板文件以template header开头,以end template结尾。
然后其中:age,className代表的是xls中的列映射名称。如第一列映射的名称为age。
template “cheesefans””为模板名称,是唯一的,关键字template表示一个规则模板的开始,一个规则模板中可以有多个模板。
@{row.rowNumber}”是模板中的一个函数,用来让规则名唯一。
“@{age}”““@{className}””是对应age、className的,是最终获取数据源中参数值的。
其中@{className}加了引号,是因为setClassName()方法需要的类型为字符串。
Kmodule.xml文件中,row/col开始的行、列起,每一行都是一条规则。row=2,相当于从第二行开始读取数据。
API方式
@Test
public void testIsDRTAPI() {
ObjectDataCompiler converter = new ObjectDataCompiler();
//赋值 给模板属性
Person person = new Person();
person.setAge(50);
person.setClassName("一班");
Collection<Person> cfl = new ArrayList<Person>();
cfl.add(person);//每add一次,就代码一条规则
InputStream dis = null;
try {
dis = ResourceFactory.newClassPathResource("rules/isDrt/Cheese.drt", this.getClass()).getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
String drl = converter.compile(cfl, dis);
System.out.println(drl);
KieHelper helper = new KieHelper();
helper.addContent(drl, ResourceType.DRL);
KieSession ksession = helper.build().newKieSession();
Person ps = new Person();
ps.setAge(50);
person.setName("张三");
ksession.insert(ps);
int i = ksession.fireAllRules();
System.out.println(ps.getClassName() + " " + i + "次");
ksession.dispose();
}
运行结果
package rules.isDrt
import com.domain.Person
rule "cheese fans_0"
no-loop true
when
$p:Person(age==50)
then
$p.setClassName("一班");
update($p);
System.out.println($p);
end
2022-43-27 03:43:26 [INFO ] org.drools.....KieRepositoryImpl - KieModule was added: MemoryKieModule[releaseId=org.default:artifact:1.0.0]
Person{age=50, name='null', className='一班'}
一班 1次
通过这种API的方式,可以对代码进行一个封装。
ObjectDataCompiler:调用规则模板的一个工具类。
Collection
ResourceFactory:加载规则模板文件。converter.compile(cfl, dis):把规则文件与参数合并,生成drl文件。
Drools入门之规则模板
https://www.zhaojun.inkhttps://www.zhaojun.ink/archives/drools-rule-template