drools--Knowledge的實例

1.引入依賴

<!--規則引擎-->
      <dependency>
          <groupId>org.kie</groupId>
          <artifactId>kie-api</artifactId>
          <version>6.5.0.Final</version>
      </dependency>
      <dependency>
          <groupId>org.drools</groupId>
          <artifactId>drools-core</artifactId>
          <version>6.5.0.Final</version>
      </dependency>
      <dependency>
          <groupId>org.drools</groupId>
          <artifactId>drools-compiler</artifactId>
          <version>6.5.0.Final</version>
      </dependency>
      <dependency>
          <groupId>org.drools</groupId>
          <artifactId>drools-decisiontables</artifactId>
          <version>6.5.0.Final</version>
      </dependency>
      <dependency>
          <groupId>org.drools</groupId>
          <artifactId>drools-templates</artifactId>
          <version>6.5.0.Final</version>
      </dependency>

2.實現

public Order handleRules(String id, Order order) {
            //獲取規則開始
            String rules = "";
            Rules ru = ruleRespository.findById(id).get();
            if (ru != null && ru.getRules() != null) {
                  rules = ru.getRules();
            }
            //獲取規則結束
            Order result = null;
            KieSession kieSession = null;
            KnowledgeBuilder kb = KnowledgeBuilderFactory.newKnowledgeBuilder();
            try{
                   //轉換DRL文件形式
                  kb.add(ResourceFactory.newByteArrayResource(rules.getBytes("utf-8")),ResourceType.DRL);
                  // 檢查規則正確性
                  if(kb.hasErrors()){
                        log.error(kb.getErrors().toString());
                  }
                  KnowledgeBase knowledgeBase = KnowledgeBaseFactory.newKnowledgeBase();
                  knowledgeBase.addKnowledgePackages(kb.getKnowledgePackages());
                  kieSession = knowledgeBase.newKieSession();
                  log.info("訂單使用規則傳入的訂單信息={}",order);
                  kieSession.insert(order);//fact插入
                  kieSession.fireAllRules();

                  for (Object per : kieSession.getObjects(new ClassObjectFilter(Order.class))) {
                        result = ((Order) per);
                  }
            }catch (Exception e){
                  log.info("執行規則出現異常");
            }finally {
                  if(null!=kieSession){
                        kieSession.dispose();//釋放
                  }
            }
            return result;
      }

3.規則(使用的是數據庫獲取,數據庫表的設計可以按照這樣設計)

INSERT INTO obk_rules VALUES
('3',
'import com.sutpc.maas.orderbook.domain.Order;
import com.sutpc.maas.orderbook.domain.StaffType;import com.sutpc.maas.orderbook.domain.OrderType;
import com.sutpc.maas.orderbook.domain.ConnectionType;
import com.sutpc.maas.orderbook.domain.Price;
import com.sutpc.maas.orderbook.domain.DiscountType;

function  Boolean containStr(String routeNo,String routeNos){
        Boolean isContain = routeNos.contains(routeNo);
        return isContain;
}

function Price queryPrice(Double routePrice){
    Price price = new Price();
    price.setPrice(routePrice);
    price.setActualPrice(routePrice);
    price.setDiscountType(DiscountType.NON);
    return price;
}
rule "rule1"
    no-loop true
    when
        $order:Order(StaffType.INTERNAL==passenger.getType()&&orderType==OrderType.IMMED&&containStr(route.routeNo,"K4"))
    then
        System.out.print("進入rule1");
        Price price = new Price();
        price.setPrice($order.getRoute().getRoutePrice());
        price.setActualPrice(2.4);
        price.setDiscountType(DiscountType.FIX);
        $order.setPrice(price);
        update($order);
     end
rule "rule2"
    no-loop true
    when
        $order:Order(StaffType.EXTERNAL==passenger.getType()&&orderType==OrderType.IMMED&&containStr(route.routeNo,"K4"))
    then
        System.out.print("進入rule2");
        Price price = queryPrice($order.getRoute().getRoutePrice());
        $order.setPrice(price);
        update($order);
    end
rule "rule3"
    no-loop true
    when
        $order:Order(StaffType.EXTERNAL==passenger.getType()&&orderType==OrderType.IMMED&&containStr(route.routeNo,"K1,K2"))
    then
        System.out.print("進入rule3");
        Price price = queryPrice($order.getRoute().getRoutePrice());
        $order.setPrice(price);
        update($order);
    end
rule "rule4"
    no-loop true
    when
        $order:Order(StaffType.INTERNAL==passenger.getType()&&orderType==OrderType.IMMED&&containStr(route.routeNo,"K1,K2"))
    then
        System.out.print("進入rule4");
        Price price = new Price();
        price.setPrice($order.getRoute().getRoutePrice());
        price.setActualPrice(0.0);
        price.setDiscountType(DiscountType.FIX);
        $order.setPrice(price);
        update($order);
    end',
'訂單策略規則',
'Y'
);

4.test

@Test
public void handleOrderRule(){
            Order order = Order.builder()
                        .orderType(OrderType.IMMED)
                        .passenger(Passenger.builder().type(StaffType.INTERNAL).build())
                        .route(Route.builder().routeNo("K4").routePrice(6.0).build())
                        .build();
            Order handledOrder = ruleService.handleRules("3", order);
            Assert.assertEquals(new Double(2.4),handledOrder.getPrice().getActualPrice());
}

解釋:這個方法是使用了數據庫動態獲取的,避免加載文件;可以先寫好規則文件,然後再存儲到數據庫中,我存儲使用的字段類型是text(測試內存數據庫中可以使用clob類型)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章