drools - 有没有办法在drools中使用基于规则LHS的休眠插入事实
问题描述
我是新来的drools
。我找到了根据文件中的规则自动从数据库中插入事实的lhs
方法drl
。
如果有这样的规定,
1: rule "simple rule"
2: when
3: Student( name == "Andy" )
4: then
5: end
然后我从db
使用中发现了事实hibernate
StudentRepository.findByName("Andy");
但是,我不知道如何lhs
在代码中使用该规则。请让我知道有一种方法以及如何做到这一点。
我几乎浪费了两个星期来做这件事......
添加我的代码) OnDemandMessageRuleUnit.java
package com.joel.messageRule.service;
import com.joel.messageRule.model.Daybook;
import com.joel.messageRule.model.Member;
import com.joel.messageRule.repositories.DaybookRepository;
import com.joel.messageRule.repositories.MemberRepository;
import lombok.Getter;
import org.kie.api.runtime.rule.DataSource;
import org.kie.api.runtime.rule.RuleUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@Getter
@Component
public class OnDemandMessageRuleUnit implements RuleUnit {
private DataSource<Member> members;
private DataSource<Daybook> daybooks;
private MemberRepository memberRepository;
private DaybookRepository daybookRepository;
private final Logger logger = LoggerFactory.getLogger(OnDemandMessageRuleUnit.class);
public OnDemandMessageRuleUnit(MemberRepository memberRepository, DaybookRepository daybookRepository){
this.memberRepository = memberRepository;
this.daybookRepository = daybookRepository;
this.members = DataSource.create();
this.daybooks = DataSource.create();
}
@Override
public void onStart() {
// in this part i want to insert daybook objects which meet the condition written as rule lhs to data source or kiesession
logger.info("OnDemandMessageRuleUnit Started");
for(Member m:members){
List<Daybook> daybookList = m.getDaybooks();
if(!daybookList.isEmpty()){
for(Daybook d:daybookList){
daybooks.insert(d);
}
}
}
}
@Override
public void onEnd() {
logger.info("OnDemandMessageRuleUnit Ended");
try{
for(Member m:members){
memberRepository.save(m);
}
for(Daybook d:daybooks){
daybookRepository.save(d);
}
}
catch (NullPointerException e){
e.printStackTrace();
throw e;
}
finally {
}
}
}
恭维消息.drl
package com.joel.messageRule.service
unit OnDemandMessageRuleUnit
import java.lang.Number;
import com.joel.messageRule.model.*;
import org.slf4j.Logger;
rule "complimentMessage"
dialect "mvel"
when
$receiver : Member(cumulativeDaybookRecord >= 3) from members
then
logger.info($receiver.getName() + "님에게 칭찬 메시지를 전송하였습니다.");
end
因此,我从规则或生产内存或节点内存中读取 Member(cumulativeDaybookRecord >= 3),查询“select * from Member wherecumulativeDaybookRecord >= 3”并将结果插入工作内存
解决方案
你在正确的轨道上,但你RuleUnit
需要一些调整。
RuleUnit 的目的,在我们在这里使用它的方式中,是以编写规则的人不需要了解如何从数据库中获取成员的方式提供成员。您的 RuleUnit 只是缺少该getMembers()
方法才能使您的规则起作用。
你的规则是这样说的:
$receiver : Member(cumulativeDaybookRecord >= 3) from members
这是不打算做的select * from members where cumulativeDaybookRecord >= 3
。select * from members
当 Drools 评估是否应该触发规则时,这将执行一个然后在内存中应用累积日记记录过滤器。这样,您可以为 >= 3 设置一条规则,为 == 0 设置另一条规则,依此类推,这些规则都适用于同一组成员。
实际上,这取决于您如何定义您public Datasource<Member> getMembers()
尚未实现的方法。这是使一组成员可用于您的规则的逻辑。您可以使用 hibernate 以任何方式实现它,只要它产生成员实例的集合即可。但是,该方法不接受任何参数。
如果您想将过滤器应用于数据库查询,那么 RuleUnit 是错误的模式。RuleUnit 作为数据源的想法是它为您提供数据集合,然后您可以针对该数据编写多个规则。因此,您可以针对不同的累积日记记录量、成员姓名、加入日期或其他任何内容编写规则——所有这些都使用相同的数据源。其他 RuleUnit 方法将允许您使用正确的启动/停止处理安全地包装该数据库交互,这对于连接或事务管理很有用。
但是,如果您确实想在查询本身上使用不同的过滤器执行多个数据库查询,那么这不是适合您使用的结构。您可能不得不像 Thilakar Raj 在他的回答中建议的那样对存储库进行实际调用(尽管我非常不建议在这样的规则中进行数据库调用,因为 Drools 如何评估规则。)如果问题是编写规则的人不是程序员,那么答案可能是为存储库编写一个自定义包装器,使用特殊方法应用过滤器或预制过滤器,然后将其传递到工作内存中。
推荐阅读
- python - 如何让 Python argparse 接受一个“-a”标志来代替位置参数?
- vb.net - 对文件路径进行硬编码时,如何考虑不同的用户配置文件?
- git - 当git历史包含私人信息时如何使源代码开放?
- c# - 用于作业的 Kubernetes 服务帐户
- reactjs - Normalizr Union 缺少嵌套项的 id
- mysql - Node JS MYSQL 查询未运行,但未记录错误
- javascript - HtmlUnit 登录尝试导致我无法通过的奇怪页面。“脚本已禁用。单击提交继续”
- java - 无法加载类但可以导入工作正常
- python - 如何在python中拆分地址?
- r - 在 R 中,我需要将一组数字除以另一列中的特定值,然后通过分组变量重复该操作