案例上一部分:规则引擎easy-rules初步学习之使用案例(四),接下来主要是实现规则配置,外置数据库mysql实现。

思路

1、Mysql存储
新建表t_biz_rule、t_biz_rule_compose分别存储规则定义、规则组合定义

2、构建Rules
Mysql中的Rule、RuleCompose转换成RuleDefinition对象

定义Rules注册工具类Helper,为每个RuleCompose注册

3、定义Facts以及RulesEngine

实现

Mysql创建的存储规则定义和规则组合定义po

1.存储规则定义BizRulePo

/**
 * @Description: 业务规则
 */
@Data
@Accessors(chain = true)
public class BizRulePo implements Serializable {

  /**
   * 主键ID
   */
  private Long id;

  /**
   * 规则名称
   */
  private String name;

  /**
   * 描述
   */
  private String description;

  /**
   * 权重
   */
  private Integer priority;

  /**
   * 组合类型 {@link com.rule.easyrule.enums.CompositeRuleTypeEnum}
   */
  private Integer compositeType;

/**
   * 状态 0有效-1无效
   */
  private Integer state;
/**
   * 创建时间
   */
  private Date createTime;
/**
   * 变更时间
   */
  private Date updateTime;
}

2.规则组合BizRuleComposePo

/**
 * @Description: 规则组合
 */
@Data
@Accessors(chain = true)
public class BizRuleComposePo implements Serializable {
  /**
   * 主键id
   */
  private Long id;

  /**
   * 规则id
   */
  private Long ruleId;

  /**
   * 规则名称
   */
  private String name;

  /**
   * 规则描述
   */
  private String description;

  /**
   * 权重
   */
  private Integer priority;

  /**
   * 条件(java代码)
   */
  private String condition;

  /**
   * 执行动作
   */
  private String actions;

  /**
   * 状态 0有效  1有效
   */
  private Integer state;

  /**
   * 创建时间
   */
  private Date createTime;

  /**
   * 修改时间
   */
  private Date updateTime;
}

通过Heler工具类构建Rules对象

  1. 定义BizRuleHelper
/**
 * @Description: 业务规则工具类
 */
public class BizRuleHelper extends AbstractRuleFactory {

  private final ParserContext parserContext;

  public BizRuleHelper(ParserContext parserContext) {
    this.parserContext = parserContext;
  }

  @Override
  public Rule createSimpleRule(RuleDefinition ruleDefinition) {
    MVELRule mvelRule = new MVELRule(parserContext)
        .name(ruleDefinition.getName())
        .description(ruleDefinition.getDescription())
        .priority(ruleDefinition.getPriority())
        .when(ruleDefinition.getCondition());
    for (String action : ruleDefinition.getActions()) {
      mvelRule.then(action);
    }
    return mvelRule;
  }
}

API代码

  1. 调用接口
@Autowired
private BizRulesConfig bizRulesConfig;

final String RULE_NAME ="审核规则";

  @PostMapping("/annotationdb")
  @SneakyThrows
  public void annotationdbTest(@RequestBody BizOrder order) {
      //定义数据
      Facts facts = new Facts();
      facts.put("order", order);
      //调用到的方法
      facts.put("OrderService", OrderService.class);
      
      //读取配置
      Rules rules = bizRulesConfig.fetchConfigRules(RULE_NAME);

      //启动点火
      RulesEngine rulesEngine = new DefaultRulesEngine();
      rulesEngine.fire(rules, facts);
  }
  1. 构建rules配置BizRulesConfig
@Component
@AllArgsConstructor
public class BizRulesConfig {

  private BizRuleService bizRuleService;

  /**
   * 构建rules配置
   */
  public Rules fetchConfigRules(String ruleName) {
    //获取全部规则
    CompositeRule compositeRule = bizRuleService.ruleDefinitions(ruleName);
    //读取配置
    Rules rules = new Rules();
    rules.register(compositeRule);
    return rules;
  }
}
  1. 获取全部规则
