drools规则引擎

1 单个文件

这个大多搜索导的都是把规则放到一个文件,这个是基础,但是实际应用就不太方便。如果你使用的jdk1.8,那么对应的drools版本为7.x

1.1 pom依赖

 <drools.version>7.74.1.Final</drools.version>  
<dependency><groupId>org.drools</groupId><artifactId>drools-core</artifactId><version>${drools.version}</version> <!-- 请根据需要选择合适的版本 --></dependency><dependency><groupId>org.drools</groupId><artifactId>drools-compiler</artifactId><version>${drools.version}</version></dependency><dependency><groupId>org.drools</groupId><artifactId>drools-decisiontables</artifactId><version>${drools.version}</version></dependency><dependency><groupId>org.drools</groupId><artifactId>drools-mvel</artifactId><version>${drools.version}</version></dependency>

1.2 droolsconfig

import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieModule;
import org.kie.api.runtime.KieContainer;
import org.kie.internal.io.ResourceFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class DroolsConfig {@Beanpublic KieContainer  initKieContainer() {KieServices kieServices = KieServices.Factory.get();KieFileSystem kieFileSystem = kieServices.newKieFileSystem();kieFileSystem.write(ResourceFactory.newClassPathResource("rules/gszy.drl"));KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);kieBuilder.buildAll();KieModule kieModule = kieBuilder.getKieModule();return kieServices.newKieContainer(kieModule.getReleaseId());}}

1.3 controller层

