Drools 规则引擎

  1. 官网:https://www.drools.org/

  2. 累了听听歌:http://www.hy57.com/p/158102.html


1. 快速度入门

1. 导入依赖

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <!--drools规则引擎-->
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-core</artifactId>
            <version>7.6.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-compiler</artifactId>
            <version>7.6.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-templates</artifactId>
            <version>7.6.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.kie</groupId>
            <artifactId>kie-api</artifactId>
            <version>7.6.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.kie</groupId>
            <artifactId>kie-spring</artifactId>
            <version>7.6.0.Final</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>



        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

2. 创建实体类Ord

package com.dxw.pojo;

public class Ord {
    public int getAmout() {
        return amout;
    }

    @Override
    public String toString() {
        return "Ord{" +
                "amout=" + amout +
                ", score=" + score +
                '}';
    }

    public void setAmout(int amout) {
        this.amout = amout;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    private int amout;
    private int score;

}

3. resources文件下创建 META-INF and rules文件夹

1.META-INF文件夹

  1. 下面创建 kmodule.xml 文件

  2. kmodule.xml配置如下

 <?xml version="1.0" encoding="UTF-8" ?>
<kmodule xmlns="http://www.drools.org/xsd/kmodule">​    
<kbase name="myKbase1" packages="rules" declarativeAgenda="true">        
<ksession name="ksession-rele" default="true"/>    
</kbase>​
</kmodule>

3. rules 文件夹

  1. 创建 score-relus.drl 文件

  2. score-relus.drl配置如下(业务实际需求)

 @Test
    public void tet(){
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieClasspathContainer.newKieSession();

        Ord ord = new Ord();
        ord.setAmout(12);
        kieSession.insert(ord);

        kieSession.fireAllRules();

        kieSession.dispose();

        System.out.println(ord.getScore());
    }

2. 整合spring-boot

1. config配置类 ( 固定写法 )

package com.example.demo.drools.config;

import org.kie.api.KieBase;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieRepository;
import org.kie.api.runtime.KieContainer;
import org.kie.internal.io.ResourceFactory;
import org.kie.spring.KModuleBeanFactoryPostProcessor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.Resource;
import java.io.IOException;


import java.io.IOException;

@Configuration
public class DroolsConfig {
    //指定规则⽂件存放的⽬录
    private static final String RULES_PATH = "rules/";
    private final KieServices kieServices = KieServices.Factory.get();

    @Bean
    @ConditionalOnMissingBean
    public KieFileSystem kieFileSystem() throws IOException {
        //设置规则启动时间
        System.setProperty("drools.dateformat","yyyy-MM-dd");
        KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        Resource[] files = resourcePatternResolver.getResources("classpath*:" + RULES_PATH + "*.*");
        String path = null;
        for (Resource file : files) {
            path = RULES_PATH + file.getFilename();
            kieFileSystem.write(ResourceFactory.newClassPathResource(path, "UTF-8"));
        }
        return kieFileSystem;
    }

    @Bean
    @ConditionalOnMissingBean
    public KieContainer kieContainer() throws IOException {
        KieRepository kieRepository = kieServices.getRepository();
        kieRepository.addKieModule(kieRepository::getDefaultReleaseId);
        KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem());
        kieBuilder.buildAll();
        return kieServices.newKieContainer(kieRepository.getDefaultReleaseId());
    }

    @Bean
    @ConditionalOnMissingBean
    public KieBase kieBase() throws IOException {
        return kieContainer().getKieBase();
    }

    @Bean
    @ConditionalOnMissingBean
    public KModuleBeanFactoryPostProcessor kiePostProcessor() {
        return new KModuleBeanFactoryPostProcessor();
    }
}

2. 实体类

package com.example.demo.pojo;

public class Order {

    private int amout;
    private int score;

    public int getAmout() {
        return amout;
    }

    public void setAmout(int amout) {
        this.amout = amout;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }
}

3. 控制器

package com.example.demo.controller;

import com.example.demo.pojo.Order;
import com.example.demo.service.RuleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class OrderController {
    @Autowired
    private RuleService ruleService;

    @GetMapping("/saveOrder")
    public Order saveOrder(Order order) {
        System.out.println("hello,world");
        return ruleService.executeOrderRule(order);
    }
}

4. service层

package com.example.demo.service;​import com.example.demo.pojo.Order;import org.kie.api.KieBase;import org.kie.api.runtime.KieSession;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;
​@Servicepublic 
class RuleService {​    
@Autowired    
private KieBase kieBase;​   
 /*** 执⾏订单⾦额积分规则 */    
public Order executeOrderRule(Order order) {        
KieSession kieSession = kieBase.newKieSession();       
 kieSession.insert(order);       
 kieSession.fireAllRules();        
kieSession.dispose();        
return order;    
}}