/**
 * 找出该组所有的规则
 *  * @param groupCode 规则组
 * @return 结果
   */
  public CompositeRule ruleDefinitions(String groupCode) {
    //规则
    List<BizRulePo> bizRuleList = this.selectByName(groupCode);
    if (CollectionUtils.isEmpty(bizRuleList)) {
//      throw new BusinessException("规则定义不存在");
    }
    CompositeRule compositeRule;
    BizRulePo bizRule = bizRuleList.get(0);
    //判断规则组合类型
    switch (CompositeRuleTypeEnum.of(bizRule.getCompositeType())) {
      case AND:
        compositeRule = new UnitRuleGroup(bizRule.getName());
        break;
      case ALL:
        compositeRule = new ConditionalRuleGroup(bizRule.getName());
        break;
      default:
        compositeRule = new ActivationRuleGroup(bizRule.getName());
    }
    compositeRule.setDescription(bizRule.getDescription());
    compositeRule.setPriority(bizRule.getPriority());
    //规则组合数据
    List<BizRuleComposePo> bizRuleComposeList = composeService.selectByRule(bizRule.getId());
    CompositeRule finalCompositeRule = compositeRule;
    BizRuleHelper bizRuleHelper = new BizRuleHelper(new ParserContext());

    //规则定义
    bizRuleComposeList.forEach(bizRuleCompose -> {
      RuleDefinition ruleComposeDefinition = new RuleDefinition();
      ruleComposeDefinition.setName(bizRuleCompose.getName());
      try {
        BeanCopyUtil.getBean(bizRuleCompose, ruleComposeDefinition);
      } catch (Exception e) {
        e.printStackTrace();
      }
      if (!StringUtils.isEmpty(bizRuleCompose.getActions())) {
        List<String> actions = Arrays.asList(bizRuleCompose.getActions().split(";"));
        ruleComposeDefinition.setActions(actions);
      }
      Rule rule = bizRuleHelper.createSimpleRule(ruleComposeDefinition);
      finalCompositeRule.addRule(rule);
    });
    return finalCompositeRule;
  }

sql

  1. t_r_biz_rule
