Springboot集成Easy Rules引擎,实现一个商品优惠券系统
Easy Rules是一个轻量级的Java规则引擎,它允许开发者将业务规则从代码中解耦出来,使规则的管理和执行更加灵活。
现在让我们一起利用Spring Boot结合Easy Rules和MyBatis技术栈,可以实现一个高效且易于维护的优惠券系统例子。
1. 添加依赖项
在 pom.xml
文件中确保包含以下依赖项:
<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis Framework -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.1</version>
</dependency>
<!-- MySQL Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Easy Rules Core -->
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-core</artifactId>
<version>4.4.0</version>
</dependency>
<!-- Easy Rules Support for Spring -->
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-support-spring</artifactId>
<version>4.4.0</version>
</dependency>
<!-- Lombok (Optional, for reducing boilerplate code) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- Test Dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
2. 配置 MyBatis 和数据库连接
在 application.properties
文件中配置数据库连接信息和 MyBatis 设置:
# 数据库配置
spring.datasource.url=jdbc:mysql://localhost:3306/coupon_system?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# MyBatis 配置
mybatis.type-aliases-package=com.example.couponsystemdb.model
mybatis.mapper-locations=classpath*:mapper/*.xml
3. 定义业务实体类
我们需要定义一些业务实体类来表示购物车、商品和优惠券信息。
ShoppingCart.java
package com.example.couponsystemdb.model;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
publicclass ShoppingCart {
privatedouble totalPrice = 0; // 购物车总价格
privatefinal List<Item> items = new ArrayList<>(); // 商品列表
/**
* 向购物车添加商品
* @param item 商品对象
*/
public void addItem(Item item) {
items.add(item);
totalPrice += item.getPrice();
}
/**
* 应用折扣
* @param discount 折扣比例(例如 0.10 表示 10% 折扣)
*/
public void applyDiscount(double discount) {
totalPrice -= totalPrice * discount;
}
}
Item.java
package com.example.couponsystemdb.model;
import lombok.Data;
@Data
publicclass Item {
private String name; // 商品名称
private String category; // 商品类别
privatedouble price; // 商品价格
/**
* 构造函数
* @param name 商品名称
* @param category 商品类别
* @param price 商品价格
*/
public Item(String name, String category, double price) {
this.name = name;
this.category = category;
this.price = price;
}
}
CouponRule.java
这个类用于从数据库加载规则信息。
package com.example.couponsystemdb.model;
import lombok.Data;
@Data
public class CouponRule {
private Long id; // 规则ID
private String ruleName; // 规则名称
private String description; // 规则描述
private String conditionExpression; // 条件表达式
private String actionExpression; // 动作表达式
}
4. 创建数据库表和初始化数据
创建一个名为 coupon_system
的数据库,并在其中创建 coupon_rule
表。然后插入一些初始规则数据。
SQL 脚本
CREATE DATABASE coupon_system;
USE coupon_system;
CREATETABLE coupon_rule (
idBIGINT AUTO_INCREMENT PRIMARY KEY,
rule_name VARCHAR(255) NOTNULL,
description TEXT,
condition_expression TEXTNOTNULL,
action_expression TEXTNOTNULL
);
INSERTINTO coupon_rule (rule_name, description, condition_expression, action_expression) VALUES
('Total Price Discount Rule', 'Offers a 10% discount if the total price exceeds 1000',
'cart.getTotalPrice() > 1000',
'cart.applyDiscount(0.10); System.out.println("Applied 10% discount for total price exceeding 1000");'),
('Category Discount Rule', 'Offers an additional 5% discount on Electronics category',
'cart.getItems().stream().anyMatch(item -> item.getCategory().equals("Electronics"))',
'cart.applyDiscount(0.05); System.out.println("Applied 5% discount for purchasing electronics");');
5. 定义动态规则
我们将使用 Easy Rules 的 DynamicRule
类来从数据库加载规则并执行。
DynamicCouponRule.java
package com.example.couponsystemdb.rule;
import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Fact;
import org.jeasy.rules.api.Facts;
import org.jeasy.rules.core.DynamicRule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
publicclass DynamicCouponRule extends DynamicRule {
@Autowired
private CouponService couponService;
/**
* 评估条件
* @param facts 事实对象
* @return 是否满足条件
* @throws Exception 异常
*/
@Override
@Condition
public boolean evaluate(Facts facts) throws Exception {
returnsuper.evaluate(facts);
}
/**
* 执行动作
* @param facts 事实对象
* @throws Exception 异常
*/
@Override
@Action
public void execute(Facts facts) throws Exception {
super.execute(facts);
}
/**
* 从数据库设置规则
* @param ruleId 规则ID
*/
public void setRuleFromDatabase(Long ruleId) {
CouponRule couponRule = couponService.getCouponRuleById(ruleId);
setName(couponRule.getRuleName());
setDescription(couponRule.getDescription());
setConditionExpression(couponRule.getConditionExpression());
setActionExpression(couponRule.getActionExpression());
}
}
6. 配置规则引擎
我们需要配置规则引擎并将规则注册到 Spring 上下文中。
EasyRulesConfig.java
package com.example.couponsystemdb.config;
import org.jeasy.rules.api.RulesEngine;
import org.jeasy.rules.core.DefaultRulesEngine;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
publicclass EasyRulesConfig {
/**
* 配置规则引擎
* @return 规则引擎实例
*/
@Bean
public RulesEngine rulesEngine() {
returnnew DefaultRulesEngine();
}
}
7. 创建 Service 层
创建一个服务层来处理与数据库的交互。
CouponService.java
package com.example.couponsystemdb.service;
import com.example.couponsystemdb.mapper.CouponRuleMapper;
import com.example.couponsystemdb.model.CouponRule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
publicclass CouponService {
@Autowired
private CouponRuleMapper couponRuleMapper;
/**
* 根据规则ID获取规则
* @param id 规则ID
* @return 规则对象
*/
public CouponRule getCouponRuleById(Long id) {
return couponRuleMapper.selectById(id);
}
}
8. 创建 Mapper 接口
使用 MyBatis 映射器接口来操作数据库。
CouponRuleMapper.java
package com.example.couponsystemdb.mapper;
import com.example.couponsystemdb.model.CouponRule;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface CouponRuleMapper {
/**
* 根据规则ID查询规则
* @param id 规则ID
* @return 规则对象
*/
@Select("SELECT * FROM coupon_rule WHERE id = #{id}")
CouponRule selectById(Long id);
}
9. 编写主应用程序类
最后,在主应用程序类中使用规则引擎来处理购物车中的商品。
CouponSystemApplication.java
package com.example.couponsystemdb;
import com.example.couponsystemdb.model.ShoppingCart;
import com.example.couponsystemdb.model.Item;
import com.example.couponsystemdb.rule.DynamicCouponRule;
import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.api.RulesEngine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
publicclass CouponSystemApplication implements CommandLineRunner {
@Autowired
private RulesEngine rulesEngine; // 规则引擎
@Autowired
private DynamicCouponRule dynamicCouponRule; // 动态规则
@Autowired
private CouponService couponService; // 优惠券服务
public static void main(String[] args) {
SpringApplication.run(CouponSystemApplication.class, args);
}
/**
* 应用启动时运行的方法
* @param args 命令行参数
* @throws Exception 异常
*/
@Override
public void run(String... args) throws Exception {
ShoppingCart cart = new ShoppingCart(); // 创建购物车
cart.addItem(new Item("Laptop", "Electronics", 1200)); // 添加商品
cart.addItem(new Item("Book", "Books", 30)); // 添加商品
Facts facts = new Facts(); // 创建事实对象
facts.put("cart", cart); // 将购物车放入事实对象
Rules rules = new Rules(); // 创建规则集合
// 从数据库加载规则并注册到规则引擎
Long[] ruleIds = {1L, 2L}; // 数据库中的规则ID
for (Long ruleId : ruleIds) {
dynamicCouponRule.setRuleFromDatabase(ruleId); // 从数据库设置规则
rules.register(dynamicCouponRule); // 注册规则
}
rulesEngine.fire(rules, facts); // 执行规则引擎
System.out.println("Final price after discounts: " + cart.getTotalPrice()); // 输出最终价格
}
}
运行应用程序
保存所有文件并在终端中运行以下命令启动应用程序:
mvn spring-boot:run
你应该会看到以下输出:
Applied 10% discount for total price exceeding 1000
Applied 5% discount for purchasing electronics
Final price after discounts: 1071.0
总结
这个示例展示了如何在 Spring Boot 应用程序中集成 Easy Rules 和 MyBatis,以便通过数据库灵活配置优惠券规则。通过这种方式,你可以在不修改代码的情况下添加新的规则。以下是关键点总结:
数据库配置:使用 MyBatis 和 MySQL 来存储和管理规则。
动态规则:使用 Easy Rules 的
DynamicRule
类来加载和执行从数据库获取的规则。服务层:通过服务层来处理与数据库的交互。
规则引擎配置:配置规则引擎并注册动态规则。
关注我!Java从此不迷路!
原文地址:https://blog.csdn.net/qq_18244417/article/details/145127953
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!