一、根据数据库存储的内容录入规则
先注入kieSystem
@Autowired
private KieFileSystem kieFileSystem;
// 获取kie服务
KieServices kieServices = KieServices.Factory.get();
// 获取规则
List<Rule> listRule = ruleDao.getRule();
// 获取规则依赖,就是import、global什么的
String importsString = ruleDao.getImports();
// 拼接
StringBuffer buffer=new StringBuffer();
buffer.append(importsString);
// for循环把规则都放进去
for(int i=0;i<listRule.size();++i){
buffer.append(listRule.get(i).getContent());
}
// 生成文件
/**
DROOLS_RULE_PATH是生成的drl文件的存储位置,一般可以设置为src/resource/rule,
Namespace是分组名
DROOLS_RULE_SUFFIX_NAME是后缀,.drl
buffer.toString()就是内容
*/
kieFileSystem.write(DROOLS_RULE_PATH+Namespace+DROOLS_RULE_SUFFIX_NAME, buffer.toString());
// 放入内存
try {
logger.info("规则kieServices.newKieBuilder(kieFileSystem).buildAll()开始");
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem).buildAll();
logger.info("规则kieServices.newKieBuilder(kieFileSystem).buildAll()结束");
logger.info("获取规则构建结果开始");
Results results = kieBuilder.getResults();
logger.info("获取规则构建结果结束");
if (results.hasMessages(Message.Level.ERROR)) {
logger.info("结果信息:" + results.getMessages());
throw new IllegalStateException("### errors ###");
}
logger.info("规则setKieContainer开始");
KieUtils.setKieContainer(kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId()));
} catch (Exception e) {
logger.error("加载失败,原因:",e);
}
二、语法细节
总结了一下常用的几个方法
- 判断是否存在有某个字段某种对象:
myObject:MyObject() attr:Attr() from myObject.Attr
,用于判断当前传进来的对象MyObject()是否包含Attr()这个对象 - 判断这个对象是否值为某个指定值:
Attr(attrCode="123") from attr
,判断attr的attrCode是否等于"123" - 对象的某个字段为集合,判断这个集合中是否存在包含某个值的对象:
exists(MianDto(mainCode=="66005") from myObject.mianDtoList )
- 对象的某个字段为集合,判断这个集合中是否每一个对象都不包含某个值:
MyObject($li:mainDtoList) forall(MainDto(mainCode!="11010000") from $li)
注意:直接把集合赋值给$li是行不通的,因为drools拿不到那块内存,只有在对象内部以属性赋值的方式才能把作为属性的集合赋值给变量$li
以后想起来再补充
---------------2020-10-19更新-----------------
三、多重遍历
有时候list里面的对象的某个字段还是list,需要复合遍历,而且这种遍历还需要满足某种约束条件来检索指定的某个对象的list字段,如何处理?
- 第一层,从对象中拿出第一层list:testObject($li:ObjList),其中ObjList是testObject这个对象的list字段;
- 第二层,按照某种约束条件拿出下一层list,ObjList(name=“xu”,$li2:nextObjList) from $li,这是把ObjList这个对象中name字段为xu的对象的下一级list拿出来,赋值给$li2
- 对$li2进行遍历并进行某种操作,例如forall:forall(FinalObj(age!=10) from $li2)
---------------2022-06-11更新-----------------
四、引入外部函数
有时候想要动态生成复杂的drools规则太过麻烦,不妨试试引入java的static方法来处理。
第一步
public void static handleMap(Hashmap map, String key, String oldVal, String newVal) {
if(map.containsKey(key)) {
map.set(key, ((String)map.get(key)).replace(oldVal, newVal));
}
}
第二步
在动态生成规则时引入该函数,假定这个方法在类DroolsClass中:
import com.test.drools.DroolsClass.handleMap
这个方法就可以在then到end的结构中使用