关于drools的简单笔记

一、什么是drools

简单回答就是把代码变成配置文件,原来写在java类里的东西,现在全部帮到配置文件里。

二、配置文件是什么

配置文件可以是drl结尾的文件,也可以是excel表,现在比较流行的是使用excel表。

三、drools如何调用

首先读取excel表的配置文件,这个叫做初始化。

初始化完成后,需要相应的实体bean用来传递参数供规则判断

如果是drl规则的写法和java类型

如果是excel那就简单的多,可以百度drools excel模板

需要注意的是,如果要使用drools一定要首先初始化,即加载规则。

另外还可以配置刷新规则,即重新加载配置文件。

下面是使用drl作为配置文件的源码。

bean PointDomain.java

package com.drools.demo.point;


/**
 * 积分计算对象
 * @author quzishen
 */
public class PointDomain {
	// 用户名
	private String userName;
	// 是否当日生日
	private boolean birthDay;
	// 增加积分数目
	private long point;
	// 当月购物次数
	private int buyNums;
	// 当月退货次数
	private int backNums;
	// 当月购物总金额
	private double buyMoney;
	// 当月退货总金额
	private double backMondy;
	// 当月信用卡还款次数
	private int billThisMonth;
	
	/**
	 * 记录积分发送流水,防止重复发放
	 * @param userName 用户名
	 * @param type 积分发放类型
	 */
	public void recordPointLog(String userName, String type){
		System.out.println("增加对"+userName+"的类型为"+type+"的积分操作记录.");
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public boolean isBirthDay() {
		return birthDay;
	}

	public void setBirthDay(boolean birthDay) {
		this.birthDay = birthDay;
	}

	public long getPoint() {
		return point;
	}

	public void setPoint(long point) {
		this.point = point;
	}

	public int getBuyNums() {
		return buyNums;
	}

	public void setBuyNums(int buyNums) {
		this.buyNums = buyNums;
	}

	public int getBackNums() {
		return backNums;
	}

	public void setBackNums(int backNums) {
		this.backNums = backNums;
	}

	public double getBuyMoney() {
		return buyMoney;
	}

	public void setBuyMoney(double buyMoney) {
		this.buyMoney = buyMoney;
	}

	public double getBackMondy() {
		return backMondy;
	}

	public void setBackMondy(double backMondy) {
		this.backMondy = backMondy;
	}

	public int getBillThisMonth() {
		return billThisMonth;
	}

	public void setBillThisMonth(int billThisMonth) {
		this.billThisMonth = billThisMonth;
	}

}

PointRuleEngine.java

package com.drools.demo.point;

/**
 * 规则接口
 * @author quzishen
 */
public interface PointRuleEngine {
	
	/**
	 * 初始化规则引擎
	 */
	public void initEngine();
	
	/**
	 * 刷新规则引擎中的规则
	 */
	public void refreshEnginRule();
	
	/**
	 * 执行规则引擎
	 * @param pointDomain 积分Fact
	 */
	public void executeRuleEngine(final PointDomain pointDomain);
}

PointRuleEngineImpl.java

package com.drools.demo.point;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;

import org.drools.RuleBase;
import org.drools.StatefulSession;
import org.drools.compiler.DroolsParserException;
import org.drools.compiler.PackageBuilder;
import org.drools.spi.Activation;

/**
 * 规则接口实现类
 * @author quzishen
 */
public class PointRuleEngineImpl implements PointRuleEngine {
	private RuleBase ruleBase;

