- Rule的LHS由條件元素(Conditional Elements—CE)和匹配模式(Patterns)組成
- Patterns被用來指示出fact的字段約束
- 每個約束必須為true才能讓RHS的actions fire
測試代碼,測試用獲取KnowledgeBase方法:
/** * 獲取KnowledgeBase * @return * @throws Exception */ private static KnowledgeBase readKnowledgeBase(String ruleName) throws Exception { KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); kbuilder.add(ResourceFactory.newClassPathResource(ruleName, RuleTest.class), ResourceType.DRL); KnowledgeBuilderErrors errors = kbuilder.getErrors(); if (errors.size() > 0) { for (KnowledgeBuilderError error: errors) { System.err.println(error); } throw new IllegalArgumentException("Could not parse knowledge."); } KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); kbase.addKnowledgePackages(kbuilder.getKnowledgePackages()); return kbase; }
使用到的fact對象
package com.bean; import java.util.ArrayList; import java.util.List; public class Customer { private String name; private String Company; private Integer age; private String gender; private String city; private List<Account> accounts = new ArrayList<Account>(); //省略set、get、toString方法 }
package com.bean; public class Account { private String name; private String status; private int num; }
匹配模式(Patterns)
- 沒有字段約束的Pattern
Person()
/**規則文件.drl**/ package com.sample import com.bean.Customer; rule "No args" when Customer() then System.out.println( "no massage" ); end /**java測試代碼,采用Junit測試**/ /** * 沒有字段約束的Pattern * @throws Exception */ @Test public void testNoParam() throws Exception { KnowledgeBase kbase = readKnowledgeBase("NoParam.drl"); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test"); Customer customer = new Customer(); ksession.insert(customer); ksession.fireAllRules(); logger.close(); }
- 有文本字段約束的Pattern
Person( name == “bob” )
/**規則文件.drl**/ package com.sample import com.bean.Customer; rule "Binding Param" when Customer($name:name=="七夜雪") then System.out.println( "Binding Param Rule and Customer is " + $name ); end /**java測試代碼,采用Junit測試**/ /** * 有文本字段約束的Pattern * @throws Exception */ Customer customer = new Customer(); customer.setName("七夜雪"); ksession.insert(customer); ksession.fireAllRules();
- 字段綁定的Pattern
Person( $name : name == “bob” )
變量名稱可以是任何合法的java變量,$是可選的,可由於區分字段和變量
//drl規則文件 package com.sample import com.bean.Customer; rule "Binding Fact" when $customer:Customer(name=="七夜雪") then System.out.println( "Binding Fact Rule :" + $customer ); end
/** * java測試方法 * 字段綁定的Pattern * @throws Exception */ @Test public void testBindingParam() throws Exception { KnowledgeBase kbase = readKnowledgeBase("HaveParam.drl"); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test"); Customer customer = new Customer(); customer.setName("七夜雪"); ksession.insert(customer); ksession.fireAllRules(); logger.close(); }
- Fact綁定的Pattern
$bob : Person( name == “bob” )字段綁定的Pattern
//drl文件 package com.sample import com.bean.Customer; rule "Binding Fact" when $customer:Customer(name=="七夜雪") //綁定變量$customer變量名
then
System.out.println( "Binding Fact Rule :" + $customer );
end
/** * Fact綁定的Pattern * @throws Exception */ @Test public void testBindingFact() throws Exception { KnowledgeBase kbase = readKnowledgeBase("BindingFact.drl"); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test"); Customer customer = new Customer(); customer.setName("七夜雪"); customer.setCompany("聽雪樓"); ksession.insert(customer); ksession.fireAllRules(); logger.close(); }
- 變量約束的Pattern
Person( name == $name )
package com.sample import com.bean.Customer; import com.bean.Account; rule "Param Limit" when Customer($name:name=="七夜雪") Account(name==$name) then System.out.println( "Param Limit Rule" ); end
/** * 變量約束的Pattern * @throws Exception */ @Test public void testParamLimit() throws Exception { KnowledgeBase kbase = readKnowledgeBase("ParamLimit.drl"); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test"); Customer customer = new Customer(); customer.setName("七夜雪"); customer.setCompany("聽雪樓"); Account account = new Account(); account.setName("七夜雪"); ksession.insert(customer); ksession.insert(account); ksession.fireAllRules(); logger.close(); }
條件元素(Conditional Elements)
and
- 對於頂級(非嵌套)patterns是隱式成立的
- 可以顯示add
- 使用關鍵字’and’(不推薦使用 &&)
package com.sample import com.bean.Customer; import com.bean.Account; rule "And" when Customer(name=="七夜雪" ) and Account(name=="七夜雪") then System.out.println( "And Rule" ); end rule "Default" when Customer(name=="七夜雪" ) Account(name=="七夜雪") then System.out.println( "default is and" ); end rule "&&" when Customer(name=="七夜雪" ) && Account(name=="七夜雪") then System.out.println( "And && Rule" ); end
/** * 條件元素 and、&&,不寫默認為and * @throws Exception */ @Test public void testAndRule() throws Exception { KnowledgeBase kbase = readKnowledgeBase("And.drl"); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test"); Customer customer = new Customer(); customer.setName("七夜雪"); Account account = new Account(); account.setName("七夜雪"); ksession.insert(customer); ksession.insert(account); ksession.fireAllRules(); logger.close(); }
or
- 列能被顯式or
- 使用關鍵字’or’(不推薦使用 ||)
package com.sample import com.bean.Customer; import com.bean.Account; rule "Or" when Customer(name=="七夜雪" ) or Account(name=="七夜雪") then System.out.println( "And Rule" ); end
/** * 條件元素 or,不寫默認為and * 注:每個條件符合,then的內容都會執行一次 * @throws Exception */ @Test public void testOrRule() throws Exception { KnowledgeBase kbase = readKnowledgeBase("Or.drl"); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test"); Customer customer = new Customer(); customer.setName("七夜雪"); Account account = new Account(); account.setName("七夜雪"); ksession.insert(customer); ksession.insert(account); ksession.fireAllRules(); logger.close(); }
exists 、Not
package com.sample import com.bean.Customer; import com.bean.Account; rule "Exists" when exists Customer() //工作空間存在customer對象 then System.out.println( "Customer Exists" ); end rule "Not" when not Account() //工作空間不存在Account對象 then System.out.println( "Account Not Exists" ); end
/** * 條件元素 exist、not,兩個剛好相反 * * @throws Exception */ @Test public void testExistsAndNotRule() throws Exception { KnowledgeBase kbase = readKnowledgeBase("From.drl"); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test"); Customer customer = new Customer(); Account account = new Account(); account.setName("七夜雪"); Account account1 = new Account(); account.setName("碧落"); customer.getAccounts().add(account); customer.getAccounts().add(account1); ksession.insert(customer); ksession.fireAllRules(); logger.close(); }
from
package com.sample import com.bean.Customer; import com.bean.Account; rule "from" when $customer:Customer( )
//customer中的accounts列表中存在name="碧落"的account對象 Account(name=="碧落") from $customer.accounts then System.out.println( "from element test success" ); end
/** * 條件元素 from * * @throws Exception */ @Test public void testFromRule() throws Exception { KnowledgeBase kbase = readKnowledgeBase("From.drl"); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test"); Customer customer = new Customer(); ksession.insert(customer); ksession.fireAllRules(); logger.close(); }
collect
package com.sample import com.bean.Customer; import com.bean.Account; import java.util.ArrayList; rule "collect" when $customer:Customer( )
//列表中status="Y"的Account對象大於等於4個, $accounts:ArrayList(size >= 4) from collect (Account(status == "Y")) then System.out.println( "collect element test success" ); end
/** * 條件元素 collect * * @throws Exception */ @Test public void testCollectRule() throws Exception { KnowledgeBase kbase = readKnowledgeBase("Collect.drl"); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test"); Customer customer = new Customer(); Account account1 = new Account(); account1.setStatus("Y"); Account account2 = new Account(); account2.setStatus("Y"); Account account3= new Account(); account3.setStatus("Y"); Account account4 = new Account(); account4.setStatus("Y"); ksession.insert(customer); ksession.insert(account1); ksession.insert(account2); ksession.insert(account3); ksession.insert(account4); ksession.fireAllRules(); logger.close(); }
Accumulate 聚合函數
package com.sample import com.bean.Customer; import com.bean.Account; rule "accumulate" when
//工作空間中,account對象的num屬性之和大於400時符合規則 $total:Number( intValue > 400) from accumulate (Account($num:num),sum($num)) then System.out.println( "accumulate element test success" ); end
/** * 條件元素 Accumulate * 聚合函數 * @throws Exception */ @Test public void testAccumulateRule() throws Exception { KnowledgeBase kbase = readKnowledgeBase("Accumulate.drl"); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "test"); Customer customer = new Customer(); Account account1 = new Account(); account1.setNum(100); Account account2 = new Account(); account2.setNum(100); Account account3= new Account(); account3.setNum(100); Account account4 = new Account(); account4.setNum(200); ksession.insert(customer); ksession.insert(account1); ksession.insert(account2); ksession.insert(account3); ksession.insert(account4); ksession.fireAllRules(); logger.close(); }