规则引擎Visual Rules Solution开发基础教程【连载5】--VisualRules深入了解

[align=center][b][size=x-large]VisualRules深入了解[/size][/b][/align]

[size=medium] 通过前两篇的简单例子说明以及基础教程的描述,已经可以了解操作VisualRules的基本方法,以及VisualRules可以实现的主要功能。下面就程序员使用过程中,关心的一些深层问题,再此加以详细描述。[/size]

[b][size=large]一、工作空间、工程、规则组、规则包区别[/size][/b]

[size=medium] 工作空间下可以包含工程。工作空间只是一个定义文件。
工程下可以包含规则组和规则包。工程是一个目录。
规则组下可以包含规则组和规则包。规则组只是一个工程中的一个分类。
规则包是一个完整的规则定义文件,所有的规则配置信息全在这个文件中,包括对象库配置信息以及规则定义信息。
规则包也可以单独打开,单独打开后,就可以进行测试编译等工作。[/size]

[b][size=large]二、对象库能传入的参数[/size][/b]

[size=medium] 目前对象库中有几类参数:[/size]
[b][size=medium] 1.传入数据[/size][/b]
[size=medium] 传入数据会在规则包执行前,定义成对应类型的变量。在规则包执行时,从外部缓冲区中取得和变量名称一样的对象,然后赋值给此变量。在规则包执行完毕后,在回传给外部的缓冲区。[/size]
[size=medium][b] 2.临时数据[/b][/size]
[size=medium] 只在规则包执行前进行定义。[/size]
[size=medium][b] 3.外部调用[/b][/size]
[size=medium][b] 直接在规则执行是调用。[/b][/size]
[size=medium][b] 4.常量[/b][/size]
[size=medium] 直接在生成的代码中定义。[/size]
[size=medium][b] 5.数据库对象[/b][/size]
[size=medium] 只在规则包执行前进行定义。[/size]
[size=medium][b] 6.表格数据[/b][/size]
[size=medium] 在规则包执行前进行定义。如果表格数据定义了保存数据的设置,则从对象库的定义中读取这些数据,传入到表格中。如果没有定义,则从外部传入的缓冲区中,取得同类型的对象,赋值到该表格中。在规则包执行完后,再更新到缓冲区中。[/size]
[size=medium][b] 7.Excel对象[/b][/size]
[size=medium]在规则包执行前进行定义。在规则包中,从缓冲区中将传入的Excel文件,读取到该对象中。执行过程中,直接对Excel文件进行了处理。[/size]
[size=medium][b] 8.SOAP对象[/b][/size]
[size=medium] 在规则包执行前进行定义。[/size]
[size=medium][b] 9.XML对象[/b][/size]
[size=medium] 在规则包执行前进行定义。根据XML对象的设置,如果设置成从外部传入,规则包执行时,先从缓冲区中读取该对象,然后赋值给该对象。如果设置成从文件中读取,则从指定的文件中读取。XML对象,会在规则包执行后,传回给缓冲区。[/size]
[size=medium][b] 10.数据树结构[/b][/size]
[size=medium] 在规则包执行前进行定义。在规则包执行时,会先判断缓冲区中是否存在该名称的对象,如果有则赋值给该对象。在规则包执行完后,传回给缓冲区。[/size]

[size=large][b]三、规则的处理机制[/b][/size]