	/* (non-Javadoc)
	 * @see com.drools.demo.point.PointRuleEngine#initEngine()
	 */
	public void initEngine() {
		// 设置时间格式
		System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
		ruleBase = RuleBaseFacatory.getRuleBase();
		try {
			PackageBuilder backageBuilder = getPackageBuilderFromDrlFile();
			ruleBase.addPackages(backageBuilder.getPackages());
		} catch (DroolsParserException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/* (non-Javadoc)
	 * @see com.drools.demo.point.PointRuleEngine#refreshEnginRule()
	 */
	public void refreshEnginRule() {
		ruleBase = RuleBaseFacatory.getRuleBase();
		org.drools.rule.Package[] packages = ruleBase.getPackages();
		for(org.drools.rule.Package pg : packages) {
			ruleBase.removePackage(pg.getName());
		}
		
		initEngine();
	}

	/* (non-Javadoc)
	 * @see com.drools.demo.point.PointRuleEngine#executeRuleEngine(com.drools.demo.point.PointDomain)
	 */
	public void executeRuleEngine(final PointDomain pointDomain) {
		if(null == ruleBase.getPackages() || 0 == ruleBase.getPackages().length) {
			return;
		}
		
		StatefulSession statefulSession = ruleBase.newStatefulSession();
		statefulSession.insert(pointDomain);
		
		// fire
		statefulSession.fireAllRules(new org.drools.spi.AgendaFilter() {
			public boolean accept(Activation activation) {
				return !activation.getRule().getName().contains("_test");
			}
		});
		
		statefulSession.dispose();
	}

	/**
	 * 从Drl规则文件中读取规则
	 * @return
	 * @throws Exception
	 */
	private PackageBuilder getPackageBuilderFromDrlFile() throws Exception {
		// 获取测试脚本文件
		List<String> drlFilePath = getTestDrlFile();
		// 装载测试脚本文件
		List<Reader> readers = readRuleFromDrlFile(drlFilePath);

		PackageBuilder backageBuilder = new PackageBuilder();
		for (Reader r : readers) {
			backageBuilder.addPackageFromDrl(r);
		}
		
		// 检查脚本是否有问题
		if(backageBuilder.hasErrors()) {
			throw new Exception(backageBuilder.getErrors().toString());
		}
		
		return backageBuilder;
	}

	/**
	 * @param drlFilePath 脚本文件路径
	 * @return
	 * @throws FileNotFoundException
	 */
	private List<Reader> readRuleFromDrlFile(List<String> drlFilePath) throws FileNotFoundException {
		if (null == drlFilePath || 0 == drlFilePath.size()) {
			return null;
		}

		List<Reader> readers = new ArrayList<Reader>();

		for (String ruleFilePath : drlFilePath) {
			readers.add(new FileReader(new File(ruleFilePath)));
		}

		return readers;
	}

	/**
	 * 获取测试规则文件
	 * 
	 * @return
	 */
	private List<String> getTestDrlFile() {
		List<String> drlFilePath = new ArrayList<String>();
		drlFilePath
				.add("D:/0_eclipse/DroolsDemo/src/com/drools/demo/point/addpoint.drl");
		drlFilePath
				.add("D:/0_eclipse/DroolsDemo/src/com/drools/demo/point/subpoint.drl");

		return drlFilePath;
	}
}

RuleBaseFacatory.java

package com.drools.demo.point;

import org.drools.RuleBase;
import org.drools.RuleBaseFactory;

/**
 * RuleBaseFacatory 单实例RuleBase生成工具
 * @author quzishen
 */
public class RuleBaseFacatory {
	private static RuleBase ruleBase;
	
	public static RuleBase getRuleBase(){
		return null != ruleBase ? ruleBase : RuleBaseFactory.newRuleBase();
	}
}

Test.java

package com.drools.demo.point;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;


public class Test {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		PointRuleEngine pointRuleEngine = new PointRuleEngineImpl();
		while(true){
			InputStream is = System.in;
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			String input = br.readLine();
			
			if(null != input && "s".equals(input)){
				System.out.println("初始化规则引擎...");
				pointRuleEngine.initEngine();
				System.out.println("初始化规则引擎结束.");
			}else if("e".equals(input)){
				final PointDomain pointDomain = new PointDomain();
				pointDomain.setUserName("hello kity");
				pointDomain.setBackMondy(100d);
				pointDomain.setBuyMoney(500d);
				pointDomain.setBackNums(1);
				pointDomain.setBuyNums(5);
				pointDomain.setBillThisMonth(5);
				pointDomain.setBirthDay(true);
				pointDomain.setPoint(0l);
				
				pointRuleEngine.executeRuleEngine(pointDomain);
				
				System.out.println("执行完毕BillThisMonth:"+pointDomain.getBillThisMonth());
				System.out.println("执行完毕BuyMoney:"+pointDomain.getBuyMoney());
				System.out.println("执行完毕BuyNums:"+pointDomain.getBuyNums());
				
				System.out.println("执行完毕规则引擎决定发送积分:"+pointDomain.getPoint());
			} else if("r".equals(input)){
				System.out.println("刷新规则文件...");
				pointRuleEngine.refreshEnginRule();
				System.out.println("刷新规则文件结束.");
			}
		}
	}

}

addpoint.drl

package com.drools.demo.point

import com.drools.demo.point.PointDomain;

rule birthdayPoint
	// 过生日,则加10分,并且将当月交易比数翻倍后再计算积分
	salience 100   
	//salience 优先级,数值越大越先执行,这个可以控制规则的执行顺序。
	lock-on-active true
	when
		$pointDomain : PointDomain(birthDay == true)
	then
		$pointDomain.setPoint($pointDomain.getPoint()+10);
		$pointDomain.setBuyNums($pointDomain.getBuyNums()*2);
		$pointDomain.setBuyMoney($pointDomain.getBuyMoney()*2);
		$pointDomain.setBillThisMonth($pointDomain.getBillThisMonth()*2);
		
