drools怎么实现if-else-then逻辑啊?只有when-then逻辑能跑通,下面这段代码跑了不打印任何东西,输入5和15两个数字都没打印任何东西,drl文件不知道哪里写的有问题
pom核心信息如下:
<properties>
<java.version>1.8</java.version>
<drools.version>7.46.0.Final</drools.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-bom</artifactId>
<type>pom</type>
<version>${drools.version}</version>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-mvel</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
drl文件内容如下:
package couponRules;
import com.xxx.drools.demo.dto.UserSession;
rule rule01
no-loop true
when
$c:UserSession(true)
if ($c.count>10) do [if_condition]
if (!($c.count>10)) do [else_condition]
then
System.out.println("走到了when分支");
then [if_condition]
$c.setResult(true);
System.out.println("走到了if分支");
then [else_condition]
$c.setResult(false);
System.out.println("走到到else分支");
end
以下是规则服务:
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.drools.core.impl.KnowledgeBaseImpl;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.KieSession;
import org.kie.internal.builder.KnowledgeBuilder;
import org.kie.internal.builder.KnowledgeBuilderFactory;
import org.kie.internal.io.ResourceFactory;
import org.kie.internal.utils.KieHelper;
import org.springframework.stereotype.Service;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Service
public class RuleService {
static KieHelper helper = new KieHelper();
static Map<Integer, KnowledgeBaseImpl> couponRuleBases = new HashMap<>();
@SneakyThrows
public void loadRule(int couponId, String drlStr) {
KnowledgeBaseImpl kieBase = couponRuleBases.get(couponId);
if (kieBase == null) {
kieBase = (KnowledgeBaseImpl) helper.build();
addRuleForBase(drlStr, kieBase);
couponRuleBases.put(couponId, kieBase);
} else {
addRuleForBase(drlStr, kieBase);
}
log.info("loadRules,couponId={},drlStr={}", couponId, drlStr);
}
private void addRuleForBase(String drlStr, KnowledgeBaseImpl kieBase) {
KnowledgeBuilder kb = KnowledgeBuilderFactory.newKnowledgeBuilder();
kb.add(ResourceFactory.newByteArrayResource(drlStr.getBytes(StandardCharsets.UTF_8)), ResourceType.DRL);
kieBase.addPackages(kb.getKnowledgePackages());
}
public void executeRules(int couponId, UserSession userSession) {
KieSession kieSession = couponRuleBases.get(couponId).newKieSession();
log.info("executeRules,couponId={}", couponId);
kieSession.insert(userSession);
kieSession.fireAllRules();
kieSession.dispose();
}
}
以下是单元测试
static String realRule = "package couponRules;\n" +
"\n" +
"import com.xxx.drools.demo.dto.UserSession;\n" +
"\n" +
"rule rule01\n" +
" no-loop true\n" +
" when\n" +
" $c:UserSession(true)\n" +
" if ($c.count>10) do [if_condition]\n" +
" if (!($c.count>10)) do [else_condition]\n" +
" then\n" +
" System.out.println(\"走到了when分支\");\n" +
" then [if_condition]\n" +
" $c.setResult(true);\n" +
" System.out.println(\"走到了if分支\");\n" +
" then [else_condition]\n" +
" $c.setResult(false);\n" +
" System.out.println(\"走到到else分支\");\n" +
"end";
@Test
void contextLoads() {
ruleService.loadRule(1, realRule);
UserSession userSession1 = new UserSession();
userSession1.setCount(5);
log.info("执行5开始");
ruleService.executeRules(1, userSession1);
log.info("执行5结束");
UserSession userSession2 = new UserSession();
userSession2.setCount(15);
log.info("执行15开始");
ruleService.executeRules(1, userSession2);
log.info("执行15结束");
}
2022-02-08 17:07:12.857 INFO 20020 --- [ main] c.j.m.d.demo.DroolsDemoApplicationTests : 执行5开始
2022-02-08 17:07:12.911 INFO 20020 --- [ main] c.j.m.drools.demo.service.RuleService : executeRules,couponId=1
2022-02-08 17:07:12.920 INFO 20020 --- [ main] c.j.m.d.demo.DroolsDemoApplicationTests : 执行5结束
2022-02-08 17:07:12.920 INFO 20020 --- [ main] c.j.m.d.demo.DroolsDemoApplicationTests : 执行15开始
2022-02-08 17:07:12.920 INFO 20020 --- [ main] c.j.m.drools.demo.service.RuleService : executeRules,couponId=1
2022-02-08 17:07:12.920 INFO 20020 --- [ main] c.j.m.d.demo.DroolsDemoApplicationTests : 执行15结束
报错
官网给的,但是不满足需求,drools规则是逐条执行的,第一条不满足就pass了
rule "Give free parking and 10% discount to over 60 Golden customer and 5% to Silver ones"
when
$customer : Customer( age > 60 )
if ( type == "Golden" ) do[giveDiscount10]
else if ( type == "Silver" ) break[giveDiscount5]
$car : Car( owner == $customer )
then
modify($car) { setFreeParking( true ) };
then[giveDiscount10]
modify($customer) { setDiscount( 0.1 ) };
then[giveDiscount5]
modify($customer) { setDiscount( 0.05 ) };
end
此示例规则为 60 岁以上的 Golden 客户提供 10% 的折扣和免费停车,但对 Silver 客户仅提供 5% 的折扣且不提供免费停车。该规则激活以giveDiscount5关键字break而不是命名的结果do。关键字do在 Drools 引擎议程中安排一个结果,使规则条件的其余部分能够继续被评估,同时break阻止任何进一步的条件评估。如果命名结果不对应于任何条件,do但被激活break,则规则无法编译,因为永远不会达到规则的条件部分。
想要通过drl文件实现if-else逻辑