《Drools7.0.0.Final规则引擎教程》第4章 4.4 约束(Pattern的一部分)
4.4.3 约束(Pattern的一部分)
前面我们已经介绍了条件约束在Pattern中位置了,那么什么是条件约束呢?简单来说就是一个返回true或者false的表达式,比如下面的5小于6,就是一个约束条件。
Person( 5 < 6 )
从本质上来讲,它是JAVA表达式的一种增强版本(比如属性访问),同时它又有一些小的区别,比如equals方法和==的语言区别。下面我们就深入了解一下。
访问JavaBean中的属性
任何一个JavaBean中的属性都可以访问,不过对应的属性要提供getter方法或isProperty方法。比如:
Person( age == 50 )
// 与上面拥有同样的效果
Person( getAge() == 50 )
Drools使用java标准的类检查,因此遵循java标准即可。同时,嵌套属性也是支持的,比如:
Person( address.houseNumber == 50 )
// 与上面写法相同
Person( getAddress().getHouseNumber() == 50 )
在使用有状态session的情况下使用嵌套属性需要注意属性的值可能被其他地方修改。要么认为它们是不可变的,当任何一个父引用被插入到working memory中。或者,如果要修改嵌套属性值,则应将所有外部fact标记更新。在上面的例子中,当houseNumber属性值改变时,任何一个包含Address的Person需要被标记更新。
Java表达式
在pattern的约束条件中,可以任何返回结果为布尔类型的java表达式。当然,java表达式也可以和增强的表达式进行结合使用,比如属性访问。可以通过使用括号来更改计算优先级,如在任一逻辑或数学表达式中。
Person( age > 100 && ( age % 10 == 0 ) )
也可以直接使用java提供的工具方法来进行操作计算:
Person( Math.round( weight / ( height * height ) ) < 25.0 )
在使用的过程中需要注意,在LHS中执行的方法只能是只读的,不能在执行方法过程中改变改变FACT对象的值,否则会影响规则的正确执行。
Person( incrementAndGetAge() == 10 ) //不要像这样在比较的过程中更新Fact对象
另外,FACT对象的相关状态除了被在working memory中进行更新操作,不应该每次调用时状态会发生变化。
Person( System.currentTimeMillis() % 1000 == 0 ) // 不要这样实现
标准Java运算符优先级也适用,请参见下面的运算符优先级列表。所有的操作符都有标准的Java语义,除了==和!=。它们的null安全的,就相当于java中比较两个字符串时把常量字符串放前面调用equals方法的效果一样。
约束条件的比较过程中是会进行强制类型转换的,比如在数据计算中传入字符串“10”,则能成功转换成数字10进行计算。但如果,此时传入的值无法进行转换,比如传了“ten”,那么将会抛出异常。
逗号分隔符
逗号可以对约束条件进行分组,它的作用相当于“AND”。
// Person的年龄要超过50,并且重量 超过80 kg
Person( age > 50, weight > 80 )
虽然“&&”和“,”拥有相同的功能,但是它们有不同的优先级。“&&”优先于“||”,“&&”和“||”又优先于“,”。但建议优先使用“,”分隔符,因为它更利于阅读理解和引擎的优化操作。同时,逗号分隔符不能和其他操作符混合使用,比如:
Person( ( age > 50, weight > 80 ) || height > 2 ) // 会编译错误
// 使用此种方法替代
Person( ( age > 50 && weight > 80 ) || height > 2 )
绑定变量
一个属性可以绑定到一个变量:
// 2 person的age属性值相同
Person( $firstAge : age ) // 绑定
Person( age == $firstAge ) // 约束表达式
前缀$只是个通用惯例,在复杂规则中可以通过它来区分变量和属性。为了向后兼容,允许(但不推荐)混合使用约束绑定和约束表达式。
// 不建议这样写
Person( $age : age * 2 < 100 )
// 推荐(分离绑定和约束表达式)
Person( age * 2 < 100, $age : age )
使用操作符“==”来绑定变量,Drools会使用散列索引来提高执行性能。
内部类分组访问
通常情况,我们访问一个内部类的多个属性时会有如下的写法:
Person( name == "mark", address.city == "london", address.country == "uk" )
Drools提供的分组访问可以更加方便进行使用:
Person( name == "mark", address.( city == "london", country == "uk") )
注意前缀’.’是用来区分嵌套对象约束和方法调用所必需的。
内部强制转换
在使用内部类的时候,往往需要将其转换为父类,在规则中可以通过“#”来进行强制转换:
Person( name == "mark", address#LongAddress.country == "uk" )
上面的例子将Address强制转换为LongAddress.,这样使得getter方法变得可用。如果无法强制转换,表达式计算的结果为false。强制转换也支持全路径的写法:
Person( name == "mark", address#org.domain.LongAddress.country == "uk" )
多次内部转换语法:
Person( name == "mark", address#LongAddress.country#DetailedCountry.population > 10000000 )
也可以使用instanceof操作符进行判断,判断之后将进一步使用该属性进行比较。
Person( name == "mark", address instanceof LongAddress, address.country == "uk" )
日期字符
规则语法中除了支持JAVA标准字符,同时也支持日期字符。Drools默认支持的日期格式为“dd-mmm-yyyy”,可以通过设置系统变量“drools.dateformat”的值来改变默认的日期格式。
Cheese( bestBefore < "27-Oct-2009" )
List和Map的访问
访问List:
// 和childList(0).getAge() == 18效果相同
Person( childList[0].age == 18 )
根据key访问map:
// 和credentialMap.get("jsmith").isValid()相同
Person( credentialMap["jsmith"].valid )
&&和||
约束表达式可以通过&&和||来进行判断比较,此处用法与标准Java相似,当组合使用时,可通过括号来划分优先级。
Person( age > 30 && < 40 )
Person( age ( (> 30 && < 40) ||(> 20 && < 25) ) )
Person( age > 30 && < 40 || location == "london" )
DRL特殊操作符
“< ⇐ > >=”操作符用于属性的比较是按照默认的排序,比如日期属性使用小于号标示可以按照日期排序,当使用在String字符串的比较时,则按照字母顺序进行排序。此操作符仅适用于可比较的属性。
Person( firstName < $otherFirstName )
Person( birthDate < $otherBirthDate )
“!.”提供了一个默认空校验的操作。当使用此操作符时,会先校验当前对象是否为null,如果不为null再调用其方法或获得其属性进行判断。一旦当前操作对象为null,则相当于结果为false。
Person( $streetName : address!.street )
// 上面的写法相当于
Person( address != null, $streetName : address.street )
matches操作符可使用Java的正则表达式进行字符串的匹配,通常情况下是对字符串进行匹配,但也支持变量值为正确的表达式的方式。此操作符仅适用于字符串属性。如果属性值为null,匹配的结果始终为false。
Cheese( type matches "(Buffalo)?\\S*Mozzarella" )
not matches方法与matches相同,唯一不同的是返回的结果与之相反。
Cheese( type not matches "(Buffalo)?\\S*Mozzarella" )
contains操作符判断一个集合属性或元素是否包含指定字符串或变量值。仅适用于集合属性。也可以用于替代String.contains()来检查约束条件。not contains用法与之相同,结果取反。
CheeseCounter( cheeses contains "stilton" ) // 包含字符串
CheeseCounter( cheeses contains $var ) // 包含变量
Cheese( name contains "tilto" )
Person( fullName contains "Jr" )
String( this contains "foo" )
memberOf用来检查属性值是否为集合,此集合的表示必须为变量。not memberOf使用方法相同,结果取反。
CheeseCounter( cheese memberOf $matureCheeses )
soundslike的效果与matches相似,但它用来检查一个字符串的发音是否与指定的字符十分相似(使用英语发音)。
// 匹配 "fubar" 或 "foobar"
Cheese( name soundslike 'foobar' )
str操作用来比较一个字符串是否以指定字符串开头或结尾,有可以用于比较字符串的长度。
Message( routingValue str[startsWith] "R1" )
Message( routingValue str[endsWith] "R2" )
Message( routingValue str[length] 17 )
in和notin用来匹配一组数据中是否含一个或多个匹配的字符串,使用的方法与数据库中in的使用方法相似。待匹配的数据可以是字符串、变量。
Person( $cheese : favouriteCheese )
Cheese( type in ( "stilton", "cheddar", $cheese ) )
运算符优先级
操作类型 | 操作符 | 备注 |
---|---|---|
(嵌套/空安全)属性访问 | .!. | 非标准java语义 |
List/Map访问 | [ ] | 非标准java语义 |
约束绑定 | : | 非标准java语义 |
乘除 | */% | |
加减 | +- | |
移位 | <<>>>>> | |
关系 | <>⇐>=instanceof | |
等 | ==!= | 未使用标准java语义,某些语义相当于equals。 |
非短路AND | & | |
非短路异或 | ^ | |
非短路包含OR | | | |
逻辑与 | && | |
逻辑或 | || | |
三元运算符 | ? : | |
逗号分隔,相当于and | , | 非标准java语义 |
后语
此系列课程持续更新中,QQ群:593177274(可扫描左上侧栏目二维码),欢迎大家加入讨论。点击链接关注《Drools博客专栏》。由于Drools资料较少,教程编写不易,每篇博客都亲身实践编写demo。如果对你有帮助也欢迎赞赏(微信)! 也是对原创的最大支持!
《Drools7.0.0.Final规则引擎教程》第4章 4.4 约束(Pattern的一部分)的更多相关文章
- 《Drools7.0.0.Final规则引擎教程》Springboot+规则重新加载
在<Drools7.0.0.Final规则引擎教程>之Springboot集成中介绍了怎样将Drools与Springboot进行集成,本篇博客介绍一下集成之后,如何实现从数据库读取规则并 ...
- 《Drools7.0.0.Final规则引擎教程》第3章 3.1 Hello World 实例
3.1 Hello World 实例 在上一章中介绍了Drools5x版本中规则引擎使用的实例,很明显在Drools7中KnowledgeBase类已经标注为"@Deprecated&quo ...
- 《Drools7.0.0.Final规则引擎教程》第2章 追溯Drools5的使用
2.1 Drools5简述 上面已经提到Drools是通过规则编译.规则收集和规则的执行来实现具体功能的.Drools5提供了以下主要实现API: KnowledgeBuilder Knowledge ...
- 【java规则引擎】《Drools7.0.0.Final规则引擎教程》第4章 4.4 约束(Pattern的一部分)
4.4.3 约束(Pattern的一部分) 前面我们已经介绍了条件约束在Pattern中位置了,那么什么是条件约束呢?简单来说就是一个返回true或者false的表达式,比如下面的5小于6,就是一个约 ...
- 【java规则引擎】《Drools7.0.0.Final规则引擎教程》第3章 3.2 KIE API解析
转载至:https://blog.csdn.net/wo541075754/article/details/75004575 3.2.4 KieServices 该接口提供了很多方法,可以通过这些方法 ...
- 【java规则引擎】《Drools7.0.0.Final规则引擎教程》第3章 3.2 KIE概念&FACT对象
转载:https://blog.csdn.net/wo541075754/article/details/74943236 3.2.1 什么是KIE KIE(Knowledge Is Everythi ...
- 《Drools7.0.0.Final规则引擎教程》第3章 3.2 KIE API解析
3.2.4 KieServices 该接口提供了很多方法,可以通过这些方法访问KIE关于构建和运行的相关对象,比如说可以获取KieContainer,利用KieContainer来访问KBase和KS ...
- 《Drools7.0.0.Final规则引擎教程》第3章 3.2 KIE概念&FACT对象
3.2.1 什么是KIE KIE(Knowledge Is Everything),知识就是一切的简称.JBoss一系列项目的总称,在<Drools使用概述>章节已经介绍了KIE包含的大部 ...
- 【java规则引擎】《Drools7.0.0.Final规则引擎教程》第4章 4.1 规则文件
转载至:https://blog.csdn.net/wo541075754/article/details/75150267 一个标准的规则文件的格式为已“.drl”结尾的文本文件,因此可以通过记事本 ...
随机推荐
- crontab + rsyncd同步方案
目的主机: rsync --daemon [root@iZ23ohdbxmrZ ~]# vim /etc/rsyncd.conf #global settingsport = 873pid file= ...
- 20135302魏静静Linux内核分析第二周学习总结
操作系统是如何工作的 1. 小结:计算机是怎样工作的 三个法宝 存储程序计算机.函数调用堆栈.中断机制 两把宝剑 中断上下文.进程上下文的切换 2. 堆栈 堆栈是C语言程序运行时必须的一个记录调用路径 ...
- 详解WIFI破解-Kali篇
转自: http://www.secbox.cn/hacker/wireless/4877.html 工具: 1:笔记本 2:USB无线网卡(必备) 3:kali系统 4:靠谱字典 第一种方法: 暴力 ...
- windows批量删除ip
cmd下输入如下命令第一步:netsh -c int ip dump >c:\ip.txt在C盘根目录看到一个ip.txt的文件,内容为当前网卡的设置信息,为了能更直观的看清楚IP的设置信息. ...
- 分析java进程假死状况
摘自: http://www.myexception.cn/internet/2044496.html 分析java进程假死情况 1 引言 1.1 编写目的 为了方便大家以后发现进程假死的时候能够正常 ...
- 读书笔记: Microsot .NET企业级应用架构设计
Microsot .NET企业级应用架构设计 Dino Esposito Andrea Saltarello 编 陈黎夫 译 人民邮电出版社 第一部分 设计原则 第1章 当代架构师和架构 ...
- vue-cli router的使用
用了很久这个vue-cli到现在连入门都算不了,为了防止忘记还是很有必要记一下随笔的. 关于vue-cli中的router的使用,, 我将所有页面都存放在components文件夹下, 灰后通过rou ...
- MySQL索引底层实现
一.定义 索引定义:索引(Index)是帮助MySQL高效获取数据的数据结构.本质:索引是数据结构. 二.B-Tree m阶B-Tree满足以下条件: 每个节点至多可以拥有m棵子树. 根节点,只有至少 ...
- spring mvc: 多解析器映射(资源绑定视图解析器 + 内部资源[普通模式/]视图解析器)
spring mvc: 多解析器映射(资源绑定视图解析器 + 内部资源[普通模式/]视图解析器) 资源绑定视图解析器 + 内部资源(普通模式)视图解析器 并存方式 内部资源视图解析器: http:// ...
- .net core mvc部署到IIS导出Word 提示80070005拒绝访问
项目中相信大家经常会遇到导出Word.Excel等需求,在实际开发环境中,一般不会出现什么问题,但当发布到IIS上后可能会遇到各种各样的问题,一般都是权限的问题.前几天把公司项目发布后,出现Word导 ...