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類型)。