[size=medium] 规则是一个完整的逻辑单元,其基本结构是具有条件以及满足条件之后动作。这是规则引擎理论中最基本的判断单元。其基本结构就是这种 if then else的结构。具体的理论不在这里描述,VisualRules在处理这种基本结构时,为了用户操作更加简便,加入了更多的功能结构。规则除了支持基本的如果、那么、否则的基本结构之外,还支持初始化动作、否则如果、否则如果动作以及异常处理动作。
初始化动作,可以在条件判断前,先做一些操作。对于某些应用来说,不用分开两个规则都加以定义。否则如果和否则如果动作,是用于定义不满足条件后,再进行条件判断的操作。对于某些雷同的处理,采用决策表定义又不太方便的情况下,就可以采用这种方式来进行定义。否则如果就是 else if的操作。
在某些条件满足时,如果一个动作不能很好的表达完整,而是需要一连串的规则处理,则可以定义成规则集,并在规则集中设定条件。将此条件满足之后的操作,用多个规则来进行表达,并且添加到规则集下面。
这样就可以实现子规则的操作,控制了规则流转。另外但规则集下面执行规则,如果只要满足一个条件,其他的条件就无需执行这样的情况时,则可以将规则集下面的规则,依次定义为互斥规则。这样当其中一个规则满足条件时,就会跳过后面规则的执行。
如果有些规则,是需要循环进行执行的。则可以将规则集设置成循环类规则集,并且在规则集中定义循环的初始化、满足条件和步骤等操作。利用循环类规则,可以实现循环的操作。[/size]

[b][size=large]四、内存表格的处理机制[/size][/b]

[size=medium] 内存表格是VisualRules为了加快批量数据的处理方式,而实现的一种技术。一般数据大家都是通过复合SQL语句,从数据库中查询对应的结果集。这种方式比较简单,但是会极大的增加数据库的负担,使得执行速度很慢。同时有些批量的数据,也不适合放到数据库中进行存储,因为其结构有可能会发生变化。而数据库表其字段结构是不能轻易发生变化的。
为了能够更快速的操作批量数据,VisualRules在规则引擎中实现了内存表格类,并且支持在规则配置器中,对其结构定义,并且在规则中对其进行操作。
内存表格的基本结构是由列信息和表格数据组成的。列信息定义了表格的每一列的类型和名称,类似于数据库表的字段信息。表格数据是用 Object[][]这种二维数组的方式存储的结构,其中先将每一行数据存储在一个Object[]中,然后在将这些行存储在大的Object[]中。在操作内存表格时,基本分类两种类型操作。一种是批量操作,一种是逐行操作。
批量操作是通过一个方法,对内存表格中所有的数据进行整体操作。包括导入数据、追加数据、更新数据、汇总数据等。这些又分为以下几种功能:
[/size]

