`
ivan19861025
  • 浏览: 42065 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

drools 学习之旅 <一>

    博客分类:
  • Java
阅读更多

 

先说一下我们的场景:

假如我们现在要给网站举办活动(奖励额外积分), 活动规则如下:

规则如下: 订单原价金额在

100以下, 不加分 

100-500 加100分 

500-1000 加500分 

1000 以上 加1000分

 

我们可能这样编码:

package com.league.drools.pojo;

import java.util.Date;

public class Order {
	
	private Date bookingDate;//下单日期
	
	private int amout;//订单原价金额
	
	private User user;//下单人
	
	private int score;
	
	public int getScore() {
		return score;
	}

	public void setScore(int score) {
		this.score = score;
	}

	public Date getBookingDate() {
		return bookingDate;
	}

	public void setBookingDate(Date bookingDate) {
		this.bookingDate = bookingDate;
	}

	public int getAmout() {
		return amout;
	}

	public void setAmout(int amout) {
		this.amout = amout;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}
	
	
	
	
	
}

 

package com.league.drools.pojo;

public class User {
	
	private String name;//姓名
	
	private int level;//用户级别

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getLevel() {
		return level;
	}

	public void setLevel(int level) {
		this.level = level;
	}
	
	
	
}

 

package com.league.drools.demo1;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import com.league.drools.pojo.Order;
import com.league.drools.pojo.User;

public class App {
	
	public static void main(String[] args) throws Exception {
		
		List<Order> orderList = getInitData();
		for (int i=0; i<orderList.size(); i++){
			Order order = orderList.get(i);
			if (order.getAmout() <= 100){
				order.setScore(0);
				addScore(order);
			}else if(order.getAmout() > 100 && order.getAmout() <= 500){
				order.setScore(100);
				addScore(order);
			}else if(order.getAmout() > 500 && order.getAmout() <= 1000){
				order.setScore(500);
				addScore(order);
			}else{
				order.setScore(1000);
				addScore(order);
			}
		}
		
	}
	
	private static void addScore(Order o){
		System.out.println("用户" + o.getUser().getName() + "享受额外增加积分: " + o.getScore());
	}
	
	private static List<Order> getInitData() throws Exception {
		List<Order> orderList = new ArrayList<Order>();
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		{
			Order order = new Order();
			order.setAmout(80);
			order.setBookingDate(df.parse("2015-07-01"));
			User user = new User();
			user.setLevel(1);
			user.setName("Name1");
			order.setUser(user);
			orderList.add(order);
		}
		{
			Order order = new Order();
			order.setAmout(200);
			order.setBookingDate(df.parse("2015-07-02"));
			User user = new User();
			user.setLevel(2);
			user.setName("Name2");
			order.setUser(user);
			orderList.add(order);
		}
		{
			Order order = new Order();
			order.setAmout(800);
			order.setBookingDate(df.parse("2015-07-03"));
			User user = new User();
			user.setLevel(3);
			user.setName("Name3");
			order.setUser(user);
			orderList.add(order);
		}
		{
			Order order = new Order();
			order.setAmout(1500);
			order.setBookingDate(df.parse("2015-07-04"));
			User user = new User();
			user.setLevel(4);
			user.setName("Name4");
			order.setUser(user);
			orderList.add(order);
		}
		return orderList;
	}
}

 运行结果:

用户Name1享受额外增加积分: 0
用户Name2享受额外增加积分: 100
用户Name3享受额外增加积分: 500
用户Name4享受额外增加积分: 1000

 那么当

用户需求变更时, 比如只有用户等级为2以上的会员才能享受此活动资格.

那么此时必须更改以前的代码, 在if前加上会员级别的判断,然后开发, 测试, 生产部署,走发布版本的流程.

而商家经常搞活动, 那么我们的产品就不得不经常因为这种规则变更而发布新的版本来支持当前的业务.

 

此时, 我们就可以使用规则引擎(Drools)来解决此类问题.

 

Drools是一个基于java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件,数据等介质中,使得规则的变更不需要修正代码甚至不需要重启机器就可以立即在线上环境生效。

 

OK, 直接上相关代码.

package com.league.drools.demo1;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseConfiguration;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.definition.KnowledgePackage;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatefulKnowledgeSession;

import com.league.drools.pojo.Order;
import com.league.drools.pojo.User;

public class App1 {

	/**
	 * 计算额外积分金额 规则如下: 订单原价金额 
	 * 100以下, 不加分 
	 * 100-500 加100分 
	 * 500-1000 加500分 
	 * 1000 以上 加1000分
	 * 
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder();
		builder.add(ResourceFactory.newClassPathResource("rules/point-rules.drl"), ResourceType.DRL);

		if (builder.hasErrors()) {
			System.out.println("规则中存在错误,错误消息如下:");
			KnowledgeBuilderErrors kbuidlerErrors = builder.getErrors();
			for (Iterator iter = kbuidlerErrors.iterator(); iter.hasNext();) {
				System.out.println(iter.next());
			}
			return;
		}

		Collection<KnowledgePackage> packages = builder.getKnowledgePackages();
		KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
		kbase.addKnowledgePackages(packages);

		StatefulKnowledgeSession session = kbase.newStatefulKnowledgeSession();

		List<Order> orderList = getInitData();

		for (int i = 0; i < orderList.size(); i++) {
			Order o = orderList.get(i);
			session.insert(o);
			session.fireAllRules();
			// 执行完规则后, 执行相关的逻辑
			addScore(o);
		}

		session.dispose();
	}

	private static void addScore(Order o){
		System.out.println("用户" + o.getUser().getName() + "享受额外增加积分: " + o.getScore());
	}
	
	private static List<Order> getInitData() throws Exception {
		List<Order> orderList = new ArrayList<Order>();
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		{
			Order order = new Order();
			order.setAmout(80);
			order.setBookingDate(df.parse("2015-07-01"));
			User user = new User();
			user.setLevel(1);
			user.setName("Name1");
			order.setUser(user);
			orderList.add(order);
		}
		{
			Order order = new Order();
			order.setAmout(200);
			order.setBookingDate(df.parse("2015-07-02"));
			User user = new User();
			user.setLevel(2);
			user.setName("Name2");
			order.setUser(user);
			orderList.add(order);
		}
		{
			Order order = new Order();
			order.setAmout(800);
			order.setBookingDate(df.parse("2015-07-03"));
			User user = new User();
			user.setLevel(3);
			user.setName("Name3");
			order.setUser(user);
			orderList.add(order);
		}
		{
			Order order = new Order();
			order.setAmout(1500);
			order.setBookingDate(df.parse("2015-07-04"));
			User user = new User();
			user.setLevel(4);
			user.setName("Name4");
			order.setUser(user);
			orderList.add(order);
		}
		return orderList;
	}
}
package rules

import com.league.drools.pojo.Order
import com.league.drools.pojo.User

rule "zero"   
    no-loop true
    lock-on-active true
    salience 1
    when
        $s : Order(amout <= 100)
    then
        $s.setScore(0);
        update($s);
end

rule "add100"   
    no-loop true
    lock-on-active true
    salience 1
    when
        $s : Order(amout > 100 && amout <= 500)
    then
        $s.setScore(100);
        update($s);
end

rule "add500"   
    no-loop true
    lock-on-active true
    salience 1
    when
        $s : Order(amout > 500 && amout <= 1000)
    then
        $s.setScore(500);
        update($s);
end

rule "add1000"   
    no-loop true
    lock-on-active true
    salience 1
    when
        $s : Order(amout > 1000)
    then
        $s.setScore(1000);
        update($s);
end

 

运行结果如下:

用户Name1享受额外增加积分: 0
用户Name2享受额外增加积分: 100
用户Name3享受额外增加积分: 500
用户Name4享受额外增加积分: 1000

 

如果更改活动规则, 只需要更改drl文件. 重启应用即可.

 

 

附MAVEN依赖如下:

 

<dependencies>
		<dependency>
			<groupId>org.drools</groupId>
			<artifactId>drools-core</artifactId>
			<version>5.6.0.Final</version>
		</dependency>
		<dependency> 
            <groupId>org.drools</groupId>
            <artifactId>drools-compiler</artifactId>
            <version>5.6.0.Final</version>
        </dependency>
        <dependency> 
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.9</version>
        </dependency>

 

 

 

 

分享到:
评论
3 楼 ivan19861025 2016-11-04  
步入低谷的浪神 写道
大神,能不能把你的包截图看看,都不知道哪个文件是放在哪个包里面的,我Eclipse的drools环境搭好了之后创建的drools项目的包都是自动分配好的,每个文件应该放哪都不知道!

会报错吗? 包放哪没有限制, 根据自已项目的规范即可.
2 楼 步入低谷的浪神 2016-10-27  
大神,能不能把你的包截图看看,都不知道哪个文件是放在哪个包里面的,我Eclipse的drools环境搭好了之后创建的drools项目的包都是自动分配好的,每个文件应该放哪都不知道!
1 楼 ivan19861025 2015-09-07  
模拟动态加载规则
package com.league.drools.demo1;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.definition.KnowledgePackage;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatefulKnowledgeSession;

import com.league.drools.pojo.Order;
import com.league.drools.pojo.User;

public class App2 {

	/**
	 * 计算额外积分金额 原始规则如下: 订单原价金额 
	 * 100以下, 不加分 
	 * 100-500 加100分 
	 * 500-1000 加500分 
	 * 1000 以上 加1000分
	 * 修改规则如下:
	 * 订单原价金额 
	 * 100以下 且 user.level = 4, 不加分 
	 * 100-500 且 user.level = 4 加100分 
	 * 500-1000 且 user.level = 4 加500分 
	 * 1000 以上 且 user.level = 4 加1000分
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder();
		builder.add(ResourceFactory.newClassPathResource("rules/point-rules.drl"), ResourceType.DRL);

		if (builder.hasErrors()) {
			System.out.println("规则中存在错误,错误消息如下:");
			KnowledgeBuilderErrors kbuidlerErrors = builder.getErrors();
			for (Iterator iter = kbuidlerErrors.iterator(); iter.hasNext();) {
				System.out.println(iter.next());
			}
			return;
		}

		Collection<KnowledgePackage> packages = builder.getKnowledgePackages();
		KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
		kbase.addKnowledgePackages(packages);

		StatefulKnowledgeSession session = kbase.newStatefulKnowledgeSession();

		List<Order> orderList = getInitData();

		for (int i = 0; i < orderList.size(); i++) {
			Order o = orderList.get(i);
			session.insert(o);
			session.fireAllRules();
			
			// 执行完规则后, 执行相关的逻辑
			addScore(o);
		}
		
		System.out.println("=======使用新的规则后=========");
		//使用新的规则
		kbase.removeKnowledgePackage(((KnowledgePackage)packages.toArray()[0]).getName());//原来的包remove
		KnowledgeBuilder builder1 = KnowledgeBuilderFactory.newKnowledgeBuilder();
		builder1.add(ResourceFactory.newClassPathResource("rules/point-rules-v1.drl"), ResourceType.DRL);
		kbase.addKnowledgePackages(builder1.getKnowledgePackages());//添加新的包
		
		orderList = getInitData();

		for (int i = 0; i < orderList.size(); i++) {
			Order o = orderList.get(i);
			session.insert(o);
			session.fireAllRules();
			
			// 执行完规则后, 执行相关的逻辑
			addScore(o);
		}
		
		session.dispose();
	}

	private static void addScore(Order o){
		System.out.println("用户" + o.getUser().getName() + "享受额外增加积分: " + o.getScore());
	}
	
	private static List<Order> getInitData() throws Exception {
		List<Order> orderList = new ArrayList<Order>();
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		{
			Order order = new Order();
			order.setAmout(80);
			order.setBookingDate(df.parse("2015-07-01"));
			User user = new User();
			user.setLevel(1);
			user.setName("Name1");
			order.setUser(user);
			orderList.add(order);
		}
		{
			Order order = new Order();
			order.setAmout(200);
			order.setBookingDate(df.parse("2015-07-02"));
			User user = new User();
			user.setLevel(2);
			user.setName("Name2");
			order.setUser(user);
			orderList.add(order);
		}
		{
			Order order = new Order();
			order.setAmout(800);
			order.setBookingDate(df.parse("2015-07-03"));
			User user = new User();
			user.setLevel(3);
			user.setName("Name3");
			order.setUser(user);
			orderList.add(order);
		}
		{
			Order order = new Order();
			order.setAmout(1500);
			order.setBookingDate(df.parse("2015-07-04"));
			User user = new User();
			user.setLevel(4);
			user.setName("Name4");
			order.setUser(user);
			orderList.add(order);
		}
		return orderList;
	}
}



package rules

import com.league.drools.pojo.Order
import com.league.drools.pojo.User

rule "zero"   
    no-loop true
    lock-on-active true
    salience 1
    when
        $s : Order(user.level == 4 && amout <= 100)
    then
        $s.setScore(0);
        update($s);
end

rule "add100"   
    no-loop true
    lock-on-active true
    salience 1
    when
        $s : Order(user.level == 4 && amout > 100 && amout <= 500)
    then
        $s.setScore(100);
        update($s);
end

rule "add500"   
    no-loop true
    lock-on-active true
    salience 1
    when
        $s : Order(user.level == 4 && amout > 500 && amout <= 1000)
    then
        $s.setScore(500);
        update($s);
end

rule "add1000"   
    no-loop true
    lock-on-active true
    salience 1
    when
        $s : Order(user.level == 4 && amout > 1000)
    then
        $s.setScore(1000);
        update($s);
end

相关推荐

    Ecplise下用maven建drools web项目

    &lt;groupId&gt;org.drools&lt;/groupId&gt; &lt;artifactId&gt;drools-core&lt;/artifactId&gt; &lt;version&gt;6.0.0.Final&lt;/version&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.drools&lt;/groupId&gt; &lt;artifactId&gt;drools-compiler&lt;/...

    drools6.5规则引擎封装实例

    &lt;groupId&gt;org.drools&lt;/groupId&gt; &lt;artifactId&gt;drools-core&lt;/artifactId&gt; &lt;version&gt;6.5.0.Final&lt;/version&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.drools&lt;/groupId&gt; &lt;artifactId&gt;drools-compiler&lt;/artifactId&gt;...

    Drools入门-----------环境搭建,分析Helloworld

    &lt;groupId&gt;org.drools&lt;/groupId&gt; &lt;artifactId&gt;drools-core&lt;/artifactId&gt; &lt;version&gt;7.x.y&lt;/version&gt; &lt;!-- 替换为实际版本 --&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.drools&lt;/groupId&gt; &lt;artifactId&gt;drools-...

    springboot集成drools实现重新加载规则

    &lt;version&gt;${drools.version}&lt;/version&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.kie&lt;/groupId&gt; &lt;artifactId&gt;kie-api&lt;/artifactId&gt; &lt;version&gt;${drools.version}&lt;/version&gt; &lt;/dependency&gt; &lt;dependency&gt; ...

    基于Spring + Drools6.4规则引擎代码实例.

    &lt;groupId&gt;org.drools&lt;/groupId&gt; &lt;artifactId&gt;drools-core&lt;/artifactId&gt; &lt;version&gt;${drools-version}&lt;/version&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.drools&lt;/groupId&gt; &lt;artifactId&gt;drools-compiler&lt;/...

    Drools6-笔记

    &lt;artifactId&gt;drools-core&lt;/artifactId&gt; &lt;version&gt;6.5.0.Final&lt;/version&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;junit&lt;/groupId&gt; &lt;artifactId&gt;junit&lt;/artifactId&gt; &lt;version&gt;4.12&lt;/version&gt; &lt;scope&gt;test&lt;/...

    junit-drools:用于Drools6的JUnit Runner

    只需将其包含在您的pom中即可: &lt; dependency&gt;&lt; groupId&gt;com.github.jeichler&lt;/ groupId&gt;&lt; artifactId&gt;junit-drools&lt;/ artifactId&gt;&lt; version&gt;1.0&lt;/ version&gt;&lt; scope&gt;test&lt;/ scope&gt;&lt;/ dependency&gt; 然后,您可以立即...

    springboot+drools动态模板引擎

    &lt;groupId&gt;org.kie&lt;/groupId&gt; &lt;artifactId&gt;kie-spring&lt;/artifactId&gt; &lt;version&gt;版本号&lt;/version&gt; &lt;/dependency&gt; ``` 确保选择与SpringBoot兼容的Drools版本。 接下来,我们需要创建Drools的规则文件(`.drl`)。...

    流口水:使用drools实现规则模板引擎

    &lt;groupId&gt;org.drools&lt;/groupId&gt; &lt;artifactId&gt;drools-core&lt;/artifactId&gt; &lt;version&gt;7.x.x.Final&lt;/version&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.drools&lt;/groupId&gt; &lt;artifactId&gt;drools-compiler&lt;/...

    从Drools规则引擎到风控反洗钱系统V0.2.3

    其中,Drools是最流行的开源规则引擎之一,而VisualRules和ILog则是知名的商业解决方案。 **1.2 Drools规则引擎** Drools是一款开源的业务规则管理系统(BRMS),它使用了Charles Forgy的RETE算法,这是一种高效的...

    Drools学习笔记

    - 指定规则文件路径,在`&lt;build&gt;`标签内添加资源目录,如`&lt;directory&gt;src/main/rules&lt;/directory&gt;`。 - 如需与Spring集成,还需要配置相应的Spring beans。 6. **规则编写与执行** - Drools 使用DRL(Drools ...

    Drools Jboss Rules 5.0 Developer's Guide

    &lt;attribute name="inputType"&gt;org.drools.decisiontable.InputType.XLS&lt;/attribute&gt; &lt;header&gt; &lt;row&gt; &lt;column name="Credit Score" type="java.lang.Integer" var="creditScore" /&gt; &lt;column name="Income Level...

    drools6学习例子

    通过这个"drools6学习例子",你不仅可以掌握Drools的基础知识,还能深入理解其在实际项目中的应用,为你的IT职业生涯添加一项实用的技能。记得实践中不断探索和总结,理论与实践相结合,才能更好地驾驭这个强大的...

    drools-springboot:规则引擎drools与springboot的使用,Drools动态规则与决策表

    流口水的春天引导 规则引擎Drools与SpringBoot的使用 SpringBoot与Drools SpringBoot项目 略 流口水 依赖 &lt;drools&gt;6.5.0.Final&lt;/drools&gt; &lt;!--Drools--&gt;... &lt;dependency&gt; ... &lt;groupId&gt;org.drools&lt;/groupId&gt;

    drools drools drools drools drools

    drools 是一个强大的规则引擎和业务规则管理系统,用于在Java应用程序中实现复杂的业务逻辑。它基于规则推理,允许用户以声明式的方式定义规则,并在运行时执行这些规则。drools 提供了一个高效的决策自动化框架,...

    Java开发:规则引擎DroolsJava实现代码示例

    Drools是其中一个流行的开源规则引擎,由JBoss(现为Red Hat的一部分)维护,它提供了丰富的功能来处理复杂的业务逻辑。本示例将深入讲解如何在Java项目中集成和使用Drools进行规则引擎的实现。 首先,我们需要理解...

    drools学习笔记

    drools 提供了多种比较操作符,如 &gt;、&lt;、==、!= 以及更复杂的 contains、memberOf 和 matches。例如,contains 用于检查对象的集合字段是否包含特定值,memberOf 则用于验证字段值是否属于某个集合,matches 则用于...

    Drools5.3官网手册

    例如,可以使用 `&lt;drools:rulebase&gt;` 和 `&lt;drools:stateful-session&gt;` 元素来定义规则库和状态化会话。 - **事件监听器**(Event Listeners):讲解了如何使用 Spring 的依赖注入功能来配置 Drools 事件监听器,以...

    fast-drools-spring-boot-starter:简易流口水,版本8.0.7

    用法1)在pom.xml注入以下依赖项(更新2021/01/04 ): &lt; dependency&gt; &lt; groupId&gt;com.github.hongwen1993&lt;/ groupId&gt; &lt; artifactId&gt;fast-drools-spring-boot-starter&lt;/ artifactId&gt; &lt; version&gt;8.0.7&lt;/ version&gt;&lt;/ ...

Global site tag (gtag.js) - Google Analytics