注意下面请求和响应返回值是分开的

    @Autowiredprivate KieContainer kisContainer;@PostMapping("gszy")public ResponseResult<GszyRespDto> gszy(@RequestBody GszyReqDto req){GszyRespDto gszyRespDto = new GszyRespDto();KieSession kieSession = kisContainer.newKieSession();kieSession.insert(req);kieSession.insert(gszyRespDto);kieSession.fireAllRules();kieSession.dispose();//ResponseResult<GszyRespDto> resp = new ResponseResult<>(true);resp.setData(gszyRespDto);return resp;}

1.4 drl文件

在idea中下载jboss插件,安装drools插件。

  这里讲请求和响应参数分开,drl中用的java语言,可以自定义function。从下面来看可以写的比较复杂的业务逻辑。

package   com.mms.rules;
import com.dzmsoft.acc.mms.rules.dto.req.GszyReqDto;
import com.dzmsoft.acc.mms.rules.dto.resp.GszyRespDto;rule "验证输入"when$req : GszyReqDto(dzsr == 0.0)thenthrow new IllegalArgumentException("请输入年收入总额");
endrule "检查总收入是否足以支付社保和公积金"when$req : GszyReqDto(dzsr < (dsb * 12.0 + dgjj * 12.0))thenthrow new IllegalArgumentException("总收入不足以负担社保和公积金");
endrule "规则1"when$req : GszyReqDto()$res : GszyRespDto()$dzsr : Double() from $req.getDzsr()$dsb : Double() from $req.getDsb()$dgjj : Double() from $req.getDgjj()$dckx : Double() from $req.getDckx()thendouble dAllCKX = 60000.0 + $dsb * 12.0 + $dgjj * 12.0 + $dckx * 12.0;$res.setDAllCKX(dAllCKX);modify($res) {};
endrule "规则2"when$req : GszyReqDto()$res : GszyRespDto()eval($req.getDzsr() <= $res.getDAllCKX())thendouble dygz = $req.getDzsr() / 12.0;int nygz = (int) dygz;if (nygz % 50 != 0) {nygz += (50 - (nygz % 50));dygz = nygz;}$res.setDygz(dygz);$res.setDnzj(0.0);$res.setDgs(0.0);$res.setDsfl(0.0);$res.setDshsr($req.getDzsr() - ($req.getDsb() + $req.getDgjj()) * 12.0);modify($res) {};
endrule "规则3"when$req : GszyReqDto()$res : GszyRespDto()eval($req.getDzsr() > $res.getDAllCKX())thendouble dygzTemp = $res.getDAllCKX() / 12.0;int nygz = (int) dygzTemp;if (nygz % 50 != 0) {nygz += (50 - (nygz % 50));dygzTemp = nygz;}double dMings = 100000000.0; // 初始设置为一个很大的值double dOptygz = 0.0;while (true) {if (dygzTemp * 12.0 > $req.getDzsr()) {break;}double dgzynssde = dygzTemp * 12.0 - $res.getDAllCKX();double dnzjynssde = $req.getDzsr() - dygzTemp * 12.0;double dgzgs = calGzgs(dgzynssde);double dnzjgs = calNzjgs(dnzjynssde);if (dgzgs + dnzjgs < dMings) {dMings = dgzgs + dnzjgs;dOptygz = dygzTemp;}dygzTemp += 50.0;}$res.setDygz(dOptygz);$res.setDnzj($req.getDzsr() - dOptygz * 12.0);$res.setDgs(dMings);$res.setDsfl(dMings / $req.getDzsr() * 100.0);$res.setDshsr($req.getDzsr() - ($req.getDsb() + $req.getDgjj()) * 12.0 - dMings);modify($res) {};end

2 多个规则文件

2.1 写定路径方式

        可以看到下面的DRL文件,多了一个就写一个,这种方式也可以可以的。

   @Beanpublic KieContainer  initKieContainer() {KieServices kieServices = KieServices.Factory.get();KieFileSystem kieFileSystem = kieServices.newKieFileSystem();// 添加多个 DRL 文件kieFileSystem.write(ResourceFactory.newClassPathResource("rules/gszy.drl"));kieFileSystem.write(ResourceFactory.newClassPathResource("rules/nzjzy.drl"));// 构建 KieModuleKieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);kieBuilder.buildAll();// 检查构建是否有错误if (kieBuilder.getResults().hasMessages(org.kie.api.builder.Message.Level.ERROR)) {throw new RuntimeException("Build Errors:\n" + kieBuilder.getResults().getMessages().toString());}KieModule kieModule = kieBuilder.getKieModule();return kieServices.newKieContainer(kieModule.getReleaseId());}

   但为什么启动会重复,看来规则文件虽然可以拆分,但是规则名称不能重复。

2.2 模糊路径方式

drools本身是不支持的,需要通过java代码来实现,按照相对路径的写法。

 @Beanpublic KieContainer  initKieContainer() {KieServices kieServices = KieServices.Factory.get();KieFileSystem kieFileSystem = kieServices.newKieFileSystem();// 添加多个 DRL 文件// 指定 DRL 文件所在的目录String drlDirectory = "rules";// 获取类路径资源ClassPathResource resource = new ClassPathResource(drlDirectory);// 扫描目录并加载所有 DRL 文件try {File file = resource.getFile();Path directoryPath = file.toPath();// 扫描目录并加载所有 DRL 文件try (Stream<Path> paths = Files.walk(directoryPath)) {List<File> drlFiles = paths.filter(Files::isRegularFile).filter(path -> path.toString().endsWith(".drl")).map(Path::toFile).collect(Collectors.toList());for (File drlFile : drlFiles) {kieFileSystem.write(ResourceFactory.newFileResource(drlFile));}}} catch (IOException e) {throw new RuntimeException("Error loading DRL files from directory: " + drlDirectory, e);}// 构建 KieModuleKieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);kieBuilder.buildAll();// 检查构建是否有错误if (kieBuilder.getResults().hasMessages(org.kie.api.builder.Message.Level.ERROR)) {throw new RuntimeException("Build Errors:\n" + kieBuilder.getResults().getMessages().toString());}KieModule kieModule = kieBuilder.getKieModule();return kieServices.newKieContainer(kieModule.getReleaseId());}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/149802.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

KITTI数据集雷达采样点时间戳属性的思考(Failed to find match for field ‘time‘)

最近在SLAM调研期间&#xff0c;看到了FAST-LIO2以及Point-lio这两个比较新的SLAM建图算法&#xff0c;想着上手编译并且运行一下&#xff0c;选择了自己了解到的比较出名的数据集KITTI&#xff0c;想着在上述两个开源算法上上手跑一下&#xff08;原论文并没有使用KITTI数据集…

大功率400mw蓝光可调激光模组价格多少钱

在现代激光技术的快速发展中&#xff0c;大功率400mw蓝光可调激光模组以其卓越的性能和广泛的应用领域&#xff0c;成为了市场上备受瞩目的产品。那么&#xff0c;这款激光模组的价格究竟是多少呢? 大功率400mw蓝光可调激光模组的价格因品牌、规格、销售渠道及促销活动等因素而…

【Python报错已解决】TypeError: forward() got an unexpected keyword argument ‘labels‘

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 专栏介绍 在软件开发和日常使用中&#xff0c;BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

【机器学习】决策树算法

目录 算法引入 基尼系数&#xff1a; 决策树算法概述 决策树的关键概念 决策树的构建 代码实现 1. 定义决策树节点 2. 计算信息增益 3. 选择最佳分割特征 4. 构建决策树 5. 决策树预测 决策树的评估指标&#xff1a; 决策树的优缺点 优点&#xff1a; 缺点&…

Github优质项目推荐-第一期

文章目录 Github优质项目推荐一、【free-for-dev】&#xff0c;88.4k stars二、【linux-command】&#xff0c;31.5k stars三、【system-design-primer】&#xff0c;270k stars四、【GitHub-Chinese-Top-Charts】&#xff0c;99.1k stars五、【Docker-OSX】&#xff0c;46k st…

汇智生物---农业与植物基因组分析专家

1.博导团队免费指导设计 2.博导团队免费解读实验结果 3.实验整体!打包服务 4.实验整体!打包服务 表观组 互作组 DNA亲和纯化测序 DNA亲和纯化测序技术通过体外表达转录因子鉴定转录因子结合位点&#xff0c;不受抗体和物种限制&#xff0c;且具有高通量的优势。DAP-Seq将蛋…

鸿萌数据恢复:NAND 内存协议,SDR 与 DDR 之间的区别

天津鸿萌科贸发展有限公司从事数据安全服务二十余年&#xff0c;致力于为各领域客户提供专业的数据恢复、数据备份解决方案与服务&#xff0c;并针对企业面临的数据安全风险&#xff0c;提供专业的相关数据安全培训。 从事 NAND 数据恢复的人都知道&#xff0c;读取 NAND 需要使…

不可错过的10款文件加密软件,2024最新文件加密软件排行榜

在数字化时代&#xff0c;数据安全变得尤为重要。无论是个人用户还是企业组织&#xff0c;保护敏感文件和数据免受未经授权的访问是至关重要的。文件加密软件通过将文件内容转换为不可读的格式&#xff0c;确保只有授权用户才能解密和访问数据。本文将为您介绍2024年不可错过的…

828华为云征文 | 在华为云上通过Docker容器部署Elasticsearch并进行性能评测

目录 前言 1. 华为云X实例介绍及优势 1.1 柔性算力 1.2 vCPU和内存的灵活配比 1.3 成本效益与性能 2. 安装并运行 Docker 2.1 修改仓库配置文件 2.2 安装 Docker 2.3 启动 Docker 3. 使用Docker部署Elasticsearch 3.1 拉取Elasticsearch镜像 3.2 启动Elasticsearch…

数据结构算法题

目录 轮转数组原地移除数组中所有元素val删除有序数组中的重复项合并两个有序数组 轮转数组 思路1&#xff1a; 1.利用循环将最后一位数据放到临时变量&#xff08;n&#xff09;中 2.利用第二层循环将数据往后移一位 3.将变量&#xff08;n&#xff09;的数据放到数组第一位 时…

React 启动时webpack版本冲突报错

报错信息&#xff1a; 解决办法&#xff1a; 找到全局webpack的安装路径并cmd 删除全局webpack 安装所需要的版本

SOMEIP_ETS_128: SD_Multicast_FindService_Major_Minor_Version_set_to_all

测试目的&#xff1a; 验证DUT能够对设置了主版本号和次版本号为0xFF的多播FindService请求做出响应&#xff0c;并为每个请求至少回复一个单播OfferService消息。 描述 本测试用例旨在确保DUT能够正确处理多播FindService请求&#xff0c;特别是当请求中的主版本号和次版本…

使用Adobe XD进行制作SVG字体

制作SVG字体的办法有很多&#xff0c;我这里选择了Adobe XD进行制作。 1.选择画布尺寸 2 输入文本 设置字体样式 3 设置画布背景 4 转换字体&#xff08;物件&#xff09;路径 5 设置组 复制SVG代码 6 放入到Html中 <!DOCTYPE html> <html lang"zh">&l…

超级干货,OSPF协议无敌详解

号主&#xff1a;老杨丨11年资深网络工程师&#xff0c;更多网工提升干货&#xff0c;请关注公众号&#xff1a;网络工程师俱乐部 下午好&#xff0c;我的网工朋友。 大家都知道&#xff0c;为了实现高效的数据传输和网络资源利用&#xff0c;路由协议的选择可以说是非常重要的…

面经 | ES6

ES6 ES6set vs weakSetmap vs weakMapPromise创建三个状态 ES6 set vs weakSet 都是集合&#xff0c;只不过weakSet里面只能存引用类型的变量。weakSet相对set的好处就是&#xff0c;可以避免内存泄漏。因为weakSet中的成员&#xff0c;如果在外部消失了&#xff0c;会自动消…

问题:vscode 打印中文时终端输出乱码

文章目录 问题分析解决 问题 在 vscode 编辑器中的终端运行出来的中文是乱码 分析 乱码原因&#xff1a;因windows中文版系统cmd编码默认为GBK&#xff0c;而vscode默认新建文件的编码为UTF-8所以会出现中文乱码情况 解决 终端下输入 chcp 查看当前的cmd编码设置。如图&…

【LeetCode】动态规划—打家劫舍(附完整Python/C++代码)

动态规划—#198. 打家劫舍 前言题目描述基本思路1. 问题定义:2. 理解问题和递推关系:3. 解决方法:4. 进一步优化:5. 小总结: 代码实现Python3代码实现Python 代码解释C代码实现C 代码解释 总结: 前言 在这个问题中&#xff0c;你是一个专业的小偷&#xff0c;计划偷窃沿街的房…

9.2 Linux_标准I/O_相关函数

打开与关闭 文件打开就是判断这个文件资源可不可以被占用&#xff0c;如果可以&#xff0c;就能够打开成功&#xff0c;否则打开失败 文件关闭就是释放文件资源 1、打开文件 1.1 函数声明 FILE *fopen(const char *pathname, const char *mode); 返回值&#xff1a;出错返…

排序算法Java实现

文章目录 排序算法概述比较排序算法非比较排序算法稳定 vs 不稳定Java 中的排序 外部排序1) 冒泡排序2) 选择排序3) 堆排序4) 插入排序5) 希尔排序6) 归并排序递归实现时间复杂度非递归实现 7) 归并插入8) 快速排序随机基准点处理重复值 9) 计数排序10) 桶排序11) 基数排序 排序…

Redmi Note 7 Pro(violet)免授权9008文件分享及刷机教程

获取文件 关注微信公众号 heStudio Community回复 violet_9008 获取下载链接。 刷机教程 下载搞机助手&#xff08;可以从上方文件中获取&#xff09;并安装。手机按音量减键和电源键进入 Fastboot 模式&#xff0c; 打开搞机助手&#xff0c;点击进入 9008 模式 等待手机…