[size=medium][b] 1.从数据库表或者查询结果集中初始化数据[/b][/size]
[size=medium] 这种方式会批量的删除掉内存表格中原先的数据,转而根据传入的数据库表或者查询结果集的数据,添加到内存表格中。追加数据时,一般根据字段的显示名以及表格列的显示名,来对应的更新数据。[/size]
[size=medium][b] 2.根据SQL语句直接初始化数据[/b][/size]
[size=medium] 为了最大限度的提高导入从数据库导入数据的速度,可以直接通过SQL语句来初始化数据,这种方式不用再生成结果集。其数据是根据字段的名称和表格列的名称,来对应更新数据。[/size]
[size=medium][b] 3.根据数据库表和查询结果集来更新表格中数据[/b][/size]
[size=medium] 根据数据库表和查询结果集,取得结果集中每一条记录,首先按照字段显示名和表格列的显示名对应的原则,找到在表格中对应的匹配的行,然后将对应的列按照记录中的值更新。[/size]
[size=medium][b] 4.根据数据库表和查询结果集追加计算表格中数据[/b][/size]
[size=medium] 根据传入的数据库表或者查询结果集的数据,添加到内存表格中。追加数据时,一般根据字段的显示名以及表格列的显示名,来对应的更新数据。[/size]
[size=medium][b] 5.将计算表格的数据汇总[/b][/size]
[size=medium] 将计算表格的数据汇总后,可以生成一个新的计算表格。所以汇总时需要制定汇总列、分组列和条件列。其中汇总列就是最后生成的新的计算表格中具有的列。这种方式非常类似于SQL查询语句。汇总列就是 select 后的字段,分组列就是 group by 后的字段,条件列就是where 后的各种条件设置。
这里要说明的是,条件列不能像SQL一样使用括号,因此在这里的约定中,如果有 and和or的多个条件间的设置。 [b]or的优先级比and的优先级要大[/b],这一点和我们一般理解的不大一样,要特别注意。
汇总后生成了新的表格后,这个表格必须作为参数传递到下面的根据表格导入数据的方法中,才能将数据保存下来。否则新生成的表格是无法访问的。[/size]
[size=medium][b] 6.将表格中的数据全部导入到当前表格中[/b][/size]
可以将一个表格数据全部导入到当前表格中,这个方法一般会和上面的汇总方法联合使用,以便实现将汇总的表格保存下来。
[size=medium][b] 7.根据表格更新当前表格,需要指定更新列和匹配列[/b][/size]
[size=medium] 根据表格来更新当前表格。这个方法一般和上面的汇总方法联合使用,以便直接根据汇总结果,来更新此表格的数据。[/size]
[size=medium][b] 8.根据设定关系将表格中的数据,导入到当前表格中[/b][/size]
[size=medium] 设定了两个表格之间列的对应关系,按照这种对应关系,将此表格数据导入到当前表格中。分为追加导入和初始化导入,这是两个不同的方法。[/size]
[size=medium][b] 9.根据设定关系将表格中的数据,更新到当前表格中[/b][/size]
[size=medium] 设定了两个表格之间列的对应关系,按照这种对应关系,找到匹配的列,然后将对应列的信息进行更新。
逐行操作的原理是在计算表格内部,有个光标在设定当前指向那一行,光标可以逐行移动,或者直接跳转到某一行。只有光标移动到具体的行上时,才可以直接访问列的值。此次访问到的列的值就是光标所在行该列的值,可以直接对其进行存取操作。逐行操作的方法具有以下一些:[/size]
[size=medium][b] (1)beforeFirst[/b][/size]
[size=medium] 将光标放到第一行之前,这是需要依次逐行操作之前的动作。[/size]
[size=medium][b] (2)next[/b][/size]
[size=medium] 当光标放到下一行上,如果下一行有数据,则会返回正确。
[b] (3)first[/b]
将光标放到第一行上,如果第一行有数据,则返回正确,否则返回错误。
[b] (4)last[/b]
将光标放到最后一行,如果最后一行有数据,则返回正确,否则返回错误。
[b] (5)previous[/b]
将光标放到上一行上,如果上一行有数据,则返回正确,否则返回错误。
[b] (6)afterLast[/b]
将光标放到最后一行之前,这是需要依次从最后逐行向前操作之前的动作。
[b] (7)gotoRow[/b]
直接跳到指定行上,如果该行有数据,则返回正确,否则返回错误。
[b] (8)getRows[/b]
返回所有数据行的个数
[b] (9)getCurrentRow[/b]
得到当前光标所在的行号。
[b] (10)insert[/b]
在当前位置之后添加一行。添加之后,光标会制定到当前新添加的行。如果光标在第一行之前,则增加到第一行之前。
[b] (11)delete[/b]
将光标当前指向的行删除。同时光标会指向其上一行。因此删除之后,仍然可以保证next操作的正常执行。[/size]

[size=large][b]五、规则的内置循环操作[/b][/size]

[size=medium] 对于一些需要逐行访问的对象,为了简化操作,可以设置规则的内置循环操作。当将规则设置成对某个对象进行内置循环时,首先会执行该对象的beforeFirst方法,然后循环执行next方法,并且在循环内部调用规则的执行。
目前支持的循环对象包括内存表格对象以及数据树中的多节点对象。这两类对象都具有beforeFirst方法以及next方法。并且都是根据next之后,根据属性或列访问其内部值的。
如果规则集设置了内置循环之后,那么规则集包含的所有的规则,也会包含在内置循环的next中。如果内置循环的规则集下面又有规则集或者规则其是内置循环的,那么就会在其里面在进行循环操作。
在设置内置循环时,一定要注意其处理逻辑,轻易不要对表格进行insert和delete等操作。防止出现非法调用的事情发生。[/size]

