java项目访问drools工作内存中的数据(fact)

本文将分享几种从drools外部访问drools工作内存中数据的方法。

实体类如下:

//客户
public class Customer {
    private Integer id;
    private String name;
    private String level;
    private double discount;//折扣率
    private boolean freeParking;//是否免费停车
}
//商品
public class Goods {
    private Integer id;
    private String name;
    private Double price;
    private String unit;
}
//订单类
public class Order {
    private Integer id;
    private Integer custId;
    private Double total;
    private String state;
    private List<Goods> goods;
}
//优惠券
public class Coupons {
    private Integer id;
    private String name;
    private Integer custId;
    private Integer orderId;
}

一、通过api方法插入的数据(即kieSession.insert(Object))

        这种情况下,直接访问Object对应的变量就可以了。

Customer customer = new Customer();
customer.setId(1);
customer.setDiscount(0.0);
customer.setFreeParking(false);
customer.setName("杨杨");
        
kieSession.insert(customer);//插入数据到工作内存
kieSession.fireAllRules();//匹配执行规则

System.out.println(customer.getDiscount());//直接访问该变量即可获取变化后的数据

kieSession.dispose();//释放 kieSession资源

二、访问规则执行时加入到工作内容的数据

     对于rule创建的实例,外部并没有引用变量,要想获取这些数据,就需要借助drools的api了。

案例:给消费金额达到100元的黄金会员发放免费停车券,优惠券下次可用。

  对于上述案例,券是由规则创建生成并保存在工作内存中,而且下次可用,这时就需要将工作内存中的停车券取出并保存到数据库。生成免费停车券的规则如下:

rule "create coupons"
   lock-on-active true
when
    $c:Customer(level == 'gold')
    $o:Order(custId == $c.id,total >= 100)//每个订单
then
    Coupons coupons = new Coupons();
    coupons.setCustId($c.getId());
    coupons.setId((int)(Math.random()*1000));
    coupons.setName("停车免费券");
    coupons.setOrderId($o.getId());
    insert(coupons);
    System.out.println("发放一张优惠券");
end

1.通过kiesession.getObjects(new ClassObjectFilter(Class clazz))获取

Customer customer = new Customer();
customer.setId(1);
customer.setDiscount(0.0);
customer.setFreeParking(false);
customer.setLevel("gold");
customer.setName("杨杨");
kieSession.insert(customer);//插入客户数据到工作内存

Order order = new Order();
order.setId(10);
order.setCustId(1);
order.setTotal(100.00);
kieSession.insert(order);//插入订单数据到工作内存

Collection<Coupons> coupons =  (Collection<Coupons>)kieSession.getObjects(new ClassObjectFilter(Coupons.class));
System.out.println("触发规则前,检索工作内存是否存在coupons:"+(coupons.size()>0));
kieSession.fireAllRules();//匹配执行规则
coupons =  (Collection<Coupons>)kieSession.getObjects(new ClassObjectFilter(Coupons.class));
for(Coupons cs: coupons){
  System.out.println("触发规则后,释放资源前检索工作内存:"+cs.toString());
}
kieSession.dispose();//释放 kieSession资源

执行结果如下:

触发规则前,检索工作内存是否存在coupons:false
发放一张优惠券
触发规则后,释放资源前检索工作内存:Coupons{id=987, name='停车免费券', custId=1, orderId=10}

2.使用Query查询工作内存

   还可以使用query来查询工作内存,query定义在drl文件中,可以提供给rule或java项目调用。

⑴. 上述需求query写法如下:

query coupons //coupons 为query的名称,通过该名称调用query查询drools工作内存
    $c:Coupons() //从工作内存中查询所有Coupons实例 注意这里应该绑定一个变量,api通过这个变量名称获取实例
end

java调用如下:

QueryResults queryResults = kieSession.getQueryResults("coupons");//coupons 为query的名称
//遍历查询结果
for(QueryResultsRow r: queryResults){
   Coupons c = (Coupons) r.get("$c");//$c 为查询绑定的变量名称
   System.out.println("后台query coupons is:"+c.toString());
}

执行结果:

后台query coupons is:Coupons{id=441, name='停车免费券', custId=1, orderId=10}

⑵. query还可以有参数,仍然是上述需求,查询指定人的优惠券,query写法如下:

query coupons(Integer cId)
    $c:Coupons(custId == cId)
end

java调用如下:

QueryResults queryResults = kieSession.getQueryResults("coupons",1);//query名称,参数值
for(QueryResultsRow r: queryResults){
   Coupons c = (Coupons) r.get("$c");
   System.out.println("后台query coupons is:"+c.toString());
}

执行结果如下:

后台query coupons is:Coupons{id=444, name='停车免费券', custId=1, orderId=10}

⑶.有参的query还可以使用org.drools.core.runtime.rule.Variable.v忽略掉参数

java调用如下:

QueryResults queryResults = kieSession.getQueryResults("coupons", Variable.v);//此时查询Coupons时并未做任何条件限制,查询的是所有Coupons实例
for(QueryResultsRow r: queryResults){
   Coupons c = (Coupons) r.get("$c");
   System.out.println("后台query coupons is:"+c.toString());
}

query在rule中调用与调用function时一样,但是query并不能绑定变量,也不想不明白怎么在rule条件中遍历查询结果,如果不能遍历query结果的话,query到底有什么用,query这么麻烦还得定义,有kieSession.getObjects()方法完全够用了。实际开发中没用过query,体会不到用它的好处是什么,学无止境啊。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值