		$pointDomain.recordPointLog($pointDomain.getUserName(),"birthdayPoint");
end

rule billThisMonthPoint
	// 2011-01-08 - 2011-08-08每月信用卡还款3次以上,每满3笔赠送30分
	salience 99
	lock-on-active true
	date-effective "2011-01-08 23:59:59"
	date-expires "2011-08-08 23:59:59"
	when
		$pointDomain : PointDomain(billThisMonth >= 3)
	then
		$pointDomain.setPoint($pointDomain.getPoint()+$pointDomain.getBillThisMonth()/3*30);
		$pointDomain.recordPointLog($pointDomain.getUserName(),"billThisMonthPoint");
end

rule buyMoneyPoint
	// 当月购物总金额100以上,每100元赠送10分
	salience 98
	lock-on-active true
	when
		$pointDomain : PointDomain(buyMoney >= 100)
	then
		$pointDomain.setPoint($pointDomain.getPoint()+ (int)$pointDomain.getBuyMoney()/100 * 10);
		$pointDomain.recordPointLog($pointDomain.getUserName(),"buyMoneyPoint");
end

rule buyNumsPoint
	// 当月购物次数5次以上,每五次赠送50分
	salience 97
	lock-on-active true
	when
		$pointDomain : PointDomain(buyNums >= 5)
	then
		$pointDomain.setPoint($pointDomain.getPoint()+$pointDomain.getBuyNums()/5 * 50);
		$pointDomain.recordPointLog($pointDomain.getUserName(),"buyNumsPoint");
end

rule allFitPoint
	// 特别的,如果全部满足了要求,则额外奖励100分
	salience 96
	lock-on-active true
	when
		$pointDomain:PointDomain(buyNums >= 5 && billThisMonth >= 3 && buyMoney >= 100)
	then
		$pointDomain.setPoint($pointDomain.getPoint()+ 100);
		$pointDomain.recordPointLog($pointDomain.getUserName(),"allFitPoint");
end

subpoint.drl

package com.drools.demo.point

import com.drools.demo.point.PointDomain;

rule subBackNumsPoint
	// 发生退货,扣减10分
	salience 10
	lock-on-active true
	when
		$pointDomain : PointDomain(backNums >= 1)
	then
		$pointDomain.setPoint($pointDomain.getPoint()-10);
		$pointDomain.recordPointLog($pointDomain.getUserName(),"subBackNumsPoint");
end

rule subBackMondyPoint
	// 退货金额大于100,扣减100分
	salience 9
	lock-on-active true
	when
		$pointDomain : PointDomain(backMondy >= 100)
	then
		$pointDomain.setPoint($pointDomain.getPoint()-10);
		$pointDomain.recordPointLog($pointDomain.getUserName(),"subBackMondyPoint");
end


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值