1、基本的概念 请参考这个链接,差不多的语法感觉都介绍了 drools-api的基本语法链接
2、如何将drl文件配置在数据库中,实现动态加载:
package com.neo.drools;
import com.neo.drools.model.Message;
import org.kie.api.io.ResourceType;
import org.kie.internal.KnowledgeBase;
import org.kie.internal.KnowledgeBaseFactory;
import org.kie.internal.builder.KnowledgeBuilder;
import org.kie.internal.builder.KnowledgeBuilderError;
import org.kie.internal.builder.KnowledgeBuilderErrors;
import org.kie.internal.builder.KnowledgeBuilderFactory;
import org.kie.internal.io.ResourceFactory;
import org.kie.internal.runtime.StatefulKnowledgeSession;
import java.io.UnsupportedEncodingException;
public class DdLoadTest {
public static void main(String[] args) {
String rule = "package com.neo.drools\r\n";
rule += "import com.neo.drools.model.Message;\r\n";
rule += "rule \"rule1\"\r\n";
rule += "\twhen\r\n";
rule += "Message( status == 1, myMessage : msg )";
rule += "\tthen\r\n";
rule += "\t\tSystem.out.println( 1+\":\"+myMessage );\r\n";
rule += "end\r\n";
String rule2 = "package com.neo.drools\r\n";
rule += "import com.neo.drools.model.Message;\r\n";
rule += "rule \"rule2\"\r\n";
rule += "\twhen\r\n";
rule += "Message( status == 2, myMessage : msg )";
rule += "\tthen\r\n";
rule += "\t\tSystem.out.println( 2+\":\"+myMessage );\r\n";
rule += "end\r\n";
StatefulKnowledgeSession kSession = null;
try {
KnowledgeBuilder kb = KnowledgeBuilderFactory.newKnowledgeBuilder();
kb.add(ResourceFactory.newByteArrayResource(rule.getBytes("utf-8")), ResourceType.DRL);
kb.add(ResourceFactory.newByteArrayResource(rule2.getBytes("utf-8")), ResourceType.DRL);
KnowledgeBuilderErrors errors = kb.getErrors();
for (KnowledgeBuilderError error : errors) {
System.out.println(error);
}
KnowledgeBase kBase = KnowledgeBaseFactory.newKnowledgeBase();
kBase.addKnowledgePackages(kb.getKnowledgePackages());
kSession = kBase.newStatefulKnowledgeSession();
Message message1 = new Message();
message1.setStatus(1);
message1.setMsg("hello world!");
Message message2 = new Message();
message2.setStatus(2);
message2.setMsg("hi world!");
kSession.insert(message1);
kSession.insert(message2);
kSession.fireAllRules();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} finally {
if (kSession != null)
kSession.dispose();
}
}
}
3、如何读取drl、决策表、csv文件:
注意:下文中的RULES_PATH,其实就是配置在resource下的路径,会通过kieFileSystem组件去读取这个目录下的所有文件。
配置drl文件的配置类(springboot+drl配置方式)
package com.itheima.drools.config;
import org.kie.api.KieBase;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieRepository;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.internal.io.ResourceFactory;
import org.kie.spring.KModuleBeanFactoryPostProcessor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.Resource;
import java.io.IOException;
@Configuration
public class DroolsConfig {
private static final String RULES_PATH = "rules/";
private final KieServices kieServices = KieServices.Factory.get();
@Bean
@ConditionalOnMissingBean
public KieFileSystem kieFileSystem() throws IOException {
System.setProperty("drools.dateformat","yyyy-MM-dd");
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
ResourcePatternResolver resourcePatternResolver =
new PathMatchingResourcePatternResolver();
Resource[] files =
resourcePatternResolver.getResources("classpath*:" + RULES_PATH + "*.*");
String path = null;
for (Resource file : files) {
path = RULES_PATH + file.getFilename();
kieFileSystem.write(ResourceFactory.newClassPathResource(path, "UTF-8"));
}
return kieFileSystem;
}
@Bean
@ConditionalOnMissingBean
public KieContainer kieContainer() throws IOException {
KieRepository kieRepository = kieServices.getRepository();
kieRepository.addKieModule(kieRepository::getDefaultReleaseId);
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem());
kieBuilder.buildAll();
return kieServices.newKieContainer(kieRepository.getDefaultReleaseId());
}
@Bean
@ConditionalOnMissingBean
public KieBase kieBase() throws IOException {
return kieContainer().getKieBase();
}
@Bean
@ConditionalOnMissingBean
public KModuleBeanFactoryPostProcessor kiePostProcessor() {
return new KModuleBeanFactoryPostProcessor();
}
}
根据文件,不管是drl文件,还是excel表格,或者是csv文件,将其动态的转换成字符串,这段代码很牛掰
public String encodeToString(String realPath) {
File file = new File(realPath);
if (!file.exists()) {
return null;
}
if (realPath.endsWith(SUFFIX_DRL)) {
return read(file);
}
InputStream is = null;
try {
is = new FileInputStream(file);
} catch (FileNotFoundException e) {
logger.error("file not fount.");
}
if (realPath.endsWith(SUFFIX_EXCEL)||realPath.endsWith(SUFFIX_EXCEL_2007)) {
return new SpreadsheetCompiler().compile(is, InputType.XLS);
}
if (realPath.endsWith(SUFFIX_CSV)) {
return new SpreadsheetCompiler().compile(is, InputType.CSV);
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
logger.error("close stream error=>", e);
}
}
return "package src.main.resources;";
}
private String read(File file) {
FileInputStream fis = null;
ByteArrayOutputStream bos = null;
try {
fis = new FileInputStream(file);
bos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) != -1) {
bos.write(buffer, 0, length);
}
return bos.toString();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bos != null) {
bos.close();
}
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
public KieSession decodeToSession(String... drl) {
KieHelper kieHelper = new KieHelper();
for (String s : drl) {
kieHelper.addContent(s, ResourceType.DRL);
}
Results results = kieHelper.verify();
if (results.hasMessages(Message.Level.WARNING, Message.Level.ERROR)) {
List<Message> messages = results.getMessages(Message.Level.WARNING, Message.Level.ERROR);
for (Message message : messages) {
logger.error("Error: {}", message.getText());
}
throw new IllegalStateException("Compilation errors.");
}
KieBaseConfiguration config = kieHelper.ks.newKieBaseConfiguration();
if (EventProcessingOption.STREAM.getMode().equalsIgnoreCase(getMode())) {
config.setOption(EventProcessingOption.STREAM);
} else {
config.setOption(EventProcessingOption.CLOUD);
}
KieBase kieBase = kieHelper.build(config);
KieSession kieSession = kieBase.newKieSession();
if (getListener() == null || !LISTENER_CLOSE.equalsIgnoreCase(getListener())) {
kieSession.addEventListener(new DefaultRuleRuntimeEventListener());
kieSession.addEventListener(new DefaultAgendaEventListener());
kieSession.addEventListener(new DefaultProcessEventListener());
}
return kieSession;
}
KieBase kieBase = kieHelper.build();
kieBase.addEventListener(new DefaultKieBaseEventListener(){
@Override
public void beforeKiePackageRemoved(BeforeKiePackageRemovedEvent event) {
super.beforeKiePackageRemoved(event);
String packageName = event.getKiePackage().getName();
System.out.println("beforeKiePackageRemoved : " + packageName);
}
});
kieBase.removeKiePackage("com.rules");
4、设置拦截器等,大致的意思就是在实时对象插入或者修改或者删除的时候 做一些拦截,然后动态的加载逻辑,这是drools官方为我们提供的扩展东西,挺好的!!!
KieBase kieBase = kieHelper.build(config);
KieSession kieSession = kieBase.newKieSession();
if (getListener() == null || !LISTENER_CLOSE.equalsIgnoreCase(getListener())) {
kieSession.addEventListener(new DefaultRuleRuntimeEventListener());
kieSession.addEventListener(new DefaultAgendaEventListener());
kieSession.addEventListener(new DefaultProcessEventListener());
}
return kieSession;
package com.drools.core.listener;
import org.kie.api.event.rule.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DefaultAgendaEventListener implements AgendaEventListener {
protected final Logger logger = LoggerFactory.getLogger(getClass());
@Override
public void matchCreated(MatchCreatedEvent event) {
logger.info("===>>匹配的规则:{}", event.getMatch().getRule());
}
@Override
public void matchCancelled(MatchCancelledEvent event) {
}
@Override
public void beforeMatchFired(BeforeMatchFiredEvent event) {
logger.info("===>>开始执行Java代码块,匹配规则:{},评估对象:{}",
event.getMatch().getRule(), event.getMatch().getFactHandles());
}
@Override
public void afterMatchFired(AfterMatchFiredEvent event) {
logger.info("===>>结束执行Java代码块,匹配规则:{},评估对象:{}",
event.getMatch().getRule(), event.getMatch().getFactHandles());
}
@Override
public void agendaGroupPopped(AgendaGroupPoppedEvent event) {
}
@Override
public void agendaGroupPushed(AgendaGroupPushedEvent event) {
}
@Override
public void beforeRuleFlowGroupActivated(RuleFlowGroupActivatedEvent event) {
}
@Override
public void afterRuleFlowGroupActivated(RuleFlowGroupActivatedEvent event) {
}
@Override
public void beforeRuleFlowGroupDeactivated(RuleFlowGroupDeactivatedEvent event) {
}
@Override
public void afterRuleFlowGroupDeactivated(RuleFlowGroupDeactivatedEvent event) {
}
}
package com.drools.core.listener;
import org.kie.api.event.process.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DefaultProcessEventListener implements ProcessEventListener {
protected final Logger logger = LoggerFactory.getLogger(getClass());
@Override
public void beforeProcessStarted(ProcessStartedEvent event) {
}
@Override
public void afterProcessStarted(ProcessStartedEvent event) {
}
@Override
public void beforeProcessCompleted(ProcessCompletedEvent event) {
}
@Override
public void afterProcessCompleted(ProcessCompletedEvent event) {
}
@Override
public void beforeNodeTriggered(ProcessNodeTriggeredEvent event) {
}
@Override
public void afterNodeTriggered(ProcessNodeTriggeredEvent event) {
}
@Override
public void beforeNodeLeft(ProcessNodeLeftEvent event) {
}
@Override
public void afterNodeLeft(ProcessNodeLeftEvent event) {
}
@Override
public void beforeVariableChanged(ProcessVariableChangedEvent event) {
}
@Override
public void afterVariableChanged(ProcessVariableChangedEvent event) {
}
}
package com.drools.core.listener;
import org.kie.api.event.rule.ObjectDeletedEvent;
import org.kie.api.event.rule.ObjectInsertedEvent;
import org.kie.api.event.rule.ObjectUpdatedEvent;
import org.kie.api.event.rule.RuleRuntimeEventListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DefaultRuleRuntimeEventListener implements RuleRuntimeEventListener {
protected final Logger logger = LoggerFactory.getLogger(getClass());
@Override
public void objectInserted(ObjectInsertedEvent event) {
logger.info("===>>插入对象:{};操作规则:{}", event.getFactHandle(), event.getRule());
}
@Override
public void objectUpdated(ObjectUpdatedEvent event) {
logger.info("===>>更新对象:{};操作规则:{}", event.getFactHandle(), event.getRule());
}
@Override
public void objectDeleted(ObjectDeletedEvent event) {
logger.info("===>>删除对象:{};操作规则:{}", event.getFactHandle(), event.getRule());
}
}
5、将决策表转化成drl字符串
public static String getDRL (String realPath) throws FileNotFoundException {
File file = new File(realPath);
InputStream is = new FileInputStream(file);
SpreadsheetCompiler compiler = new SpreadsheetCompiler();
String drl = compiler.compile(is, InputType.XLS);
System.out.println(drl);
return drl;
}
顺便分享一个完整的案例,如何从数据库读取脚本,实现动态加载,包括简单的表设计,全量代码:
github-drools+db代码
6、drools部分api使用(这些api是你市面上可能找不到的,一般百度是找不到的哦): 6.1、drl文件中使用函数
package rules
import com.huan.drools.Person
function boolean playGameOk(Person person){
return person.getAge()>=18;
}
function String whenInvoked(Person person){
return "whenInvoked,peronName:" + person.getName();
}
rule "rule_can_play_game"
when
$person: Person()
$invokedFunction: String() from whenInvoked($person)
then
System.out.println("在when中调用function获取的结果: " + $invokedFunction);
System.err.println("drl function 判断: 用户:["+$person.getName()+"]是否可以玩游戏?["+playGameOk($person)+"]");
System.err.println("java static function 调用: "+ String.format("当前用户:%s", $person.getName()));
end
6.2 map在drools的应用
package com.rules
import java.util.Map;
import com.secbro.drools.model.Person;
rule "map-usage"
agenda-group "map-group"
when
$obj : Object();
$map : Map(["p1"] != $obj);
then
System.out.println("p1's age is " + ((Person)$map.get("p1")).getAge());
System.out.println("p2's age is " + ((Person)$map.get("p2")).getAge());
end
6.3、全局变量,可以通过这个在drl中 动态的调用 java代码:
package com.rules
import com.secbro.drools.model.Risk
import com.secbro.drools.model.Message
global com.secbro.drools.EmailService emailService
rule "test-global"
agenda-group "test-global-group"
when
then
Message message = new Message();
message.setRule(drools.getRule().getName());
message.setDesc("to send email!");
emailService.sendEmail(message);
end
6.4、函数的使用:
package com.rules
function String hello(String name){
return "Hello " + name + "!";
}
rule helloSomeone
agenda-group "function-group"
when
eval(true);
then
System.out.println(hello("Tom"));
end
6.5、可以在规则文件中获取"rule"这个对象,然后可以获取到很多属性:
package com.rules
rule "Get name and package demo"
agenda-group "Name and package"
when
then
System.out.println("The rule's name is '" + drools.getRule().getName() + "'");
System.out.println("The rule's package is '" + drools.getRule().getPackageName() + "'");
end
6.5、query方法,相当于给java提供一个入口,去获取drl文件里面的对象:
package com.rules
import com.secbro.drools.model.Person;
rule "query-test"
agenda-group "query-test-group1"
when
$person : Person()
then
System.out.println("The rule query-test fired!");
end
query "query-1"
$person : Person(age > 30)
end
query "query-2"(String nameParam)
$person : Person(age > 30,name == nameParam)
end
package com.secbro.drools.test;
import com.secbro.drools.BaseTest;
import com.secbro.drools.model.Person;
import org.junit.Test;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.rule.QueryResults;
import org.kie.api.runtime.rule.QueryResultsRow;
public class QueryTest extends BaseTest {
@Test
public void queryTest() {
KieSession kieSession = this.getKieSession("query-test-group1");
Person p1 = new Person();
p1.setAge(29);
Person p2 = new Person();
p2.setAge(40);
kieSession.insert(p1);
kieSession.insert(p2);
int count = kieSession.fireAllRules();
System.out.println("Fire " +count + " rule(s)!");
QueryResults results = kieSession.getQueryResults("query-1");
System.out.println("results size is " + results.size());
for(QueryResultsRow row : results){
Person person = (Person) row.get("$person");
System.out.println("Person from WM, age : " + person.getAge());
}
kieSession.dispose();
}
@Test
public void queryWithParamTest() {
KieSession kieSession = this.getKieSession("query-test-group1");
Person p1 = new Person();
p1.setAge(29);
p1.setName("Ross");
Person p2 = new Person();
p2.setAge(40);
p2.setName("Tom");
kieSession.insert(p1);
kieSession.insert(p2);
int count = kieSession.fireAllRules();
System.out.println("Fire " +count + " rule(s)!");
QueryResults results = kieSession.getQueryResults("query-2","Tom");
System.out.println("results size is " + results.size());
for(QueryResultsRow row : results){
Person person = (Person) row.get("$person");
System.out.println("Person from WM, age : " + person.getAge() + "; name :" + person.getName());
}
kieSession.dispose();
}
}
6.6、同一个对象类型,在drl文件中如何展示:
package com.rules
import com.secbro.drools.model.Customer;
rule "two same objects"
agenda-group "two same objects"
when
$firstCustomer:Customer(age == 59);
$secondCustomer:Customer(this != $firstCustomer,age == 61);
then
System.out.println("firstCustomer age :" + $firstCustomer.getAge());
System.out.println("secondCustomer age :" + $secondCustomer.getAge());
end
6.7、drl文件中的from的用法:
package com.rules
import com.secbro.drools.model.Customer;
import java.util.List;
rule "two same objects in list"
agenda-group "two same objects in list"
when
$list : List();
$firstCustomer:Customer(age == 59) from $list;
$secondCustomer:Customer(this != $firstCustomer,age == 61) from $list;
then
System.out.println("two same objects in list:firstCustomer age :" + $firstCustomer.getAge());
System.out.println("two same objects in list:secondCustomer age :" + $secondCustomer.getAge());
end
6.8、Calendar在 drools的使用:设置不同的日期限制,规则中对应的触发日期就不一样,比time更强大一些
package com.secbro.drools.chapter21;
import com.secbro.drools.BaseTest;
import org.junit.Test;
import org.kie.api.runtime.KieSession;
import org.kie.api.time.Calendar;
import org.quartz.impl.calendar.WeeklyCalendar;
public class CalenderTest extends BaseTest{
@Test
public void testCalender(){
KieSession kieSession = this.getKieSessionBySessionName("calenderTest-rules");
kieSession.getCalendars().set("weekday_exclude",WEEKDAY_EXCLUDE);
kieSession.getCalendars().set("weekday",WEEKDAY);
kieSession.fireAllRules();
kieSession.dispose();
}
private static final Calendar WEEKDAY = new Calendar() {
@Override
public boolean isTimeIncluded(long timestamp) {
WeeklyCalendar weeklyCalendar = new WeeklyCalendar();
weeklyCalendar.setDaysExcluded(new boolean[]{false,false,false,false,false,false,false});
weeklyCalendar.setDayExcluded(java.util.Calendar.WEDNESDAY,true);
return weeklyCalendar.isTimeIncluded(timestamp);
}
};
private static final Calendar WEEKDAY_EXCLUDE = new Calendar() {
@Override
public boolean isTimeIncluded(long timestamp) {
WeeklyCalendar weeklyCalendar = new WeeklyCalendar();
weeklyCalendar.setDaysExcluded(new boolean[]{false,false,false,false,false,false,false});
return weeklyCalendar.isTimeIncluded(timestamp);
}
};
}
package com.calenderTest
rule "test-calender-rule"
calendars "weekday"
when
then
System.out.println("test-calender-rule 被触发");
end
rule "test-calender-rule-1"
calendars "weekday_exclude"
when
then
System.out.println("test-calender-rule-1 被触发");
end
6.9、declare 用法:
package com.newType
import java.util.Date;
rule "new-type-rule-1"
when
$country: Country(name == "美国")
then
Address address = new Address();
address.setName(CountryName.CHINA.getFullName());
address.setCity("北京");
address.setNumber(100000);
insert(address);
end
rule "new-type-rule"
when
$address : Address(name == CountryName.CHINA.getFullName())
then
System.out.println("规则被触发");
end
declare Address extends Country
number : Integer
city : String
crateTime : Date
end
declare Country
name : String
end
declare enum CountryName
CHINA("中国");
fullName : String
end
6.10、meta-元数据:
declare City
@author("wmd")
name : String @key
address: String
end
6.11、根据不同的路径读excel决策表:
@Test
public void checkDrl() throws FileNotFoundException {
File file = new File("E:\\GitHub\\respo\\drools-lesson\\src\\main\\resources\\decision.xls");
InputStream is = new FileInputStream(file);
SpreadsheetCompiler compiler = new SpreadsheetCompiler();
String drl = compiler.compile(is, InputType.XLS);
System.out.println(drl);
}
@Test
public void checkDrl2() throws FileNotFoundException {
SpreadsheetCompiler compiler = new SpreadsheetCompiler();
String drl = compiler.compile(ResourceFactory.newClassPathResource("com/decision/decision.xls"), InputType.XLS);
System.out.println(drl);
}
6.12、如何获取kiebase 如何获取kiesession
package com.secbro2.drools.chapter6;
import org.kie.api.KieServices;
import org.kie.api.builder.Message;
import org.kie.api.builder.Results;
import org.kie.api.runtime.KieContainer;
import java.util.Collection;
import java.util.List;
public class Chapter6 {
public static void main(String[] args) {
KieServices kieServices = KieServices.Factory.get();
KieContainer container = kieServices.getKieClasspathContainer();
Results results = container.verify();
List<Message> messages = results.getMessages();
System.out.println("messages size:" + messages.size());
for (Message msg : messages) {
System.out.println("level:" + msg.getLevel() + ";text=" + msg.getText());
}
Collection<String> kieBaseNames = container.getKieBaseNames();
for(String kieBaseName : kieBaseNames){
System.out.println("kieBaseName----" + kieBaseName);
Collection<String> kieSessionNamesInKieBase = container.getKieSessionNamesInKieBase(kieBaseName);
for(String kieSession : kieSessionNamesInKieBase){
System.out.println("kieSession-----" + kieSession);
}
}
}
}
6.13、如何获取jar里面的规则文件,Drools中提供了一个类KieScanner,可以支持从Maven存储库动态的加载并更新规则。官方给出的例子没有很好的证明这一能力。下面我来演示一下:
package com.secbro2.drools.demo;
import org.kie.api.KieServices;
import org.kie.api.builder.KieScanner;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
public class Demo8 {
public static void main(String[] args) throws InterruptedException {
KieServices kieServices = KieServices.Factory.get();
KieContainer container = kieServices.newKieContainer(kieServices.newReleaseId("com.secbro2","drools-rules","1.0-SNAPSHOT"));
KieScanner kieScanner = kieServices.newKieScanner(container);
kieScanner.start(1000);
KieSession kieSession = container.newKieSession("all-kieSession-1");
while (true){
Thread.sleep(5000);
int nums = kieSession.fireAllRules();
System.out.println("Fire " + nums + " rules!");
}
}
}
6.14、获取jar包里面的规则,利用ksession动态的获取里面的不同类型的对象,通过过滤器:
package cn.abel.service;
import cn.abel.model.Person;
import org.drools.core.ClassObjectFilter;
import org.kie.api.KieServices;
import org.kie.api.builder.KieScanner;
import org.kie.api.builder.ReleaseId;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
@Service
public class ExecuteService {
private KieContainer kContainer;
@PostConstruct
public void setUp() {
KieServices ks = KieServices.Factory.get();
ReleaseId releaseId = ks.newReleaseId("cn.abel", "springboot-drools-dynamic-rules-kjar", "1.0-SNAPSHOT");
kContainer = ks.newKieContainer(releaseId);
KieScanner kScanner = ks.newKieScanner(kContainer);
kScanner.start(10000L);
}
public Integer execute() {
KieSession kSession = kContainer.newKieSession("PersonAgeSession");
kSession.setGlobal("out", System.out);
kSession.insert(new Person("Dave",100));
kSession.fireAllRules();
Integer result = null;
for (Object per : kSession.getObjects(new ClassObjectFilter(Person.class))) {
if (((Person) per).getName().equals("abel")) {
result = ((Person) per).getAge();
}
}
return result;
}
}
6.15 drt用法,这个,我个人觉得不好用,但是也写下吧
template header
age
type
log
package com.us.templates;
global java.util.List list;
template "cheesefans"
rule "Cheese fans_@{row.rowNumber}"
when
Person(age == @{age})
Cheese(type == "@{type}")
then
list.add("@{log}");
end
end template
package com.us.templates;
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import java.util.ArrayList;
import java.util.List;
public class SimpleRuleTemplateExample {
public static void main(String[] args) {
KieContainer kc = KieServices.Factory.get().getKieClasspathContainer();
execute(kc);
}
public static void execute(KieContainer kc) {
KieSession ksession = kc.newKieSession("TemplatesKS");
ksession.insert(new Cheese("stilton",
42));
ksession.insert(new Person("michael",
"stilton",
42));
ksession.insert(new Cheese("cheddar",
21));
ksession.insert(new Person("michael",
"stilton",
21));
final List<String> list = new ArrayList<String>();
ksession.setGlobal("list", list);
ksession.fireAllRules();
System.out.println(list);
ksession.dispose();
}
}
6.16、创建一个kjar、初始化一个jar,动态加载(这个功能,个人觉得很吊)
package com.secbro2.drools.demo;
import org.drools.compiler.kie.builder.impl.InternalKieModule;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieRepository;
import org.kie.api.builder.ReleaseId;
import org.kie.api.builder.model.KieBaseModel;
import org.kie.api.builder.model.KieModuleModel;
import org.kie.api.builder.model.KieSessionModel;
import org.kie.api.conf.EqualityBehaviorOption;
import org.kie.api.conf.EventProcessingOption;
import org.kie.api.io.Resource;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.internal.io.ResourceFactory;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
public class DynamicDrlDemo {
private static final String RULES_FILE_NAME = "rules.drl";
private static final String RULES_PATH = "com";
private static final String RULES = "package com.rules\n" +
"\n" +
"rule \"chapter4\"\n" +
"\n" +
"when\n" +
"\n" +
"then\n" +
"\n" +
"System.out.println(\"Fire the default rules for dynamic!\");\n" +
"end";
public static void main(String[] args) {
KieServices kieServices = KieServices.Factory.get();
final ReleaseId releaseId = kieServices.newReleaseId("com.secbro2", "drools-rules", "1.0.0");
InternalKieModule kJar = initKieJar(kieServices, releaseId);
KieRepository repository = kieServices.getRepository();
repository.addKieModule(kJar);
KieContainer kieContainer = kieServices.newKieContainer(releaseId);
KieSession session = kieContainer.newKieSession();
try {
session.fireAllRules();
} finally {
session.dispose();
}
System.out.println("-----first fire end-------");
kJar = createKieJar(kieServices, releaseId, new ResourceWrapper(ResourceFactory.newByteArrayResource(RULES.getBytes()), RULES_FILE_NAME));
repository.addKieModule(kJar);
kieContainer.updateToVersion(releaseId);
session = kieContainer.newKieSession();
try {
session.fireAllRules();
} finally {
session.dispose();
}
System.out.println("-----second fire end-------");
}
private static List<File> getRuleFiles() {
List<File> list = new ArrayList<>();
URL url = Thread.currentThread().getContextClassLoader().getResource("");
if (url == null) {
return list;
}
String filePath = url.getPath();
File rootDir = new File(filePath);
File[] files = rootDir.listFiles();
if (files == null) {
return list;
}
for (File itemFile : files) {
if (itemFile.isDirectory() && itemFile.getName().equals(RULES_PATH)) {
File[] childrenFile = itemFile.listFiles();
if (childrenFile != null) {
for (File f : childrenFile) {
if (f.getName().endsWith(".drl")) {
list.add(f);
}
}
}
}
}
return list;
}
public static InternalKieModule initKieJar(KieServices ks, ReleaseId releaseId) {
KieFileSystem kfs = createKieFileSystemWithKProject(ks, true);
kfs.writePomXML(getPom(releaseId));
for (File file : getRuleFiles()) {
kfs.write("src/main/resources/" + file.getName(),
ResourceFactory.newClassPathResource(RULES_PATH + File.separator + file.getName(), "UTF-8"));
}
KieBuilder kieBuilder = ks.newKieBuilder(kfs);
if (!kieBuilder.buildAll().getResults().getMessages().isEmpty()) {
throw new IllegalStateException("Error creating KieBuilder.");
}
return (InternalKieModule) kieBuilder.getKieModule();
}
public static InternalKieModule createKieJar(KieServices ks, ReleaseId releaseId, ResourceWrapper resourceWrapper) {
KieFileSystem kfs = createKieFileSystemWithKProject(ks, true);
kfs.writePomXML(getPom(releaseId));
kfs.write("src/main/resources/" + resourceWrapper.getTargetResourceName(), resourceWrapper.getResource());
KieBuilder kieBuilder = ks.newKieBuilder(kfs);
if (!kieBuilder.getResults().getMessages().isEmpty()) {
System.out.println(kieBuilder.getResults().getMessages());
throw new IllegalStateException("Error creating KieBuilder.");
}
return (InternalKieModule) kieBuilder.getKieModule();
}
public static KieFileSystem createKieFileSystemWithKProject(KieServices ks, boolean isDefault) {
KieModuleModel kproj = ks.newKieModuleModel();
KieBaseModel kieBaseModel = kproj.newKieBaseModel("KBase").setDefault(isDefault)
.setEqualsBehavior(EqualityBehaviorOption.EQUALITY).setEventProcessingMode(EventProcessingOption.STREAM);
kieBaseModel.newKieSessionModel("KSession").setDefault(isDefault)
.setType(KieSessionModel.KieSessionType.STATEFUL);
KieFileSystem kfs = ks.newKieFileSystem();
kfs.writeKModuleXML(kproj.toXML());
return kfs;
}
public static String getPom(ReleaseId releaseId, ReleaseId... dependencies) {
StringBuilder pom = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
+ " xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n"
+ " <modelVersion>4.0.0</modelVersion>\n" + "\n" + " <groupId>" + releaseId.getGroupId()
+ "</groupId>\n" + " <artifactId>" + releaseId.getArtifactId() + "</artifactId>\n" + " <version>"
+ releaseId.getVersion() + "</version>\n" + "\n");
if (dependencies != null && dependencies.length > 0) {
pom.append("<dependencies>\n");
for (ReleaseId dep : dependencies) {
pom.append("<dependency>\n");
pom.append(" <groupId>").append(dep.getGroupId()).append("</groupId>\n");
pom.append(" <artifactId>").append(dep.getArtifactId()).append("</artifactId>\n");
pom.append(" <version>").append(dep.getVersion()).append("</version>\n");
pom.append("</dependency>\n");
}
pom.append("</dependencies>\n");
}
pom.append("</project>");
return pom.toString();
}
static class ResourceWrapper {
private Resource resource;
private String targetResourceName;
public ResourceWrapper(Resource resource, String targetResourceName) {
this.resource = resource;
this.targetResourceName = targetResourceName;
}
public Resource getResource() {
return resource;
}
public String getTargetResourceName() {
return targetResourceName;
}
public void setResource(Resource resource) {
this.resource = resource;
}
public void setTargetResourceName(String targetResourceName) {
this.targetResourceName = targetResourceName;
}
}
}
决策表长什么样?截图看看
7、drools如何结合 规则流呢? drools引擎控制规则分组,以及规则执行先后次序的方法有多种。 第一种:salience 第二种:ruleflow-group 如下图:(流程的编写可以使用drools的eclipse插件可视化的完成。) 官网参考地址:http://www.jboss.org/drools/drools-flow
rule "XX"
ruleflow-group "A"
...
then
...
end
注意:第二种比较复杂,结合流程图,可以完成很复杂的商业逻辑:
下面详细聊聊其用法:
|