[size=large][b]六、Null对象的处理[/b][/size]

[size=medium] 在实际的规则包运行时,如果数据为空,则容易出现nullException这种异常错误。一旦出现这种异常错误,规则包会终止运行,并且会说明发生异常的规则或者规则集。Null异常需要尽可能的避免。目前VisualRules的规则包执行时,已经进行以下的操作来规避这类错误:
[b] 1.所有的常规类型定义都会进行初始化[/b]
像String类型,会初始化为””;list类型,会初始化为 new ArrayList(0);map类型,会初始化为 new Hashmap(0)
但是date、datetime、time这些类型,初始化还是为null的。因此尽可能采用规则引擎提供的日期操作方法,而不要直接使用date类型自带的java方法。
[b] 2.自带的判断方法等兼容null[/b]
在规则的定义中的判断,比如String的等于、包含等等方法、以及日期等的方法。都是兼容null类型的。会将null定义为空。如果日期是null,则其表述的意思在规则包的属性中加以定义。
另外注意,数据库的查询结果集,其读取的数据可能会有null的数据产生,因此要特别注意从数据库提取的数据的null的数据的发生。[/size]

[size=large][b]七、数据库单表操作的功能[/b][/size]

[size=medium] VisualRules中对数据库的单表操作非常方便,基本的增加、删除、修改、替换、查询等功能很简便。以下描述这几种方法的实现原理:
[b] 1.增加操作:[/b]
对单表的增加,规则引擎是根据设置的值,生成一个insert的语句。因此在添加的时候,只需要设置需要赋值的字段的值。然后执行insert方法,就会自动生成一个insert语句,进行执行。执行后会返回添加的个数。
[b] 2.删除操作[/b]
对单表的删除,规则引擎也是根据设置的值,生成一个delete的语句。返回删除记录数。
[b] 3.修改操作[/b]
根据已经设置的值,首先规则引擎会根据该表的主键信息,生成update操作中的where部分,然后在根据其他字段设置的值,生成update部分。最后生成完成的update语句,进行执行。返回修改记录数。
[b] 4.替换操作[/b]
首先根据主键和其他字段的赋值信息,生成update语句进行执行,如果执行返回的修改记录数等于0,则再生成insert语句,进行执行。其效果就是如果存在记录则更新,不存在则添加记录。
[b] 5.查询操作[/b]
根据字段赋值的情况,将赋值的值生成where条件部分。然后生成一个select语句,其查询字段为所有该对象设置的字段信息,where部分就是赋值部分。然后通过执行select语句,来生成查询结果集。
数据库表操作时,有几个技巧。一个是表的主键信息是自动从数据库表中取的,但是有时如果想批量更新数据,那么可以将这边设置的表的主键信息做一下调整,那么这样得到的update语句就是一个批量更新的语句。注意update语句只能生成这边设定的主键。
在根据单表生成查询语句时,这种操作一般会希望简单的取某条记录的数据。但有些大数据的字段,会影响访问速度,因此可以在这里将其从结构中删除。这样在查询数据时,就不会查询这些暂时不需要取的字段。
字段的类型,也可以做一些设置。某些值,在数据库中存储的是字符串,但是实际描述的意思可能是数值,因此可以将字段的类型定义成数值型。这样就便于取值间的操作。但是这个只在逐行取值是有用的,当设置成直接导出结果集时,是直接将数据库得到的原始类型,直接输出的,这样可以保证数据不会因为格式转化发生异常。
[/size]

[size=large][b]八、自定义查询的设置[/b][/size]

