Drools-決策表使用1-快速開始


前言

決策表(decision-table)即以xls表格的形式定義規則,而不再是只有開發人員能看懂的drl文本。
對業務人員來說,這種EXCEL表格肯定是友好的;對開發人員而言,需要使用官方API將xls內容“翻譯”為熟悉的drl串,即編譯器SpreadsheetCompiler

快速開始

  • 新建Maven工程
    <drools.version>7.42.0.Final</drools.version>
    
    <dependency>
    	<groupId>org.drools</groupId>
    	<artifactId>drools-decisiontables</artifactId>
    </dependency>
    
  • 項目結構圖
    image
  • 本次測試實體類
    @Data
    @Accessors(chain = true)
    public class PersonInfoEntity {
    	private String sex;
    	private int age;
    	private double salary;
    }
    
  • xls規則文件參考
    image
  • 開始:直接從類路徑讀取xls規則文件
    /**
     * 直接從類路徑找到目標xls文件,翻譯,加載,觸發
     */
    @Test
    public void test() {
    	String classPath = "testRule.xls";
    	SpreadsheetCompiler compiler = new SpreadsheetCompiler();
    
    	//文件讀取與編譯
    	InputStream is = this.getClass().getClassLoader().getResourceAsStream(classPath);
    	String drl = compiler.compile(is, InputType.XLS);
    	log.info("解析出的drl文本:\n{}", drl);
    	
    	//載入規則
    	KieHelper kieHelper = new KieHelper();
    	kieHelper.addContent(drl, ResourceType.DRL);
    	
    	//定義fact
    	PersonInfoEntity personInfoEntity = new PersonInfoEntity();
    	personInfoEntity.setSex("女").setAge(35).setSalary(1000);
    
    	//創建會話,fact插入工作內存,觸發
    	KieSession session = kieHelper.build().newKieSession();
    	List<String> list = new ArrayList<String>();
    	session.setGlobal("listRules", list);
    	session.insert(personInfoEntity);
    	session.getAgenda().getAgendaGroup("sign").setFocus();
    	session.fireAllRules();
    	for (String s : list) {
    		log.info("輸出結果:{}", s);
    	}
    	
    	//關閉會話
    	session.dispose();
    }
    
  • 改進1:切換讀取指定路徑的磁盤xls文件
    /**
     * 直接從類路徑找到目標xls文件,翻譯,加載,觸發
     */
    @Test
    public void test() {
    	String classPath = "testRule.xls";
    	String fsp = "D:/temp/testRule.xls";
    
    	//文件讀取與編譯
        //String drl = readXlsDrl("cp", classPath);
    	String drl = readXlsDrl("fs", fsp);
    	
    	//載入規則
    	KieHelper kieHelper = new KieHelper();
    	kieHelper.addContent(drl, ResourceType.DRL);
    	...
    }
    
    private String readXlsDrl(String type, String path) {
    	InputStream is = null;
    	if("cp".equals(type)) {
    		is = this.getClass().getClassLoader().getResourceAsStream(path);
    	}else if("fs".equals(type)) {
    		try {
    			is = new FileInputStream(new File(path));
    		} catch (FileNotFoundException e) {
    			log.error("文件讀取異常", e);
    			throw new RuntimeException("文件讀取異常", e);
    		}
    	}
    	SpreadsheetCompiler compiler = new SpreadsheetCompiler();
    	String drl = compiler.compile(is, InputType.XLS);
    	log.info("解析出的drl文本:\n{}", drl);
    	return drl;
    }
    
  • 改進2:添加顯式的drl語法檢查
    @Test
    public void test() {
    	String classPath = "testRule.xls";
    	String fsp = "D:/temp/testRule.xls";
    
    	//文件讀取與編譯
        // String drl = readXlsDrl("cp", classPath);
    	String drl = readXlsDrl("fs", fsp);
    	
    	//載入規則
    	KieHelper kieHelper = new KieHelper();
    	kieHelper.addContent(drl, ResourceType.DRL);
    	
    	//drl文本語法校驗
    	verifyDrl(kieHelper);
    	...
    }
    
    private void verifyDrl(KieHelper kieHelper) {
    	Results verify = kieHelper.verify();
    	if (verify.hasMessages(Message.Level.WARNING, Message.Level.ERROR)) {
    		List<Message> messages = verify.getMessages(Message.Level.WARNING, Message.Level.ERROR);
    		for (Message message : messages) {
    			log.error("Error: " + message.getText());
    		}
    		throw new IllegalStateException("Compilation errors were found. Check the logs.");
    	}
    }
    

小結

  • 從API可以看出
    • Drools同時也支持從CSV文件讀取規則定義
    • 支持任意來源的drl文本串,即初版(見下方demo源碼同級工程)的將.drl文件內容直接放置數據庫,全權交給開發人員維護
  • 官方文檔不太友好,冗長且沒有xls模板下載,下方有整理的參考資料

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM