Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 欧美一区二区三区大片,久久99国产亚洲高清观看首页,香蕉蕉亚亚洲aav综合

          整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          數(shù)據(jù)庫中的定義屬性(字段)

          義屬性

          概述

          ·django根據(jù)屬性的類型確定以下信息

          ·當(dāng)前選擇的數(shù)據(jù)庫支持字段的類型

          ·渲染管理表單時(shí)使用的默認(rèn)html控件

          ·在管理站點(diǎn)最低限度的驗(yàn)證

          ·django會(huì)為表增加自動(dòng)增長(zhǎng)的主鍵列,每個(gè)模型只能有一個(gè)主鍵列,如果使用選項(xiàng)設(shè)置某屬性為主鍵列后,則django不會(huì)再生成默認(rèn)的主鍵列

          ·屬性命名限制

          ·遵循標(biāo)識(shí)符規(guī)則

          ·由于django的查詢方式,不允許使用連續(xù)的下劃線

          ·定義屬性時(shí),需要字段類型,字段類型被定義在django.db.models.fields目錄下,為了方便使用,被導(dǎo)入到django.db.models中

          ·使用方式

          ·導(dǎo)入from django.db import models

          ·通過models.Field創(chuàng)建字段類型的對(duì)象,賦值給屬性

          邏輯刪除

          ·對(duì)于重要數(shù)據(jù)都做邏輯刪除,不做物理刪除,實(shí)現(xiàn)方法是定義isDelete屬性,類型為BooleanField,默認(rèn)值為False

          字段類型

          ·AutoField

          ·一個(gè)根據(jù)實(shí)際ID自動(dòng)增長(zhǎng)的IntegerField,通常不指定如果不指定,一個(gè)主鍵字段將自動(dòng)添加到模型中

          ·CharField(max_length=字符長(zhǎng)度)

          ·字符串,默認(rèn)的表單樣式是 TextInput

          ·TextField

          ·大文本字段,一般超過4000使用,默認(rèn)的表單控件是Textarea

          ·IntegerField

          ·整數(shù)

          ·DecimalField(max_digits=None, decimal_places=None)

          ·使用python的Decimal實(shí)例表示的十進(jìn)制浮點(diǎn)數(shù)

          ·參數(shù)說明

          ·DecimalField.max_digits

          ·位數(shù)總數(shù)

          ·DecimalField.decimal_places

          ·小數(shù)點(diǎn)后的數(shù)字位數(shù)

          ·FloatField

          ·用Python的float實(shí)例來表示的浮點(diǎn)數(shù)

          ·BooleanField

          ·true/false 字段,此字段的默認(rèn)表單控制是CheckboxInput

          ·NullBooleanField

          ·支持null、true、false三種值

          ·DateField([auto_now=False, auto_now_add=False])

          ·使用Python的datetime.date實(shí)例表示的日期

          ·參數(shù)說明

          ·DateField.auto_now

          ·每次保存對(duì)象時(shí),自動(dòng)設(shè)置該字段為當(dāng)前時(shí)間,用于"最后一次修改"的時(shí)間戳,它總是使用當(dāng)前日期,默認(rèn)為false

          ·DateField.auto_now_add

          ·當(dāng)對(duì)象第一次被創(chuàng)建時(shí)自動(dòng)設(shè)置當(dāng)前時(shí)間,用于創(chuàng)建的時(shí)間戳,它總是使用當(dāng)前日期,默認(rèn)為false

          ·說明

          ·該字段默認(rèn)對(duì)應(yīng)的表單控件是一個(gè)TextInput. 在管理員站點(diǎn)添加了一個(gè)JavaScript寫的日歷控件,和一個(gè)“Today"的快捷按鈕,包含了一個(gè)額外的invalid_date錯(cuò)誤消息鍵

          ·注意

          ·auto_now_add, auto_now, and default 這些設(shè)置是相互排斥的,他們之間的任何組合將會(huì)發(fā)生錯(cuò)誤的結(jié)果

          ·TimeField

          ·使用Python的datetime.time實(shí)例表示的時(shí)間,參數(shù)同DateField

          ·DateTimeField

          ·使用Python的datetime.datetime實(shí)例表示的日期和時(shí)間,參數(shù)同DateField

          ·FileField

          ·一個(gè)上傳文件的字段

          ·ImageField

          ·繼承了FileField的所有屬性和方法,但對(duì)上傳的對(duì)象進(jìn)行校驗(yàn),確保它是個(gè)有效的image

          字段選項(xiàng)

          ·概述

          ·通過字段選項(xiàng),可以實(shí)現(xiàn)對(duì)字段的約束

          ·在字段對(duì)象時(shí)通過關(guān)鍵字參數(shù)指定

          ·null

          ·如果為True,Django 將空值以NULL 存儲(chǔ)到數(shù)據(jù)庫中,默認(rèn)值是 False

          ·blank

          ·如果為True,則該字段允許為空白,默認(rèn)值是 False

          ·注意

          ·null是數(shù)據(jù)庫范疇的概念,blank是表單驗(yàn)證證范疇的

          ·db_column

          ·字段的名稱,如果未指定,則使用屬性的名稱

          ·db_index

          ·若值為 True, 則在表中會(huì)為此字段創(chuàng)建索引

          ·default

          ·默認(rèn)值

          ·primary_key

          ·若為 True, 則該字段會(huì)成為模型的主鍵字段

          ·unique

          ·如果為 True, 這個(gè)字段在表中必須有唯一值

          關(guān)系

          ·分類

          ·ForeignKey:一對(duì)多,將字段定義在多的端中

          ·ManyToManyField:多對(duì)多,將字段定義在兩端中

          ·OneToOneField:一對(duì)一,將字段定義在任意一端中

          ·用一訪問多

          ·格式

          ·對(duì)象.模型類小寫_set

          ·示例

          grade.students_set

          ·用一訪問一

          ·格式

          ·對(duì)象.模型類小寫

          ·示例

          ·grade.students

          ·訪問id

          ·格式

          ·對(duì)象.屬性_id

          ·示例

          ·student.sgrade_id

          JavaScript 類型是在java.util.Date類的基礎(chǔ)上建立起來的。所以,Date類型使用的是UTC, 又稱世界統(tǒng)一時(shí)間,使用自1970年1月1日起經(jīng)過的毫秒數(shù)來保存,可以精確到之后的285616年。

          //創(chuàng)建一個(gè)日期對(duì)象

          var date = new Date();

          console.log(date); //FireFox: Wed Nov 07 2018 21:31:23 GMT+0800

          //Chrome: Wed Nov 07 2018 21:31:23 GMT+0800 (中國標(biāo)準(zhǔn)時(shí)間)

          //IE: Wed Nov 07 21:31:23 UTC+0800 2018

          //Opera: Wed Nov 07 2018 21:31:23 GMT+0800

          構(gòu)造方法中可以傳遞參數(shù),指定需要的時(shí)間,如果沒有傳參數(shù),就默認(rèn)使用當(dāng)前的時(shí)間。調(diào)用Date構(gòu)造方法不傳遞參數(shù)時(shí),新實(shí)例化的對(duì)象自動(dòng)獲取當(dāng)前的日期時(shí)間,但是在不同的瀏覽器上顯示的結(jié)果是有區(qū)別的,如上所示。

          ECMAScript 中有兩個(gè)方法,分別是 Date.parse() 和 Date.UTC(), 這兩個(gè)方法屬于靜態(tài)方法,不需要進(jìn)行實(shí)例化。 Date.parse()方法接收一個(gè)日期格式的參數(shù),并根據(jù)這個(gè)字符串返回相應(yīng)的毫秒數(shù)。例如:

          console.log(Date.parse("4/12/2007")); //返回一個(gè)毫秒數(shù)。毫秒數(shù)1176307200000, 各 個(gè)瀏覽器相同。

          但是返回的這個(gè)值對(duì)于我們來說是不容易理解的,所以可以返回我們能夠看得懂的值。如下:

          var date = new Date(Date.parse("4/12/2007"));

          console.log(date); //Thu Apr 12 2007 00:00:00 GMT+0800

          還可以這樣寫:

          var date = new Date(1176307200000); //注意參數(shù)當(dāng)中是數(shù)字

          console.log(date); //Thu Apr 12 2007 00:00:00 GMT+0800

          如果參數(shù)變成字符串?dāng)?shù)字,如下:

          var date = new Date("1176307200000"); //注意參數(shù)當(dāng)中是字符串

          console.log(date); //Invalid Date

          當(dāng)然可以這樣寫,var date = new Date("4/12/2007"); console.log(date);

          //Thu Apr 12 2007 00:00:00 GMT+0800, 默認(rèn)后臺(tái)自動(dòng)調(diào)用Date.parse() 方法。

          關(guān)于更多日期和時(shí)間的用法,請(qǐng)關(guān)注下期的更新。

          、介紹

          規(guī)則屬性是您可以添加到業(yè)務(wù)規(guī)則以修改規(guī)則行為的附加規(guī)范。 在 DRL 文件中,您通常在規(guī)則條件和操作的上方定義規(guī)則屬性,多個(gè)屬性位于單獨(dú)的行中,格式如下:

          rule "rule_name"
              // Attribute
              // Attribute
              when
                  // Conditions
              then
                  // Actions
          end
          

          二、常見的規(guī)則屬性

          規(guī)則屬性

          解釋

          舉例

          salience

          定義規(guī)則優(yōu)先級(jí),是一個(gè)整數(shù)。當(dāng)在激活隊(duì)列中排序時(shí),salience的值越大,優(yōu)先級(jí)越高

          salience 99

          enabled

          定義規(guī)則是否啟用. true 啟用,false 禁用,默認(rèn)值是true

          enabled true

          date-effective

          包含時(shí)間和日期的字符串,當(dāng)當(dāng)前時(shí)間大于date-effective時(shí),該規(guī)則才會(huì)被激活。這個(gè)時(shí)間格式可以修改,見下方具體的用法

          date-effective "4-5月-2022"

          date-expires

          設(shè)置規(guī)則的過期時(shí)間,時(shí)間格式和上方一樣。

          date-expires "4-5月-2022"

          no-loop

          布爾值,默認(rèn)值為false, 定義當(dāng)當(dāng)前規(guī)則規(guī)則的結(jié)果修改了fact對(duì)象時(shí),是否可以再次執(zhí)行該規(guī)則。true:不可以, false:可以,可能會(huì)導(dǎo)致死循環(huán)。指的是當(dāng)前規(guī)則的修改,如果別的規(guī)則修改了,還會(huì)導(dǎo)致該規(guī)則的觸發(fā)

          no-loop true

          agenda-group

          Agenda groups允許您對(duì)agenda進(jìn)行分區(qū),以提供對(duì)規(guī)則組的更多執(zhí)行控制。 只有獲得焦點(diǎn)的議程組中的規(guī)則才能被激活。 ,但是這個(gè)里面有個(gè)特例,如果某個(gè)規(guī)則沒有配置 agenda-group,但是它模式匹配成功了,那么會(huì)被分到默認(rèn)的組(main),這個(gè)main組的規(guī)則也會(huì)執(zhí)行。

          agenda-group "GroupName"

          auto-focus

          布爾值,僅適用于Agenda-Group內(nèi)的規(guī)則。當(dāng)值為true時(shí),下次激活該規(guī)則時(shí),會(huì)將焦點(diǎn)自動(dòng)給這個(gè)Agenda group

          auto-focus true

          activation-group

          表示該組下的規(guī)則只有一個(gè)規(guī)則會(huì)被執(zhí)行,該組下其余激活的規(guī)則會(huì)被取消執(zhí)行。 但是別的組激活的規(guī)則可能會(huì)被執(zhí)行。

          activation-group "GroupName"

          duration

          long類型的值,如果在這個(gè)時(shí)間之后規(guī)則還成立,那么執(zhí)行該規(guī)則

          duration 1000

          timer

          一個(gè)字符串,標(biāo)識(shí)用于調(diào)度規(guī)則的 int(間隔)或 cron 計(jì)時(shí)器定義。

          Example: timer ( cron:* 0/15 * * * ? ) (every 15 minutes)

          calendar

          定義Quartz calendar用于調(diào)度規(guī)則。


          lock-on-active

          一個(gè)布爾值,僅適用于規(guī)則流組或議程組中的規(guī)則。 選擇該選項(xiàng)后,下次規(guī)則的規(guī)則流組變?yōu)榛顒?dòng)狀態(tài)或規(guī)則的議程組獲得焦點(diǎn)時(shí),規(guī)則無法再次激活,直到規(guī)則流組不再處于活動(dòng)狀態(tài)或議程組失去焦點(diǎn)。 這是 no-loop 屬性的更強(qiáng)版本,因?yàn)槠ヅ湟?guī)則的激活被丟棄,無論更新的來源如何(不僅是規(guī)則本身)。 此屬性非常適合計(jì)算規(guī)則,其中您有許多修改事實(shí)的規(guī)則并且您不希望任何規(guī)則重新匹配和再次觸發(fā)。

          lock-on-active true

          dialect

          將 JAVA 或 MVEL 標(biāo)識(shí)為用于規(guī)則中的代碼表達(dá)式的語言的字符串。 默認(rèn)情況下,該規(guī)則使用在包級(jí)別指定的方言。 此處指定的任何方言都會(huì)覆蓋該規(guī)則的包方言設(shè)置。

          dialect "JAVA"

          三、部分規(guī)則屬性案例

          此處編寫出規(guī)則文件和部分核心Java代碼


          項(xiàng)目結(jié)構(gòu)

          1、salience

          定義規(guī)則執(zhí)行的優(yōu)先級(jí),salience的值越大,優(yōu)先級(jí)越高

          1、規(guī)則文件的編寫

          rule "salience_rule_1"
              salience 4
              when
              then
                  System.out.println("rule 1");
          end
          
          rule "salience_rule_2"
              salience 3
              when
              then
                  System.out.println("rule 2");
          end
          
          // 此處優(yōu)先級(jí)的值是動(dòng)態(tài)獲取來的
          rule "salience_rule_3"
              salience $dynamicSalience
              when
                  $dynamicSalience: Integer()
              then
                  System.out.println("rule 3");
          end
          

          注意:
          我們的salience_rule_3的優(yōu)先級(jí)的值是動(dòng)態(tài)來的,即是從工作內(nèi)存中獲取的。

          2、java代碼編寫

          public class DroolsSalienceApplication {
              public static void main(String[] args) {
                  KieServices kieServices = KieServices.get();
                  KieContainer kieContainer = kieServices.getKieClasspathContainer();
                  KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
          
                  // 向工作內(nèi)存中插入一個(gè)Integer值,salience_rule_3 需要用到這個(gè)優(yōu)先級(jí)
                  kieSession.insert(10);
          
                  // 只匹配規(guī)則名稱是已 salience_ 開頭的規(guī)則,忽略其余的規(guī)則
                  kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("salience_"));
          
                  kieSession.dispose();
              }
          }
          

          kieSession.insert(10);此處向工作內(nèi)存中插入一個(gè)值,將會(huì)匹配到salience_rule_3,然后動(dòng)態(tài)修改它的優(yōu)先級(jí)。

          3、運(yùn)行結(jié)果

          rule 3
          rule 1
          rule 2
          

          因?yàn)?salience 的值越大優(yōu)先級(jí)越高,所以是這個(gè)順序。

          2、enabled

          定義規(guī)則是否啟用,true啟用 false禁用

          1、規(guī)則文件編寫

          package rules
          
          rule "enabled_rule_1"
              // 禁用此規(guī)則
              enabled false
              when
              then
                  System.out.println("enabled_rule_1");
          end
          
          rule "enabled_rule_2"
              // 啟用此規(guī)則,默認(rèn)就是啟用
              enabled true
              when
              then
                  System.out.println("enabled_rule_2");
          end
          

          enabled_rule_2這個(gè)規(guī)則需要運(yùn)行,enabled_rule_1這個(gè)規(guī)則不能運(yùn)行。

          2、java代碼編寫

          /**
           * 測(cè)試規(guī)則的啟用和禁用
           */
          public class DroolsEnabledApplication {
              public static void main(String[] args) {
                  KieServices kieServices = KieServices.get();
                  KieContainer kieContainer = kieServices.getKieClasspathContainer();
                  KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
                  // 只匹配規(guī)則名稱是已 enabled_ 開頭的規(guī)則,忽略其余的規(guī)則
                  kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("enabled_"));
                  kieSession.dispose();
              }
          }
          

          沒有需要注意的地方

          3、運(yùn)行結(jié)果

          enabled_rule_2

          可以看到只有規(guī)則enabled_rule_2輸出了結(jié)果,而enabled_rule_1被禁用了。

          3、date-effective

          定義規(guī)則什么時(shí)候啟用,只有當(dāng)前時(shí)間>規(guī)則時(shí)間才會(huì)啟用。需要注意默認(rèn)的時(shí)間格式,可以通過java代碼進(jìn)行修改。

          1、規(guī)則文件編寫

          package rules
          import java.text.SimpleDateFormat
          import java.util.Date
          
          // 規(guī)則一:輸出當(dāng)前時(shí)間
          rule "date_effective_rule_1"
              when
              then
                  System.out.println("當(dāng)前時(shí)間:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
          end
          
          // 規(guī)則二: 該規(guī)則會(huì)在2022-05-18 10:54:26之后被激活
          rule "date_effective_rule_2"
              date-effective "2022-05-18 10:54:26"
              when
              then
                  System.out.println("date_effective_rule_2執(zhí)行了,規(guī)則允許被執(zhí)行的時(shí)間應(yīng)該在2022-05-18 10:54:26之后");
          end
          
          // 規(guī)則三: 該規(guī)則會(huì)在2023-05-18 10:54:26之后被激活
          rule "date_effective_rule_3"
              date-effective "2023-05-18 10:54:26"
              when
              then
                  System.out.println("date_effective_rule_3會(huì)在時(shí)間到了2023-05-18 10:54:26才激活");
          end
          

          規(guī)則一:輸出當(dāng)前時(shí)間
          規(guī)則二: 該規(guī)則會(huì)在2022-05-18 10:54:26之后被激活
          規(guī)則三: 該規(guī)則會(huì)在2023-05-18 10:54:26之后被激活

          2、java代碼編寫

          /**
           * 測(cè)試規(guī)則在執(zhí)行的時(shí)間之后才能執(zhí)行
           */
          public class DroolsDateEffectiveApplication {
              public static void main(String[] args) {
                  // 設(shè)置日期格式,否則可能會(huì)報(bào)錯(cuò)(Wrong date-effective value: Invalid date input format: [2022-05-18 10:54:26] it should follow: [d-MMM-yyyy]]])
                  System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
                  KieServices kieServices = KieServices.get();
                  KieContainer kieContainer = kieServices.getKieClasspathContainer();
                  KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
                  // 只匹配規(guī)則名稱是已 date_effective_ 開頭的規(guī)則,忽略其余的規(guī)則
                  kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("date_effective_"));
                  kieSession.dispose();
              }
          }
          

          需要注意System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");這句,這個(gè)修改drools中的日期格式,因?yàn)橐?guī)則中寫的日期格式為date-effective "2023-05-18 10:54:26"而默認(rèn)的格式為d-MMM-yyyy,不修會(huì)報(bào)錯(cuò)。

          3、運(yùn)行結(jié)果

          當(dāng)前時(shí)間:2022-05-18 10:59:38
          date_effective_rule_2執(zhí)行了,規(guī)則允許被執(zhí)行的時(shí)間應(yīng)該在2022-05-18 10:54:26之后

          可以看到規(guī)則二執(zhí)行了,規(guī)則三沒有執(zhí)行,因?yàn)橐?guī)則三需要時(shí)間到達(dá)了2023-05-18 10:54:26才執(zhí)行,而當(dāng)前時(shí)間不符合。

          4、注意事項(xiàng)

          如果出現(xiàn)了Wrong date-effective value: Invalid date input format: [2022-05-18 10:54:26] it should follow: [d-MMM-yyyy]]]這個(gè)錯(cuò)誤該怎么解決了,這是因?yàn)槿掌诟袷讲徽_。需要在java代碼中進(jìn)行如下設(shè)置System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss")

          4、date-expires

          定義規(guī)則的過期時(shí)間,即規(guī)則到了該時(shí)間之后就不可使用了。和date-effective的用法類似,此處就不演示了。

          5、no-loop

          定義當(dāng)當(dāng)前規(guī)則的結(jié)果修改了fact對(duì)象時(shí),是否可以再次執(zhí)行該規(guī)則。可以防止死循環(huán)

          1、規(guī)則文件編寫

          package rules
          import java.util.concurrent.TimeUnit
          import java.text.SimpleDateFormat
          import java.util.Date
          
          rule "no_loop_rule_1"
              no-loop true
              when
                  $i: Integer(intValue() < 20)
              then
                  modify($i){
                  }
                  System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " no_loop_rule_1 i=" + $i);
          end
          
          rule "no_loop_rule_2"
              no-loop false
          
              when
                  $i: Integer(intValue() < 20)
              then
                  modify($i){
                  }
                  TimeUnit.SECONDS.sleep(1);
                  System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " no_loop_rule_2 i=" + $i);
          end
          

          解釋:
          no_loop_rule_1no-loop true表示如果當(dāng)前規(guī)則的RHS部分,對(duì)Fact對(duì)象進(jìn)行了修改,則不會(huì)再次觸發(fā)該規(guī)則。那如果是no_loop_rule_2修改了,會(huì)導(dǎo)致該規(guī)則的觸發(fā)嗎?答案是會(huì)觸發(fā),如果我不想被觸發(fā)呢?那么使用lock-on-active可以實(shí)現(xiàn)。
          no_loop_rule_2no-loop false表示如果當(dāng)前規(guī)則的RHS部分,對(duì)Fact對(duì)象進(jìn)行了修改,那么還會(huì)再次匹配這個(gè)規(guī)則。

          2、java代碼編寫

          /**
           * 測(cè)試規(guī)則是否可以再次被執(zhí)行
           */
          public class DroolsNoLoopApplication {
              public static void main(String[] args) throws InterruptedException {
                  System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
                  KieServices kieServices = KieServices.get();
                  KieContainer kieContainer = kieServices.getKieClasspathContainer();
                  KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
                  kieSession.insert(10);
                  // 只匹配規(guī)則名稱是已 no_loop_ 開頭的規(guī)則,忽略其余的規(guī)則
                  kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("no_loop_"));
                  // 睡眠5s,使規(guī)則文件中的規(guī)則執(zhí)行完
                  TimeUnit.SECONDS.sleep(5);
                  kieSession.dispose();
              }
          }
          

          此處 java 代碼,睡眠了5s,是為了讓規(guī)則執(zhí)行。

          3、運(yùn)行結(jié)果

          2022-05-18 11:42:29 no_loop_rule_1 i=10
          2022-05-18 11:42:31 no_loop_rule_2 i=10
          2022-05-18 11:42:31 no_loop_rule_1 i=10
          2022-05-18 11:42:32 no_loop_rule_2 i=10
          

          解釋:
          2022-05-18 11:42:29 no_loop_rule_1 i=10: no_loop_rule_1被觸發(fā),由于RHS部分使用了modify修改了規(guī)則內(nèi)存中的對(duì)象,但是該規(guī)則存在 no-loop true 的屬性,所以該規(guī)則沒有再次被觸發(fā),即只輸出了一次。

          2022-05-18 11:42:30 no_loop_rule_2 i=10 2022-05-18 11:42:30 no_loop_rule_1 i=10 此時(shí)規(guī)則 no_loop_rule_2 執(zhí)行了,由于該規(guī)則的 no-loop 為 false 并且使用了 modify 方法,所以該規(guī)則多次被觸發(fā)了,從結(jié)果上看,貌似規(guī)則 no_loop_rule_1 又再次被觸發(fā)了,不是應(yīng)該不被觸發(fā)嗎,因?yàn)樵O(shè)置了no-loop true?因?yàn)檫@是no_loop_rule_2導(dǎo)致no_loop_rule_1觸發(fā)的,而no_loop只對(duì)自身的RHS修改有效。

          疑問:
          那如果將 no-loop換成lock-on-active結(jié)果會(huì)一樣嗎?可以自己嘗試一下看看結(jié)果。

          6、agenda-group

          將被模式匹配成功后的規(guī)則,進(jìn)行分組,只有獲得焦點(diǎn)的組,才可以執(zhí)行規(guī)則。但是這個(gè)里面有個(gè)特列,如果某個(gè)規(guī)則在模式匹配,匹配成功了,但是沒有配置agenda-group,那么它會(huì)被分配到main組,這個(gè)main組的規(guī)則總是執(zhí)行的。

          agenda-group的數(shù)據(jù)結(jié)構(gòu)就類似stack,激活的組是在棧頂。參考如下圖:


          agenda-group



          參考鏈接: https://stackoverflow.com/questions/6870192/understanding-agenda-group-in-drools

          1、規(guī)則文件編寫

          package rules
          
          /**
              agenda-group 的數(shù)據(jù)結(jié)構(gòu)類似與棧,激活的組會(huì)被放置在棧頂,
              `main`是默認(rèn)組,總是存在的,即沒有配置agenda-group的就是`main`,
              `main`總是會(huì)執(zhí)行的。
          */
          
          rule "agenda_group_001_rule_1"
              agenda-group "group-001"
              when
              then
                  System.out.println("agenda_group_001_rule_1");
          end
          
          rule "agenda_group_001_rule_2"
              agenda-group "group-001"
              when
              then
                  System.out.println("agenda_group_001_rule_2");
          end
          
          rule "agenda_group_002_rule_3"
              agenda-group "group-002"
              when
              then
                  System.out.println("agenda_group_002_rule_3");
          end
          
          rule "agenda_group_no_group_rule_4"
              when
              then
                  System.out.println("agenda_group_no_group_rule_4");
          end
          

          注意: 此處其實(shí)是 存在 3個(gè)組的,agenda_group_no_group_rule_4如果模式匹配成功后會(huì)被分配到main組,main總是會(huì)被執(zhí)行的。

          2、java代碼編寫

          /**
           * 測(cè)試規(guī)則分組
           */
          public class DroolsAgendaGroupApplication {
              public static void main(String[] args) {
                  // 設(shè)置日期格式,否則可能會(huì)報(bào)錯(cuò)(Wrong date-effective value: Invalid date input format: [2022-05-18 10:54:26] it should follow: [d-MMM-yyyy]]])
                  System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
                  KieServices kieServices = KieServices.get();
                  KieContainer kieContainer = kieServices.getKieClasspathContainer();
                  KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
          
                  // 激活組
                  kieSession.getAgenda().getAgendaGroup("group-001").setFocus();
          
                  // 只匹配規(guī)則名稱是已 agenda_group_ 開頭的規(guī)則,忽略其余的規(guī)則
                  kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("agenda_group_"));
                  kieSession.dispose();
              }
          }
          

          激活group-001分組。

          3、運(yùn)行結(jié)果

          agenda_group_001_rule_1
          agenda_group_001_rule_2
          agenda_group_no_group_rule_4
          

          解釋:
          agenda_group_no_group_rule_4為什么會(huì)被輸出呢?它沒有定義agenda-group啊,而且我們激活的也是group-001分組,它不應(yīng)該輸出啊。這是應(yīng)為這個(gè)規(guī)則模式匹配成功后被分配到了默認(rèn)的main組,而main組一定會(huì)被執(zhí)行的。

          7、auto-focus

          設(shè)置某個(gè)agenda-group默認(rèn)獲取到焦點(diǎn),和在java代碼中使用kieSession.getAgenda().getAgendaGroup("group-001").setFocus();或在drl文件中使用drools.setFocus(..)一樣。

          8、activation-group

          處于該分組中激活的規(guī)則,同一個(gè)組下,只有一個(gè)規(guī)則可以執(zhí)行,其余的會(huì)被取消執(zhí)行。但是別的組中激活的規(guī)則還是可以執(zhí)行的。

          1、規(guī)則文件編寫

          package rules
          
          rule "activation_group_001_rule_1"
              activation-group "group-001"
              salience 1
              when
              then
                  System.out.println("activation_group_001_rule_1");
          end
          
          rule "activation_group_001_rule_2"
              activation-group "group-001"
              salience 2
              when
              then
                  System.out.println("activation_group_001_rule_2");
          end
          
          rule "activation_group_002_rule_3"
              activation-group "group-002"
              when
              then
                  System.out.println("activation_group_002_rule_3");
          end
          
          rule "activation_group_no_group_rule_4"
              when
              then
                  System.out.println("activation_group_no_group_rule_4");
          end
          

          activation-group "group-001"此處對(duì)這個(gè)組的規(guī)則指定了優(yōu)先級(jí),優(yōu)先級(jí)高的先執(zhí)行,執(zhí)行完之后,該組別的規(guī)則不執(zhí)行。

          2、java代碼編寫

          public class DroolsActivationGroupApplication {
              public static void main(String[] args) {
                  System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
                  KieServices kieServices = KieServices.get();
                  KieContainer kieContainer = kieServices.getKieClasspathContainer();
                  KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
                  // 只匹配規(guī)則名稱是已 activation_group_ 開頭的規(guī)則,忽略其余的規(guī)則
                  kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("activation_group_"));
                  kieSession.dispose();
              }
          }
          

          3、運(yùn)行結(jié)果

          activation_group_001_rule_2
          activation_group_002_rule_3
          activation_group_no_group_rule_4
          

          可以看到分組group-001中有2個(gè)規(guī)則,但是只執(zhí)行了一個(gè)規(guī)則。

          9、duration

          long類型的值,單位毫秒,如果在這個(gè)時(shí)間之后規(guī)則還成立,那么執(zhí)行該規(guī)則。

          1、規(guī)則文件編寫

          package rules
          import java.text.SimpleDateFormat
          import java.util.Date
          
          rule "duration_rule_1"
              // 延遲1s后執(zhí)行規(guī)則
              duration 1000
              when
                  $i: Integer(intValue() < 10)
              then
                  System.out.println(Thread.currentThread().getName() + ": " + 
                  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())+ 
                  " duration_rule_1 $i:"+$i);
          end
          

          定義規(guī)則延遲1s后進(jìn)行執(zhí)行。

          2、java代碼編寫

          /**
           * 在多少毫秒后,如果條件還成立,則觸發(fā)該規(guī)則
           */
          public class DroolsDurationApplication {
              public static void main(String[] args) throws InterruptedException {
                  System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
                  KieServices kieServices = KieServices.get();
                  KieContainer kieContainer = kieServices.getKieClasspathContainer();
                  KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
          
                  FactHandle factHandle = kieSession.insert(3);
                  // 只匹配規(guī)則名稱是已 duration_ 開頭的規(guī)則,忽略其余的規(guī)則
                  new Thread(() -> {
                      // 調(diào)用此方法會(huì)阻塞調(diào)用線程,直到 `kieSession.halt();`的調(diào)用
                      System.out.println("當(dāng)前時(shí)間:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                      kieSession.fireUntilHalt(new RuleNameStartsWithAgendaFilter("duration_"));
                  }, "fire-thread").start();
          
                  // 如果修改這個(gè)值,使得規(guī)則的條件不成立,看規(guī)則是否還執(zhí)行
                  kieSession.update(factHandle, 4);
          
                  TimeUnit.SECONDS.sleep(2);
                  kieSession.halt();
          
                  kieSession.dispose();
              }
          }
          

          注意:
          1、我們調(diào)用出發(fā)所有規(guī)則執(zhí)行的方法不在是fireAllRules而是fireUntilHalt
          2、fireUntilHalt的調(diào)用會(huì)阻塞線程,直到調(diào)用halt方法,因此fireUntilHalt需要放置到另外的線程中調(diào)用。而且我們觀察規(guī)則的執(zhí)行,也是在這個(gè)線程中調(diào)用的。

          3、運(yùn)行結(jié)果

          當(dāng)前時(shí)間:2022-05-18 14:13:36
          fire-thread: 2022-05-18 14:13:37 duration_rule_1 $i:4
          

          可以看到,延遲1s后規(guī)則執(zhí)行了。

          4、疑問

          如果我們?cè)?/span>1s鐘之內(nèi),將規(guī)則的條件修改成不成立,那么規(guī)則還執(zhí)行嗎?答案:不執(zhí)行。

          10、lock-on-active

          rule flow groups or agenda groups配合使用。

          需求:
          我們有2個(gè)規(guī)則,并且同屬于一個(gè)組,規(guī)則二執(zhí)行完之后,工作內(nèi)存中的Fact對(duì)象的值發(fā)生了變化,導(dǎo)致規(guī)則一滿足執(zhí)行的條件,而規(guī)則一已經(jīng)執(zhí)行一遍了,此處需要阻止規(guī)則二的觸發(fā)導(dǎo)致規(guī)則一的出觸發(fā)。使用
          lock-on-active 即可實(shí)現(xiàn)。

          1、規(guī)則文件編寫

          package rules
          
          import com.huan.drools.lockonactive.Person
          
          rule "lock_on_active_rule_01"
              agenda-group "group-001"
              lock-on-active true
              when
                  $p: Person(age < 18)
              then
                  System.out.println("lock_on_active_rule_01: 用戶:[" + $p.getName() + "]當(dāng)前的年齡是:[" + $p.getAge() + "]");
           end
          
          rule "lock_on_active_rule_02"
              agenda-group "group-001"
              when
                  $p: Person(name == "張三")
              then
                  modify($p){
                      setAge(15)
                  }
                  System.out.println("lock_on_active_rule_02: 用戶:[" + $p.getName() + "]當(dāng)前的年齡是:[" + $p.getAge() + "]");
          end
          

          規(guī)則lock_on_active_rule_01加了lock-on-active true屬性后,規(guī)則lock_on_active_rule_02修改Fact導(dǎo)致規(guī)則lock_on_active_rule_01的條件成立,此時(shí)規(guī)則也是不會(huì)執(zhí)行的。

          2、java代碼編寫

          /**
           * 一個(gè)簡(jiǎn)單的實(shí)體類
           *
           * @author huan.fu
           * @date 2022/5/18 - 14:34
           */
          @Getter
          @Setter
          @AllArgsConstructor
          public class Person {
              private String name;
              private Integer age;
          }
          
          public class DroolsLockOnActiveApplication {
              public static void main(String[] args) {
                  System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
                  KieServices kieServices = KieServices.get();
                  KieContainer kieContainer = kieServices.getKieClasspathContainer();
                  KieSession kieSession = kieContainer.newKieSession("rule-attributes-ksession");
                  // 激活組
                  kieSession.getAgenda().getAgendaGroup("group-001").setFocus();
          
                  Person person = new Person("張三", 20);
                  kieSession.insert(person);
          
                  // 只匹配規(guī)則名稱是已 lock_on_active_ 開頭的規(guī)則,忽略其余的規(guī)則
                  kieSession.fireAllRules(new RuleNameStartsWithAgendaFilter("lock_on_active_"));
                  kieSession.dispose();
              }
          }
          

          3、運(yùn)行結(jié)果

          lock_on_active_rule_02: 用戶:[張三]當(dāng)前的年齡是:[15]
          

          可以看到只有規(guī)則二執(zhí)行了,說明阻止了規(guī)則一的執(zhí)行。

          四、完整代碼

          https://gitee.com/huan1993/spring-cloud-parent/tree/master/drools/drools-drl-rule-attributes

          五、參考鏈接

          1、https://docs.drools.org/7.69.0.Final/drools-docs/html_single/index.html#rules-attributes-ref_drl-rules
          2、 https://stackoverflow.com/questions/6870192/understanding-agenda-group-in-drools


          主站蜘蛛池模板: 无码国产精品一区二区免费式芒果 | 国产婷婷色一区二区三区| 精品无码一区在线观看| 久久精品国产一区二区三区肥胖 | 亚洲av乱码一区二区三区香蕉| 国产AV午夜精品一区二区三| 精品国产一区二区三区免费| 国产福利91精品一区二区| 国产精品视频一区| 视频一区二区三区在线观看| 中文字幕一区二区三区四区| 日韩人妻无码一区二区三区99| 亚洲中文字幕久久久一区| 国产一区二区免费在线| 性无码一区二区三区在线观看| 亚洲第一区二区快射影院| 夜夜爽一区二区三区精品| 性色AV一区二区三区| 韩国精品一区视频在线播放| 国产不卡视频一区二区三区| 亚洲一区二区三区高清| 国产精品一区二区三区高清在线| 国产一区二区三区在线观看精品| 精品一区二区三区自拍图片区| 午夜爽爽性刺激一区二区视频| 中文字幕一区视频一线| 中文精品一区二区三区四区| 久99精品视频在线观看婷亚洲片国产一区一级在线 | 视频一区视频二区在线观看| 亚洲AV乱码一区二区三区林ゆな | 日本免费一区二区久久人人澡| 精品国产一区二区三区AV| 亚洲综合国产一区二区三区| 国产精品一区二区综合| 农村乱人伦一区二区| 中文字幕亚洲一区| 国产在线观看一区二区三区| 亚洲AV综合色一区二区三区 | 国产精品区AV一区二区| 天堂一区人妻无码| 无码人妻精品一区二区三区久久|