[size=medium] 自定义查询是可以直接根据select语句,生成结果集。该结果集的类型可以分为以下四种:
[b] 1.查询后既缓存全部结果集[/b]
这是缺省的结果集读取方式,在执行完select语句之后,会根据resultset结果集,循环执行next,并且将记录存放在一个list中,保存起来。之后再访问此查询结果集时,就直接读取list了。这种方式可以最快的释放和数据库的连接。
[b] 2.查询后逐条访问时缓存结果集[/b]
这种方式在第一次执行完select语句之后,不会缓存结果值,之后当开始next时,才依次将字段以list的形式保存下来。一旦访问过一次之后,第二次再访问时,就是直接去list中的值了。
[b] 3.不缓存结果集,也不支持后退[/b]
这种方式是最快的读取数据库的方式,同时读取的值仍然存储在resultset中,对其操作都是对next的操作。由于前两种比较消耗内存,因此这种方式是能显著提高查询性能的功能。
[b] 4.不缓存结果集且支持后退[/b]
这种方式和上一种方式类似,只是查询的类型是支持游标的。因此在getRows时可以得到正确的值。
同时为了使查询可以支持分页,因为分页在数据库级别的话,对于大数据量结果集的查询是非常有效果的。这种方式一般根据数据库的不同,会有所不同,比如一般的数据库,会先执行一个count(*),取得了总记录数。然后如果是Mysql,则执行 limt,如果是Oracle,则执行rownumber方法,如果是SQL Server,则使用top。取得指定页数的结果集。
在自定义查询中有两个方法:
设置该月工资表的排序字段为{arg1},方向为{arg2}
设置该月工资表分页页码为{arg1},每页数为{arg2}
这两个方法就用于设置查询排序以及分页读取数据的操作。
如果设置了分页之后,那么取总个数,需要根据getCount方法来得到。
[/size]

[size=large][b]九、数据库表本地内存缓存[/b][/size]

[size=medium] 数据库访问一直是提高性能的一个重要考虑,如何使得数据库访问的次数更少,是系统优化的主要方式。因此对于一些变更不大频繁的表,可以通过本地内存缓存的方式,来加快系统的执行。
将表的结果集类型设置成“本地缓存表数据”,这样就能在访问此表时,系统会同时更新本地内存的表。其他通过单表进行查询时,就会以这个本地内存为主来进行执行了。
[/size]

[size=large][b]十、数据库表结构更新[/b][/size]

[size=medium] 当数据库表结构发生变更时,很多时候不一定了解究竟在那些地方应用了这些表结构,因此需要有系统自动来识别那些应用的数据库操作会发生异常。
点击工程中的所有表操作,然后点击更新按钮,系统会自动将该工程中所有的sql查询以及表访问一遍。如果发现查询SQL语句无法执行,或者表的字段已经和数据库中的实际字段信息不匹配,会以红色的标记来说明这些对象已经有问题。因此建议进行修改。
双击这个需要修改的数据库对象,会直接转到该对象的修改界面。如果是表,则直接点击右键,选择“和数据库同步”就行了,系统会自动根据数据库实际来进行更新。如果是查询,则需要手工修改SQL语句。
[/size]

[size=large][b]十一、规则执行轨迹的原理[/b][/size]

[size=medium] 通过规则配置器来设置后台处理逻辑,由于全部采用配置方式实现,因此不能像代码一样可以在编辑器中进行调试跟踪。当发生错误时,为了能够查看到究竟在哪一步出现了问题,因此就需要查看规则的执行轨迹以及执行结果。
规则的执行轨迹,是对系统的传入传出变量以及临时变量的记录,在每个规则执行时,如果这个规则的初始化动作或者满足条件动作,或者不满足条件动作执行时,系统会将规则执行前的变量的情况记录下来,然后在规则执行完毕后,在记录这些变量改变之后的值。
这样可以知道规则改变了那些变量,以及那些变量的值发生了变更。
同时还可以以更加简便的方式,单独对某一步的执行,进行拍照操作。
[/size]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值