网站首页 > 技术文章 正文
一、背景
在我们编写drl规则的时候,有些时候需要自己声明一些类,用于辅助之后的规则运行,如果需要用到的类还需要在java中预先声明出来,这样就不灵活了,那么是否可以在drl文件中声明一个类呢?可以使用drools的 Type declaration来实现。
二、前置知识
1、Type declaration语法结构
2、java代码中获取drl声明的类型
1、非枚举类型
KieBase kieBase = kieContainer.getKieBase("type-kabse");
// 规则文件的包名 声明的类型名
FactType productOrderFactType = kieBase.getFactType("rules", "ProductOrder");
Object instance = productOrderFactType.newInstance();
productOrderFactType.set(instance, "orderId", 20220517121212001L);
2、获取枚举类型的值
需要通过反射来获取到。
KieBase kieBase = kieContainer.getKieBase("type-kabse");
// 此处的FactType的真实类型是EnumClassDefinition,可以获取到枚举中构造方法的参数的值
FactType orderStatusFactType = kieBase.getFactType("rules", "OrderStatus");
// 获取drools中枚举的值
Class<?> factClass = orderStatusFactType.getFactClass();
Method method = factClass.getMethod("valueOf", String.class);
Object pay = method.invoke(null, "PAY");
注意:
如果上方的代码看不懂,则接着往下看。
三、需求
1、在drl文件中声明一个枚举类型。
2、在drl文件中声明一个类。
3、在drl文件中声明一个类并完成继承操作。
4、编写rule并使用我们自定义的type。
5、java中给在drl文件中声明的type赋值,包括类和枚举类型。
四、实现
1、在drl文件中声明一个枚举类型
// 声明一个枚举类型
declare enum OrderStatus
CREATED(0, "新创建"),
PAY(1, "已支付"),
RECEIVED(2, "已接收");
status: Integer;
desc: String;
end
语法结构: declare enum 枚举名字 end
2、在drl文件中声明一个类
// 声明一个类
declare BaseOrder
orderId: Long // 订单id
createdTime: Date // 时间
item: ProductItem // java中定义的类
orderStatus: OrderStatus // 上方定义的枚举类型
end
这个类中的每个属性都有一个类型,这个类型可以是已经存在的fact,也可以是任何有效的Java类型。
3、在drl文件中声明一个类并完成继承操作
// 实现继承操作
declare ProductOrder extends BaseOrder
userId: Long // 下单用户的id
end
使用extends来完成继承操作。
4、编写rule并使用我们自定义的type
// 定义一个规则,规则内存中存在ProductOrder并且 orderStatus是已支付userId==1001
rule "rule_type"
no-loop true
when
$order: ProductOrder(userId == 1001 && orderStatus == OrderStatus.PAY)
then
String createdTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.format($order.getCreatedTime());
System.out.println("用户["+ $order.getUserId() +"]在["+ createdTime +"]购买的["+ $order.getItem().getItemName() +"]已完成付款");
modify($order){
setOrderStatus(OrderStatus.RECEIVED)
}
end
解释:
1、如果规则内存中存在ProductOrder对象,并且userId的值是1001,orderStatus的值是PAY则该规则被激活了。
2、当该规则激活时,修改订单的状态为RECEIVED,在java代码中获取修改后的值。
5、java中给在drl文件中声明的type赋值
@Slf4j
public class DroolsTypeDeclareApplication {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
KieServices kieServices = KieServices.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession("type-ksession");
kieSession.addEventListener(new DebugRuleRuntimeEventListener());
kieSession.addEventListener(new DebugAgendaEventListener());
kieSession.addEventListener(new DebugProcessEventListener());
KieBase kieBase = kieContainer.getKieBase("type-kabse");
FactType productOrderFactType = kieBase.getFactType("rules", "ProductOrder");
FactType orderStatusFactType = kieBase.getFactType("rules", "OrderStatus");
// 获取drools中枚举的值
Class<?> factClass = orderStatusFactType.getFactClass();
Method method = factClass.getMethod("valueOf", String.class);
Object pay = method.invoke(null, "PAY");
Object instance = productOrderFactType.newInstance();
ProductItem item = new ProductItem();
item.setItemName("iphone 13");
productOrderFactType.set(instance, "orderId", 20220517121212001L);
productOrderFactType.set(instance, "createdTime", new Date());
productOrderFactType.set(instance, "item", item);
productOrderFactType.set(instance, "orderStatus", pay);
productOrderFactType.set(instance, "userId", 1001L);
kieSession.insert(instance);
kieSession.fireAllRules();
Object orderStatus = productOrderFactType.get(instance, "orderStatus");
log.info("获取rule中修改之后的枚举字段的值:[{}]", orderStatus);
kieSession.dispose();
}
}
注意:
1、在java中获取到drl文件中声明的类型,需要使用 kieBase.getFactType来获取。
2、如果需要获取到drl文件中申明的枚举类型的值,可以通过反射来获取。
6、运行上方的代码
用户[1001]在[2022-05-17 11:42:27]购买的[iphone 13]已完成付款
11:42:27.724 [main] INFO com.huan.drools.querys.DroolsTypeDeclareApplication - 获取rule中修改之后的枚举字段的值:[RECEIVED]
可以看到规则执行了,并且java中也获取到了工作内存中修改后的值。
五、完整代码
https://gitee.com/huan1993/spring-cloud-parent/tree/master/drools/drools-drl-type-declarations
六、参考链接
1、https://docs.drools.org/7.69.0.Final/drools-docs/html_single/index.html#drl-declarations-con_drl-rules
- 上一篇: 规则引擎drools-实战个人所得税计算器
- 下一篇:已经是最后一篇了
猜你喜欢
- 2024-11-16 规则引擎drools-实战个人所得税计算器
- 2024-11-16 基于 Flink 和 Drools 的实时日志处理
- 2024-11-16 开源、强大的工作流引擎:camunda入门介绍
- 2024-11-16 53-SpringBoot整合Drools_2(springboot整合zuul)
- 2024-11-16 开启灵活开发编码模式:规则引擎drools——LHS部分
- 2024-11-16 AI应用企业落地方法论:践行财务共享AI审单项目
- 2024-11-16 开启灵活开发编码模式:规则引擎drools——RHS部分
- 2024-11-16 开启灵活开发编码模式:规则引擎drools——高级语法global
- 2024-11-16 43-drools基础语法(比较操作符_memberof)
- 2024-11-16 Google Aviator——轻量级 Java 表达式引擎实战
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)