java - Drools 7 - 从数据库加载规则
问题描述
我使用 Drools 7 作为规则引擎。最初,我使用以下代码从类路径加载规则以构建 StatelessKieSession:
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
StatelessKieSession statelessKieSession = kContainer.newStatelessKieSession();
然后我决定从数据库加载规则,代码如下:
KnowledgeBuilder knowledgeBuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
SqlRowSet sqlRowSet = new JdbcTemplate(ds).queryForRowSet("select drl_code from rule");
while(sqlRowSet.next()) {
Resource r = ResourceFactory.newReaderResource(new StringReader(sqlRowSet.getString("drl_code")));
knowledgeBuilder.add(r, ResourceType.DRL);
}
KieBase kieBase = knowledgeBuilder.newKieBase();
StatelessKieSession statelessKieSession = kieBase.newStatelessKieSession();
让我担心的是 KnowledgeBuilder 接口在一个内部包中(“org.kie.internal”)。
使用“公共”API 从数据库加载规则时,是否有另一种方法来构建 StatelessKieSession?
解决方案
类似的情况我做了如下。我使用从 MYSQL 加载我的规则。
public void reloadRules() {
// TODO Auto-generated method stub
List<DroolsDrlModel> droolsDrlModels = droolsDrlDao.findAll();
KieContainer kieContainer = loadDroolsSessionContainer(droolsDrlModels);
this.kieContainer=kieContainer;
KieSession kieSession = this.kieContainer.newKieSession();
Thread t1 = new Thread(new Runnable() {
public void run() {
kieSession.fireUntilHalt();
}
});
t1.start();
}
public KieContainer loadDroolsSessionContainer(List<DroolsDrlModel> droolsDrlModels){
long startTime = System.currentTimeMillis();
if(this.kieServices == null){
this.kieServices = KieServices.Factory.get();
}
// add following if you are using timer in your rules
KieSessionConfiguration ksconf = kieServices.newKieSessionConfiguration();
ksconf.setOption(TimedRuleExecutionOption.YES);
KieRepository kr = kieServices.getRepository();
KieFileSystem kfs = kieServices.newKieFileSystem();
for(DroolsDrlModel drlModel:droolsDrlModels){
kfs.delete("src/main/resources/" + drlModel.getRuleFileName() + ".drl");
LOGGER.info("Drools DRL was deleted sucessfully"+drlModel.getRuleFileName());
kfs.write("src/main/resources/" + drlModel.getRuleFileName() + ".drl", drlModel.getDroolContent());
LOGGER.info("Drools DRL was created sucessfully "+drlModel.getRuleFileName());
}
KieBuilder kb = kieServices.newKieBuilder(kfs);
kb.buildAll();
if (kb.getResults().hasMessages(Message.Level.ERROR)) {
throw new RuntimeException("Build Errors:\n" + kb.getResults().toString());
}
long endTime = System.currentTimeMillis();
LOGGER.info("Time to build rules : " + (endTime - startTime) + " ms" );
startTime = System.currentTimeMillis();
KieContainer kContainer = kieServices.newKieContainer(kr.getDefaultReleaseId());
endTime = System.currentTimeMillis();
LOGGER.info("Time to load container: " + (endTime - startTime) + " ms" );
return kContainer;
}
还有我的 DroolDrl 模型
@Entity(name="rules_table")
public class DroolsDrlModel{
@Column(name = "drl_file_name")
private String ruleFileName;
@Column(name = "drl_content")
private String droolContent;
@Column(name = "version")
private int version;
// getter and setters
推荐阅读
- javascript - TypeError:无法读取未定义 React.js 的属性“项目”
- python - TensorFlow 1.19.5 需要什么版本的 Numpy?
- javascript - 如何添加“大约几分钟前、大约几小时前等;” 在 .filter 中用于 angular/ionic v1 项目
- c# - 我可以通过 Blazor 组件更新 DateTime
- javascript - 使用带有 JQuery 的 XML 文件自动完成输入
- apache-spark - 计算比例 Py(Spark) 的置信区间
- architecture - 如何在新增的微服务中实现数据一致性?
- php - IMAP PHP 中不显示新电子邮件
- logstash - logstash中有这么多变量
- blazor - Blazor 服务器强制缓存重新加载