5. resources 文件

  1. 创建droolsd包

    1. score-rules.drl文件

package rules
import com.example.demo.pojo.Order

//规则1:100元以下, 不加分
rule "score_1"
when
    $s : Order(amout <= 100)
then
    $s.setScore(0);
    System.out.println("成功匹配到规则1:100元以下, 不加分 ");
end

//规则2:100元-500元 加100分
rule "score_2"
when
    $s : Order(amout > 100 && amout <= 500)
then
    $s.setScore(100);
    System.out.println("成功匹配到规则2:100元-500元 加100分 ");
end

//规则3:500元-1000元 加500分
rule "score_3"
when
    $s : Order(amout > 500 && amout <= 1000)
then
    $s.setScore(500);
    System.out.println("成功匹配到规则3:500元-1000元 加500分 ");
end

//规则4:1000元 以上 加1000分
rule "score_4"
when
    $s : Order(amout > 1000)
then
    $s.setScore(1000);
    System.out.println("成功匹配到规则4:1000元 以上 加1000分 ");
en

static 创建 order.html

<!DOCTYPE >
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>订单⻚⾯</title>
    <script type="text/javascript" src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <style> div {
        margin: auto;
        width: 500px;
    }

    #score {
        color: red;
        font-size: 14px;
    } </style>
</head>
<body>
<div>
    <table>
        <tr>
            <td>订单⾦额:</td>
            <td><input type="text" id="amout" name="amout"/></td>
        </tr>
        <tr>
            <td>该订单可以累计的积分:</td>
            <td><span id="score"></span></td>
        </tr>
    </table>
</div>
</body>
<script type="text/javascript">
    $(function () {
        $("#amout").blur(function () {
            $.ajax({
                url: "/saveOrder",
                type: "get",
                data: {"amout": $("#amout").val()},
                dataType: "json",
                success: function (data) {
                    //设置积分
                    $("#score").html(data.score);
                }
            });
        });
    });
</script>
</html>

3. Drools 实战(计算所得税)

创建 Calculation 类并且提供getset方法

public class Calculation {
    private double wage; //税前工资
    private double wagemore; //应纳税所得额
    private double cess;  //税率
    private double preminus; //速算解扣除数
    private double wageminus;  //扣税额
 }

编写 calculation.drl 规则文件

package rulesimport com.example.demo.pojo.Calculation
​​rule "计算应纳税所得额"     //优先级    salience 10    //设置规则启动时间    date-effective "2022-10-21"    //防止死循环    no-loop true    when       $cal: Calculation(wage > 0)    then       double wagemore = $cal.getWage() - 3500;       //赋值       $cal.setWagemore(wagemore);       update($cal)end​​

rule "设置税率,速算扣除数 >1500 and <=4500"    
salience 9    no-loop true    //方法不重复触发    
activation-group "SETCess_Group"   
 when        
$cal:Calculation(wagemore > 1500 && wagemore<=5400)    
then       
 $cal.setCess(0.1); //税率       
 $cal.setPreminus(105);    //速算扣除数        update($cal);end


​​rule "设置税率,速算扣除数 >4500 and <=10000"    
salience 9    no-loop true    activation-group "SETCess_Group"    
when        $cal:Calculation(wagemore > 4500 && wagemore<=10000)   
 then        $cal.setCess(0.2); //税率       
 $cal.setPreminus(305);    //速算扣除数      
  update($cal);end​​


rule "个人所得税:计算税后工资"    
salience 1    
when       
 $cal:Calculation(wage > 0 && wagemore > 0 && cess > 0)   
 then        
double wageminus = $cal.getWagemore() * $cal.getCess() - $cal.getPreminus();        double actualwage = $cal.getWage() -wageminus;       
 $cal.setWagemore(wageminus);        
$cal.setActualwage(actualwage);       
 System.out.println("税前工资"+$cal.getWage());      
  System.out.println("应纳税所得额"+$cal.getWagemore());       
 System.out.println("税率"+$cal.getCess());       
 System.out.println("速算扣除数"+$cal.getPreminus());       
 System.out.println("税后工资"+$cal.getActualwage());end

RuleService 层

@Autowired
    private KieBase kieBase;
    
        public Calculation calculation(Calculation calculation) {
        KieSession kieSession = kieBase.newKieSession();
        kieSession.insert(calculation);
        kieSession.fireAllRules();
        kieSession.dispose();
        return calculation;
    }

OrderController 类

 @RequestMapping("/calculate")
    public Calculation calculation(double wage){
        Calculation calculation  = new Calculation();
        calculation.setWage(wage);
        Calculation calculation1 = ruleService.calculation(calculation);
        return calculation1;
    }

最后,自己传入参数测试!!!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值