首页 > 解决方案 > 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?

标签: javadrools

解决方案


类似的情况我做了如下。我使用从 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

推荐阅读