使用drools-7.73.0.Final实现规则匹配的简单案例

1、案例业务规则说明

在一般的商城系统中,订单收到货签收完成后可以参与评价订单,商城会针对好评赠送相应的积分。

如可以定义金牌、银牌、铜牌会员,分别评论商品的字数多少,是否上传实物拍照,给予多少颗星的评价等多个维度判断给用户赠送合适的积分。

假定一个评论送积分的规则如下

会员级别 级别码 3星 4星 5星
金牌 30 100积分 300积分 500积分
银牌 20 50积分 250积分 400积分
铜牌 10 30积分 200积分 300积分
2、案例演示代码

使用spring-boot:2.7.2+drools-7.73.0.Final完成演示

  • 2.1、配置文件pom.xml文件中drools依赖包内容如下
<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-core</artifactId>
    <version>7.73.0.Final</version>
</dependency>

<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-compiler</artifactId>
    <version>7.73.0.Final</version>
</dependency>

<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-mvel</artifactId>
    <version>7.73.0.Final</version>
</dependency>
  • 2.2、新建配置文件kmodule.xml(在目录resources/META-INF/kmodule.xml)
<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
    <kbase name="kbase" packages="rules" default="true">
        <ksession name="ksession-rule" default="true"/>
    </kbase>
</kmodule>

此文件默认定义,可以不修改

  • 2.3、编写规则文件comment_score.drl(在目录resources/rules/comment_score.drl)
package rules;
import com.mixfate.drools.model.Comment

rule "comment_score_30_5"
    when
        $comment: Comment(account.level==30 && star==5)
    then
        $comment.setScore(500);
end

rule "comment_score_30_4"
    when
        $comment: Comment(account.level==30 && star==4)
    then
        $comment.setScore(300);
end

rule "comment_score_30_3"
    when
        $comment: Comment(account.level==30 && star==3)
    then
        $comment.setScore(100);
end

注意:规则文件是以drl为后缀命名的,为了在项目中清晰地区分各种业务规则,最好是遵循一定的规范定义规则,不然到后期会非常混乱。规则匹配成功时将setScore设置积分数量。

  • 2.3、编写Java代码
DroolsApplication.java
------
package com.mixfate.drools;

import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class DroolsApplication {

    public static void main(String[] args) {
        SpringApplication.run(DroolsApplication.class, args);
    }

    @Bean
    public KieContainer kieContainer() {
        KieServices service = KieServices.Factory.get();
        return service.newKieClasspathContainer();
    }

}

Comment.java
------
package com.mixfate.drools.model;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Comment {

    private int star;

    private Account account;

    private int score;

}


Account.java
------
package com.mixfate.drools.model;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Account {

    private int level;

}

代码非常简单,定义一个Comment对象,里面包含了账号信息、评论的星数及赠送的积分信息。

  • 2.4、编写Java测试代码
@Autowired
private KieContainer kieContainer;

@Test
public void comment() {
    KieSession kieSession = kieContainer.newKieSession();
    Comment comment = new Comment();
    Account account = new Account();
    account.setLevel(30);
    comment.setStar(new Random().nextInt(3) + 3);
    comment.setAccount(account);

    System.out.println(JSON.toJSONString(comment));
    // 插入comment
    kieSession.insert(comment);
    kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("comment_score"));

    //清除会话
    kieSession.dispose();
    System.out.println(JSON.toJSONString(comment));
}

在测试代码中使用newKieSession创建新的session,注意在使用完成后需要使用dispose方法将session清除。在fireAllRules时传入一个规则的前缀,可以按这个规范将同一个规则文件内的规则命名成相同的前缀,通过此过滤器限定规则的范围。


赞赏(Donation)
微信(Wechat Pay)

donation-wechatpay