Drools學習筆記2—Conditions / LHS 匹配模式&條件元素
阿新 • • 發佈:2019-02-02
- 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();
}