【发布时间】:2022-01-14 22:45:54
【问题描述】:
我是 Drools 的新手,我们正在尝试使用 Drools n Scala 框架创建基本的验证规则,例如 NULL 检查等。
我有一个包含 200 个属性的源文件,需要对所有这些属性应用 NULL 检查规则, 有什么简单的方法可以做到这一点吗?还是我需要为每个属性创建 200 条规则?
提前致谢。
【问题讨论】:
标签: drools
我是 Drools 的新手,我们正在尝试使用 Drools n Scala 框架创建基本的验证规则,例如 NULL 检查等。
我有一个包含 200 个属性的源文件,需要对所有这些属性应用 NULL 检查规则, 有什么简单的方法可以做到这一点吗?还是我需要为每个属性创建 200 条规则?
提前致谢。
【问题讨论】:
标签: drools
假设您有一个 POJO(“普通的旧 java 对象”、getter/setter 和一些用于保存值的私有变量)或现代 java Records(实际上是同一件事),那么答案是否定的:您需要单独的规则。对于这种情况,检查字段“name”是否为 null 的唯一方法是实际断言该字段,如下所示:
rule "example - name is null"
when
ExampleObject( name == null )
then
System.out.println("Name is null.");
end
但是存在其他数据结构——例如,Map 及其同级类型——您可以在其中按名称引用字段。在这种情况下,理论上您可以遍历所有字段名称并找到值为空的字段。
因此,例如,Map 有一个 keySet() 方法,该方法返回一组字段——您可以遍历此键集并为每个键检查映射中是否存在非空值。
rule "example with map"
when
$map: Map()
$keys: Set() from $map.keySet()
$key: String() from $keys
String( this == null ) from $map.get($key)
// or this might work, not sure if the "this" keyword allows this syntax:
// Map( this[$key] == null ) from $map
then
System.out.println($key + " is missing/null");
end
这需要在传递给规则之前将您的 Java 对象转换为 Map。
但是我不推荐这种方法。由于它们如何序列化/反序列化,地图非常在规则中表现不佳。在触发它们时,您将使用 ton 不必要的堆。如果您查看 HashMap 如何序列化,例如,通过查看其源代码,您会发现它实际上包含一堆“子”数据结构,如 entryset 和 keyset 之类的东西。使用“new”时,这些子结构仅在需要时才被初始化;但是在序列化/反序列化时,即使您不需要它们,它们也会立即创建。
另一种解决方案是使用 Java 反射来获取声明的字段名称列表,然后使用反射遍历这些名称以获取该字段的值。在你的位置,我会在 Java 中执行此操作(如果没有尝试在 Drools 中执行,反射就足够有问题了),然后在必要时从 Drools 调用这样的实用程序函数。
【讨论】: