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文件夹
-
下面创建 kmodule.xml 文件
-
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 文件夹
-
创建 score-relus.drl 文件
-
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 文件
-
创建droolsd包
-
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;
}
最后,自己传入参数测试!!!