栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Drools使用心得

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Drools使用心得

目录

一、前言

二、结构

三、代码摘要

1.kmodule.xml

2.rule.drl

3.Java调用

三、个人心得


一、前言

Drools规则引擎,在项目中有用到,但并未使用其后续可视化WorkBench。

在此仅记录个人的一些使用心得。

二、结构

在初步版本以及测试学习版本中,比较简要的搭建了Springboot+Drools规则引擎项目。其项目结构如图所示:

在resources目录下创建meta-INF目录,并创建kmodule.xml文件;创建rules目录,并创建XXX.drl规则文件即可。

三、代码摘要

1.kmodule.xml


    
    
        
        
    

    
        
    

关于其中一些针对性内容,已经在代码段的注释中表达,此处不再赘述,下面简要记录一下个人使用心得。

在实际的项目开发中,ksession是可以通过代码直接指定的,例如:

Kiebase kiebase = kieContainer.getKiebase("Kiebase-name");

KieSession kSession = kContainer.newKieSession("ksession-rules");

但实际在简单的调用规则时,是不需要指定名称的。

2.rule.drl

这可以说是规则中的核心部分,一个简单的规则示例:

package rules.special.company

import java.util.Arrays;
import java.util.Map;
import com.csf.ib.rules.entity.RuleContext
import java.util.HashMap

function String getSpecialCompany(RuleContext r){
    if(r.getInitVariableMap().containsKey("code")){
        String code = r.getInitVariableMap().get("ticker").toString();
        return code;
    }else {
        return "";
    }
}

function String getSpecialCompanyName(RuleContext r){
    if(r.getInitVariableMap().containsKey("company_name")){
        String code = r.getInitVariableMap().get("company_name").toString();
        return code;
    }else {
        return "";
    }
}

rule "checkSpecialCompany"
    when
        $ruleContext:RuleContext();
        Object(getSpecialCompany($ruleContext) memberOf (Arrays.asList("601288","601988","601939","601398")))
    then
        $ruleContext.getResultMap().put("company_name",getSpecialCompanyName($ruleContext));
        $ruleContext.getResultMap().put("company_id",$ruleContext.getInitVariableMap().get("company_id").toString());
        $ruleContext.getResultMap().put("ruleResult","1");
        $ruleContext.getRuntimeVariableMap().put("company_name",getSpecialCompanyName($ruleContext));
        $ruleContext.getRuntimeVariableMap().put("company_id",$ruleContext.getInitVariableMap().get("company_id").toString());
        $ruleContext.getLogger().info("执行了checkSpecialCompany规则");
    end

package:必须存在的包名,是属于逻辑上的管理,不管其物理位置(甚至是从数据库中读取,当然需要额外的构建,后面会写到)位于何处,都能调用。

import:导入类。

globals:全局变量,需要在Java调用规则处声明才可使用,示例中未使用。

function:函数,类同于Java代码。

rule:规则,可以存在多个。

在示例中可以看到,我引入了一个外部实体类,通过读取实体类中的属性,在function中进行处理,得到结果后,在规则中进行处理,最后通过log输出。在实体类中实例化过的log可以在此处直接调用。

规则的必要结构包括:

rule "name"

when

then

end

其中name,是唯一值,指代这个规则的名称。

rule与when之间,可以添加各种属性,例如:activation-group,salience等(相关文档还是有的,不再赘述)

when,即所谓的LHS,Left Hand Side,是指判断条件,例如1==1。

then,即所谓的RHS,RightHand Side,是指条件满足时的执行。

end,即规则结束。

LHS中关键字示例:

contains| not contains:Object( field[Collection/Array] contains value),指一个集合中是否包含某属性/实例。

memberOf | not memberOf:Object(fieldName memberOf value[Collection/Array]),指某属性是否存在于某集合。

matches | not matches:Object(fieldName matches “正则表达式”),matches 是用来对某个 Fact 的字段与标准的 Java 正则表达式进行相似匹配, 被比较的字符串可以是一个标准的 Java 正则表达式(正则表达式字符串当中不用考虑“”的转义问题)。

3.Java调用
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieContainer.newKieSession();
        list.add("123");
        list.add("123");
        list.add("123");
        list.add("123");
        kieSession.setGlobal("list",list);
        FactHandle insert = kieSession.insert(object);
        int count = kieSession.fireAllRules();
        System.out.println("总执行了" + count + "条规则");
        kieSession.dispose();

这可以说是极为简单的调用了,其中原理在各类文档中皆有详细描述。

但如果规则是从数据库中读取的话,此处的调用示例如下:

    public boolean process() {
        KieSession kSession = null;
        try {
            KnowledgeBuilder kb = KnowledgeBuilderFactory.newKnowledgeBuilder();
            kb.add(ResourceFactory.newByteArrayResource(ruleContext.getRuleDef().getRuleContent().getBytes(StandardCharsets.UTF_8)), ResourceType.DRL);

            // 检查规则正确性
            KnowledgeBuilderErrors errors = kb.getErrors();
            if (errors.size() > 0) {
                for (KnowledgeBuilderError error : errors) {
                    log.error("规则文件正确性有误:{}", error);
                }
                return false;
            }
            InternalKnowledgebase kbase = KnowledgebaseFactory.newKnowledgebase();
            kbase.addPackages(kb.getKnowledgePackages());

            // 执行规则
            kSession = kbase.newKieSession();

            kSession.insert(ruleContext);
            kSession.fireAllRules();
        } catch (Exception e) {
            log.error("规则执行异常", e);
            return false;
        } finally {
            if (null != kSession)
                kSession.dispose();
        }
        return true;

    }

三、个人心得

受限于时间以及资料,个人在项目中所使用的Drools仅仅是很少的一部分内容,同时也由于网上所搜寻的资料参差不齐,也很难在有限的时间内做出完美的项目,但也在努力的学习中,本文也仅限于快速构建一个Drools项目罢了。虽然网络上各种相关资料不少,但是对于初步构建的内容还是比较欠缺的。

本文仅作参考。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/732680.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号