drools详解

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;

/**  
 * @Description:将下面的两给drl字符串,其实可以放进数据库中,或者有专门的机制来维护这个字符串,
 * 后面直接读取这个字符串(其实就是drl文件),那么就可以实现动态加载了,缺点是,偏技术,业务人员看不懂
 * @Author: wumingdu
 * @Date: 2022/5/26 13:38
 */
public class DdLoadTest {
   
	public static void main(String[] args) {
   
		//rule,rule2可以放在数据库中,有个唯一code和他们对于,代码要执行规则的时候,根据code从数据库获取出来就OK了,这样自己开发的规则管理系统那边对数据库里的规则进行维护就行了
		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文件,将其动态的转换成字符串,这段代码很牛掰

	/**
     * 规则文件,决策表解析成字符串
     * @param realPath  决策表路径
     * @return  字符串
     */
    public String encodeToString(String realPath) {
   
        File file = new File(realPath);
        if (!file.exists()) {
   
            return null;
        }
        // drl文件
        if (realPath.endsWith(SUFFIX_DRL)) {
   
            return read(file);
        }
        InputStream is = null;
        try {
   
            is = new FileInputStream(file);
        } catch (FileNotFoundException e) {
   
            logger.error("file not fount.");
        }
        // excel文件 xls和xlsx都支持
        // @author <a href="mailto:312182539@qq.com">fbf</a>
        if (realPath.endsWith(SUFFIX_EXCEL)||realPath.endsWith(SUFFIX_EXCEL_2007)) {
   
            return new SpreadsheetCompiler().compile(is, InputType.XLS);
        }
        // csv文件
        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;";
    }



	/**
     * 读取drl文件
     */
    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;
    }



	//这里还有很重要的一步,不管是excel,还是drl,最终会变解析为字符串
	//这个字符串是需要被解析运行的,如下:
	
	/**
     * 把字符串解析成KieSession
     * @param drl   规则文件字符串
     * @return  KieSession
     */
    public KieSession decodeToSession(String... drl) {
   
        KieHelper kieHelper = new KieHelper();
        for 
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值