-- ----------------------------
-- Table structure for t_r_biz_rule
-- ----------------------------
DROP TABLE IF EXISTS `t_r_biz_rule`;
CREATE TABLE `t_r_biz_rule` (
  `id` bigint(22) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '规则名称',
  `description` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '规则描述',
  `priority` int(11) DEFAULT NULL COMMENT '权重',
  `composite_type` tinyint(4) DEFAULT NULL COMMENT '组合类型 1-and 2-or 3-all',
  `state` tinyint(4) DEFAULT NULL COMMENT '数据状态 0-有效 1-无效',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `idx_name` (`name`) USING BTREE COMMENT '策略名称'
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;

-- ----------------------------
-- Records of t_r_biz_rule
-- ----------------------------
INSERT INTO `t_r_biz_rule` VALUES ('1', '审核规则', '审核规则测试用例,组合方式为XOR', '1', '2', '0', '2022-02-21 14:13:18', null);
  1. t_r_biz_rule_compose
DROP TABLE IF EXISTS `t_r_biz_rule_compose`;
CREATE TABLE `t_r_biz_rule_compose` (
  `id` bigint(22) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `rule_id` bigint(22) NOT NULL COMMENT '规则ID',
  `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '规则名称',
  `description` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '规则描述',
  `condition` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '规则条件',
  `actions` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '执行动作',
  `priority` int(11) DEFAULT NULL COMMENT '规则权重',
  `state` tinyint(4) DEFAULT NULL COMMENT '数据状态 0-有效 1-无效',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `idx_rule` (`rule_id`) USING BTREE COMMENT '规则'
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;

-- ----------------------------
-- Records of t_r_biz_rule_compose
-- ----------------------------
INSERT INTO `t_r_biz_rule_compose` VALUES ('1', '1', 'discount_order_rule', '折扣订单类型', '(2).equals(order.type)', 'System.out.println(\"折扣订单类型\");OrderService.doDiscountAction(order);', '1', '0', '2022-02-21 14:13:34', '2022-04-05 15:40:51');
INSERT INTO `t_r_biz_rule_compose` VALUES ('2', '1', 'ordinary_order_rule', '普通订单类型', '(1).equals(order.type)', 'System.out.println(\"普通订单类型\");', '2', '0', '2022-02-21 14:13:34', '2022-04-05 15:40:57');

运行结果展示

在这里插入图片描述

[2022-04-05 15:41:01.381] [http-nio-8089-exec-5] [DEBUG] [.e.mapper.BizRuleMapper.selectByName:159 ] - ==>  Preparing: select * from t_r_biz_rule where state =0 AND `name` = ? 
[2022-04-05 15:41:01.383] [http-nio-8089-exec-5] [DEBUG] [.e.mapper.BizRuleMapper.selectByName:159 ] - ==> Parameters: 审核规则(String)
[2022-04-05 15:41:01.387] [http-nio-8089-exec-5] [DEBUG] [.e.mapper.BizRuleMapper.selectByName:159 ] - <==      Total: 1
[2022-04-05 15:41:01.388] [http-nio-8089-exec-5] [DEBUG] [c.r.e.m.B.selectByRule                  :159 ] - ==>  Preparing: select id,rule_id,`condition`,`name`,priority,actions from t_r_biz_rule_compose where state =0 AND `rule_id` = ? 
[2022-04-05 15:41:01.389] [http-nio-8089-exec-5] [DEBUG] [c.r.e.m.B.selectByRule                  :159 ] - ==> Parameters: 1(Long)
[2022-04-05 15:41:01.391] [http-nio-8089-exec-5] [DEBUG] [c.r.e.m.B.selectByRule                  :159 ] - <==      Total: 2
------------------------------
审核规则
[2022-04-05 15:41:01.407] [http-nio-8089-exec-5] [DEBUG] [.jeasy.rules.core.DefaultRulesEngine:139 ] - Engine parameters { skipOnFirstAppliedRule = false, skipOnFirstNonTriggeredRule = false, skipOnFirstFailedRule = false, priorityThreshold = 2147483647 }
[2022-04-05 15:41:01.408] [http-nio-8089-exec-5] [DEBUG] [.jeasy.rules.core.DefaultRulesEngine:143 ] - Registered rules:
[2022-04-05 15:41:01.408] [http-nio-8089-exec-5] [DEBUG] [.jeasy.rules.core.DefaultRulesEngine:145 ] - Rule { name = '审核规则', description = '审核规则测试用例,组合方式为XOR', priority = '1'}
[2022-04-05 15:41:01.408] [http-nio-8089-exec-5] [DEBUG] [.jeasy.rules.core.DefaultRulesEngine:151 ] - Known facts:
[2022-04-05 15:41:01.408] [http-nio-8089-exec-5] [DEBUG] [.jeasy.rules.core.DefaultRulesEngine:153 ] - Fact{name='order', value=BizOrder(goods=商品, amount=200, type=2, discount=0.7)}
[2022-04-05 15:41:01.408] [http-nio-8089-exec-5] [DEBUG] [.jeasy.rules.core.DefaultRulesEngine:153 ] - Fact{name='OrderService', value=class com.rule.easyrule.service.OrderService}
[2022-04-05 15:41:01.408] [http-nio-8089-exec-5] [DEBUG] [.jeasy.rules.core.DefaultRulesEngine:82  ] - Rules evaluation started
[2022-04-05 15:41:01.412] [http-nio-8089-exec-5] [DEBUG] [.jeasy.rules.core.DefaultRulesEngine:108 ] - Rule '审核规则' triggered
折扣订单类型
[2022-04-05 15:41:01.416] [http-nio-8089-exec-5] [ERROR] [m.rule.easyrule.service.OrderService:21  ] - 商品goods:商品,折后amount:140.0
[2022-04-05 15:41:01.417] [http-nio-8089-exec-5] [DEBUG] [.jeasy.rules.core.DefaultRulesEngine:113 ] - Rule '审核规则' performed successfully

学习资料

Easy Rules 配置文件外置-Mysql
easy-rule结合mysql数据库实现查询规则组装并使用
demo代码地址

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