zoukankan      html  css  js  c++  java
  • 语法基础

    package

    package定义在规则文件的首行,是规则文件的三大模块之一。

    package表示规则的逻辑路径。建议在定义的时候和物理路径相同。但这并不是必须的。可以不同。不过强烈建议。

    package包含 import、global、funcation、query、rule、EOF。

    rule是规则文件的核心。前面学习的规则属性就是rule中的内容。

    在前面的示例中,我们配置过kmodule.xml这样的一个文件,在这个文件中KieBase元素设置了packages路径,来表示当前路径下的所有规则文件,像规则文件、决策表、领域语言文件等等都会被加入到规则库中。但是当前路径下子文件夹的规则文件并没有包含在当前的规则库中。

    package参数实际上是一个命名空间,没有去关联文件或者文件夹。因此,可以有多个规则目录为规则库构建源组合规则。有一个顶级的package配置。所有的规则都在其控制之下。

    虽然生命在不同名称下的资源不可能合并成一个包,但是单个规则库可以用多个包来构建它。

    packages可以设置多个路径,通过逗号来分割。

    创建规则内容:

     1 package rules.isPackage
     2 rule "testRuleNameOnly"
     3     when
     4         eval(true);
     5     then
     6         System.out.println("testRuleNameOnly say hello");
     7 end
     8 rule "testRuleNameOnly"
     9     when
    10         eval(true);
    11     then
    12         System.out.println("testRuleNameOnly say hello");
    13 end

    在配置文件中继续添加:

      <kbase name="isPackage" packages="rules.isPackage">
            <ksession name="isPackge"/>
        </kbase>

    看下运行结果:

    2019-08-07 22:58:12 [ERROR]org.drools.....KieProject - Unable to build KieBaseModel:isPackage
    [8,0]: Duplicate rule name: testRuleNameOnly
    Rule Compilation error : [Rule name='testRuleNameOnly']
        rules/isPackage/Rule_testRuleNameOnly670538843.java (3:109) : The type Rule_testRuleNameOnly670538843 is already defined
    
    
    
    java.lang.RuntimeException: Error while creating KieBase[Message [id=1, kieBase=isPackage, level=ERROR, path=D:JavaDevworkspaceDroolsProjectBaseProject	argetclasses
    ules.isPackagepackage.drl, line=8, column=0
       text=Duplicate rule name: testRuleNameOnly], Message [id=2, kieBase=isPackage, level=ERROR, path=D:JavaDevworkspaceDroolsProjectBaseProject	argetclasses
    ules.isPackagepackage.drl, line=8, column=0
       text=Rule Compilation error The type Rule_testRuleNameOnly670538843 is already defined]]
    
        at org.drools.compiler.kie.builder.impl.KieContainerImpl.getKieBase(KieContainerImpl.java:363)
        at org.drools.compiler.kie.builder.impl.KieContainerImpl.newKieSession(KieContainerImpl.java:519)
        at org.drools.compiler.kie.builder.impl.KieContainerImpl.newKieSession(KieContainerImpl.java:487)
        at com.packages.RulePackage.RulePackage(RulePackage.java:14)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
        at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
        at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
        at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
        at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

    很是明显的一个错误,提示规则文件代码rule名称重复了。修改名称后就可以正常运行。这个时候再添加一个规则文件,内容如下:

    package rules.isPackage2
    rule "testRuleNameOnly"
        when
            eval(true);
        then
            System.out.println("testRuleNameOnly say hello");
    end

    和之前的例子中区别就是package参数是不相同的。继续看下结果:

    2019-08-07 23:02:41 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now FIRING_ALL_RULES
    testRuleNameOnly say hello
    testRuleNameOnly say hello
    testRuleNameOnly say hello
    2019-08-07 23:02:41 [DEBUG]org.drools...DefaultAgenda - State was FIRING_ALL_RULES is now HALTING
    2019-08-07 23:02:41 [DEBUG]org.drools...DefaultAgenda - State was HALTING is now INACTIVE
    总共执行了3条规则
    2019-08-07 23:02:41 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now DISPOSED

    从结果中可以看出,同一个物理路径下的规则相关文件都会被加载到规则苦衷,不同规则文件中不同的package会影响规则名称的定义。

    继续创建一个规则文件,测试一下子目录下的规则文件是不是会被加载。

    创建规则内容:

    package rules.isPackage.package2;
    rule "testRuleNameOnly"
        when
            eval(true);
        then
            System.out.println("testRuleNameOnly say hello");
    end

    看下结果:

    2019-08-07 23:06:32 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now FIRING_ALL_RULES
    testRuleNameOnly say hello
    testRuleNameOnly say hello
    testRuleNameOnly say hello
    2019-08-07 23:06:32 [DEBUG]org.drools...DefaultAgenda - State was FIRING_ALL_RULES is now HALTING
    2019-08-07 23:06:32 [DEBUG]org.drools...DefaultAgenda - State was HALTING is now INACTIVE
    总共执行了3条规则
    2019-08-07 23:06:32 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now DISPOSED

    结果是没有任何变化的。说明了规则库不会去加载子目录下的规则相关文件。

    global

    全局变量,由关键字global class name组成。 class是很随意的,能够为规则提供操作数据或者服务等功能。特别实在规则RHS部分中使用程序提供的服务,例如,添加日志,发送邮件,操作数据表等。

    global全局变量与Fact对象有区别,不会因为值的改变而影响到规则的再次激活。

    创建规则内容如下:

    package rules.isPackage
    rule "testRuleNameOnly"
        when
            eval(true);
        then
            System.out.println("testRuleNameOnly say hello");
    end
    rule "testRuleNameOnly2"
        when
            eval(true);
        then
            System.out.println("testRuleNameOnly say hello");
    end

    创建调用代码:

       @Test
        public void testActivationGroup() {
            KieServices kss = KieServices.Factory.get();
            KieContainer kc = kss.getKieClasspathContainer();
            KieSession ks = kc.newKieSession("isGlobal");
            ks.setGlobal("count", 2019);
            int count = ks.fireAllRules();
            System.out.println("总共执行了" + count + "条规则");
            ks.dispose();
        }

    看下执行结果:

    1 globalupdate1 count:2019
    2 globalupdate1 count:10
    3 globalupdate2 count:2019
    4 2019-08-08 23:19:55 [DEBUG]org.drools...DefaultAgenda - State was FIRING_ALL_RULES is now HALTING
    5 2019-08-08 23:19:55 [DEBUG]org.drools...DefaultAgenda - State was HALTING is now INACTIVE
    6 总共执行了2条规则

    结论:当前规则体中修改的值包装类的全局变量只会影响到当前规则体。

    如果多个package使用相同标识声明的全局变量,那么他们的类型必须是相同的,并且它们所有引用都是相同的全局变量。

    创建规则:

    package rules.isGlobal;
    
    global java.lang.Boolean count;
    
    rule "global2"
        when
        then
            System.out.println("global2 count:" + count);
    end

    执行结果会报错如下:

    ule Compilation error : [Rule name='globalupdate1']
        rules/isGlobal/Rule_globalupdate1174728079.java (8:445) : Type mismatch: cannot convert from int to Boolean

    重新编写文件内容如下:

    package rules.isGlobal;
    
    //global java.lang.Boolean count;
    global java.lang.Integer count
    
    rule "global2"
        when
        then
            System.out.println("global2 count:" + count);
    end

    再次执行后,不会报错。

    global功能:

    1.全局变量定义成常量或者包装类型时,这个值对于整个规则而言是不变的。但是如果在同一段规则代码中改变了global值,那么其作用只是针对这段规则代码而言,使用的则是被修改后的global值。对其他规则代码或者元素节点中的global都不会有任何的影响。也可以这样去说,他是当前规则代码或其他元素节点中的global副本。规则内部不会影响全局的使用。

    global变量作为全局变量放在规则中,虽然说全局变量的值是不可以变化的。但是并不建议用于数据之间的共享。因为,针对不同类型全局变量中的内容也可能会发生变化。

    2.全局变量定义为集合类或者JavaBean时,在规则体RHS部分中进行修改,则规则库或Java代码中的值都是会发生变化的。这说明了全局变量并非不可变的值。如果在多个地方使用并修改了全局变量,可能就会导致结果非常奇怪了。

    query查询

    以query开头,以end结束。其中包含query name,查询参数是可以选择的,多个参数以逗号为分隔符。需要注意的是查询是一种条件匹配的方式,所以它只包含LHS部分。所以不需要when 或者then。如何判断条件是否正确,可以通过Java代码进行获取。查询中的name在当前规则库的逻辑路径下是唯一的,和规则名称的约束是一样的。

    创建规则示例:

    package rules.isQuery;
    import com.entity.Person;
    
    query "person age is 30"
        person:Person(age == 30);
    end 

    添加配置文件:

        <kbase name="isQuery" packages="rules.isQuery">
            <ksession name="isQuery"/>
        </kbase>

    创建测试调用的代码:

        @Test
        public void testQuery() {
            KieServices kss = KieServices.Factory.get();
            KieContainer kc = kss.getKieClasspathContainer();
            KieSession ks = kc.newKieSession("isQuery");
            Person person1 = new Person("张三", "35");
            Person person2 = new Person("李四", "30");
            Person person3 = new Person("王五", "50");
            ks.insert(person1);
            ks.insert(person2);
            ks.insert(person3);
            QueryResults queryResults = ks.getQueryResults("person age is 30");
            for (QueryResultsRow q : queryResults) {
                Person person = (Person) q.get("person");
                System.out.println("输出符合查询条件的对象的name是:" + person.getName());
            }
            ks.dispose();
        }

    看一下输出的结果:

    2019-08-09 22:27:08 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now EXECUTING_TASK
    2019-08-09 22:27:08 [DEBUG]org.drools...DefaultAgenda - State was EXECUTING_TASK is now INACTIVE
    2019-08-09 22:27:08 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now EXECUTING_TASK
    2019-08-09 22:27:08 [DEBUG]org.drools...DefaultAgenda - State was EXECUTING_TASK is now INACTIVE
    2019-08-09 22:27:08 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now EXECUTING_TASK
    2019-08-09 22:27:08 [DEBUG]org.drools...DefaultAgenda - State was EXECUTING_TASK is now INACTIVE
    输出符合查询条件的对象的name是:李四
    2019-08-09 22:27:08 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now DISPOSED

    是符合预期的。规则文件中没有使用任何的规则体,query的目的只是为了判断insert到规则中的Fact对象是否满足条件。query非常简单,判断Person属性是否满足age==30,如果满足,就返回一个集合。

    另外,query是可以添加参数的。

    创建规则内容如下:

    package rules.isQuery;
    import com.entity.Person;
    
    query "person age is 30 and name is 张小三" (String $name)
        person:Person(name == $name, age == 30);
    end

    创建调用端的测试代码示例:

    @Test
        public void testQuery2() {
            KieServices kss = KieServices.Factory.get();
            KieContainer kc = kss.getKieClasspathContainer();
            KieSession ks = kc.newKieSession("isQuery");
            Person person1 = new Person("张三", "35");
            Person person2 = new Person("李四", "30");
            Person person3 = new Person("王五", "50");
            Person person4 = new Person("张小三", "30");
            ks.insert(person1);
            ks.insert(person2);
            ks.insert(person3);
            ks.insert(person4);
            Object[] objects = new Object[]{"张小三"};
            QueryResults queryResults = ks.getQueryResults("person age is 30 and name is 张小三", objects);
            for (QueryResultsRow q : queryResults) {
                Person person = (Person) q.get("person");
                System.out.println("输出符合查询条件的对象的name是:" + person.getName());
            }
            ks.dispose();
        }

    看下运行的结果:

    2019-08-09 22:38:00 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now EXECUTING_TASK
    2019-08-09 22:38:00 [DEBUG]org.drools...DefaultAgenda - State was EXECUTING_TASK is now INACTIVE
    2019-08-09 22:38:00 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now EXECUTING_TASK
    2019-08-09 22:38:00 [DEBUG]org.drools...DefaultAgenda - State was EXECUTING_TASK is now INACTIVE
    2019-08-09 22:38:00 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now EXECUTING_TASK
    2019-08-09 22:38:00 [DEBUG]org.drools...DefaultAgenda - State was EXECUTING_TASK is now INACTIVE
    输出符合查询条件的对象的name是:张小三
    2019-08-09 22:38:00 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now DISPOSED

    符合预期。

    function

    function函数的写法是和JavaScript中的函数类似的,规则函数是Java类方法的一种变形,它的参数是非必填的信息。返回值也是非必填的。一个规则使用函数的好处是可以在同一个地方保持所有的逻辑,同一个逻辑路径下的函数是一个全局的函数,如果规则函数发生变化,就意味着所有调用该函数的规则体都发生了变化。

    规则中的函数有两种形式,一种是import,可以去引用Java中的静态方法,另一种需要在规则中添加关键字function.

    创建规则体内容:

    package rules.isFunction;
    
    rule "function"
        when
        then
            function01();
            System.out.println("函数function02()的返回值" + function02());
            function03("张小三");
            System.out.println("函数function04()的返回值" + function04("李小四"));
        end
    
    function void function01() {
        System.out.println("一个无参无返回值的函数");
    }
    
    function String function02() {
        System.out.println("一个无参有返回值的函数");
        return "Hello";
    }
    
    function void function03(String name) {
        System.out.println("一个有参无返回值的函数,输出入参是:" + name);
    }
    
    function String function04(String name) {
        System.out.println("一个有参没有返回值的函数,输出入参是" + name);
        return name;
    }

    在kmodule.xml文件中继续添加节点:

        <kbase name="isFunction" packages="rules.isFunction">
            <ksession name="isFunction"/>
        </kbase>

    创建调用规则的Java客户端代码:

        @Test
        public void testFunction() {
            KieServices kss = KieServices.Factory.get();
            KieContainer kc = kss.getKieClasspathContainer();
            KieSession ks = kc.newKieSession("isFunction");
            int count = ks.fireAllRules();
            System.out.println("总共执行了" + count + "条规则");
            ks.dispose();
        }

    运行结果如下:

    2019-08-10 20:49:20 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now FIRING_ALL_RULES
    一个无参无返回值的函数
    一个无参有返回值的函数
    函数function02()的返回值Hello
    一个有参无返回值的函数,输出入参是:张小三
    一个有参没有返回值的函数,输出入参是李小四
    函数function04()的返回值李小四
    2019-08-10 20:49:20 [DEBUG]org.drools...DefaultAgenda - State was FIRING_ALL_RULES is now HALTING
    2019-08-10 20:49:20 [DEBUG]org.drools...DefaultAgenda - State was HALTING is now INACTIVE
    总共执行了1条规则
    2019-08-10 20:49:20 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now DISPOSED

    function函数和一个Java方法并没有什么区别。

    最后来验证下同一个逻辑路径下或者不同路径下函数的访问范围。

    1.同一个逻辑路径下

    创建规则文件:

    package rules.isFunction;
    
    rule "function2"
    when
    then
        function01();
        System.out.println("函数function02()的返回值" + function02());
        function03("张小小");
        System.out.println("函数function04()的返回值" + function04("李小小"));
    end

    看下调用的结果:

    一个无参无返回值的函数
    一个无参有返回值的函数
    函数function02()的返回值Hello
    一个有参无返回值的函数,输出入参是:张小小
    一个有参没有返回值的函数,输出入参是李小小
    函数function04()的返回值李小小
    一个无参无返回值的函数
    一个无参有返回值的函数
    函数function02()的返回值Hello
    一个有参无返回值的函数,输出入参是:张小三
    一个有参没有返回值的函数,输出入参是李小四
    函数function04()的返回值李小四

    证明了function函数在同逻辑路径下是全局性的。

    相反,如果不在同一逻辑路径下,是不可用的。

    function函数的第一种形式,是通过Java静态方法的方式。

    创建FunctionStatic.java文件

    
    
    package com.rules.isFunction;

    public class FunctionStatic {

    public static void testStatic1() {
    System.out.println("一个无参无返回值的Java静态方法");
    }

    public static String testStatic2() {
    System.out.println("一个无参有返回值的Java静态方法");
    return "Hello";
    }

    public static void testStatic3(String name) {
    System.out.println("一个有参有返回值的Java静态方法,参数是:" + name);
    }

    public static String testStatic4(String name) {
    System.out.println("一个有参有返回值的Java静态方法, 参数是" + name);
    return name;
    }
    }

    调用代码:

    package rules.isFunction;
    import function com.rules.isFunction.FunctionStatic.testStatic1;
    import function com.rules.isFunction.FunctionStatic.testStatic2;
    import function com.rules.isFunction.FunctionStatic.testStatic3;
    import function com.rules.isFunction.FunctionStatic.testStatic4;
    
    rule "function3"
        when
        then
            testStatic1();
            System.out.println("testStatic2()的返回值" + testStatic2());
            testStatic3("张小三");
            System.out.println("testStatic4()的返回值" + testStatic4("李小四"));
        end

    结果如下:

    2019-08-10 21:11:00 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now FIRING_ALL_RULES
    一个无参无返回值的Java静态方法
    一个无参有返回值的Java静态方法
    testStatic2()的返回值Hello
    一个有参有返回值的Java静态方法,参数是:张小三
    一个有参有返回值的Java静态方法, 参数是李小四

     declare声明

    declare在规则引擎中的功能主要有两个:一个是声明新类型,二是声明元数据类型。

    1.声明新类型 和JavaBean功能一样,但是方式比JavaBean简单。在之前的例子里面,在规则中操作Fact对象都是通过Java代码insert到规则中进行处理。但是有时候,我们不希望去编写JavaBean。在这个时候,使用declare再好不过。

    2.声明元数据类型,fact对象中包含了一些特性,这些特性称之为类元信息。如果需要当前的属性长度是固定的,那么就可以在属性声明前添加元数据。一般元数据用于在查询中,复杂的事件处理和属性字段的约束最多。

    创建规则内容:

    package rules.isDeclare;
    
    declare Person
        name:String
        age:int
    end
    
    rule "declareInsert"
    when
    then
        insert(new Person("张三", 20));
    end
    
    rule "declareTest"
    when
        $p:Person(name=="张三")
    then
        System.out.println("使用declare测试insert后进行操作");
    end

    在kmodule.xml中添加节点:

        <kbase name="isDeclare" packages="rules.isDeclare">
            <ksession name="isDeclare"/>
        </kbase>

    创建测试代码:

       @Test
        public void testDeclare() {
            KieServices kieServices = KieServices.Factory.get();
            KieContainer kieClasspathContainer = kieServices.getKieClasspathContainer();
            KieSession session = kieClasspathContainer.newKieSession("isDeclare");
            int count = session.fireAllRules();
            System.out.println("总共执行了" + count + "条规则");
            session.dispose();
        }

    运行结果:

    2019-08-11 17:39:37 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now FIRING_ALL_RULES
    使用declare测试insert后进行操作
    2019-08-11 17:39:37 [DEBUG]org.drools...DefaultAgenda - State was FIRING_ALL_RULES is now HALTING
    2019-08-11 17:39:37 [DEBUG]org.drools...DefaultAgenda - State was HALTING is now INACTIVE
    总共执行了2条规则
    2019-08-11 17:39:37 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now DISPOSED

    例子中声明了一个名称是Person的新的Fact类型。定义声明属性类型可以是任意的Java有效类型,并且包括自定义创建的任何其他类,甚至可以是当前规则中已有的声明类型。

    在声明一个新的事实类型时,Drools会在编译时生成实现表示事实类型的一个Java类的字节码。生成的Java类,将是一个一对一JavaBean类型定义的映射。

    因为生成的类是一个简单的Java类,相当于在当前规则中import一个对象,所以在同一个逻辑路径下的规则体中都是可以使用的。和全局变量,函数查询的共享范围都是一致的。

    如果在规则文件中声明的类型和import引用的类名相同时,系统会报错。

    创建规则内容:

    package rules.isDeclare;
    import com.entity.Person;
    
    declare Person
        name:String
        age:int
    end

    运行测试代码结果:

    New declaration of com.entity.Person does not include field className
    New declaration of com.entity.Person redeclared field age : 
    existing : java.lang.String vs declared : int
    New declaration of com.entity.Person can't declare a different set of fields 
    existing : [age, className, name]
    declared : [age, name]
    diff : [--className]
    Rule Compilation error : [Rule name='declareInsert']
        rules/isDeclare/Rule_declareInsert725960459.java (7:390) : The constructor Person(String, int) is undefined
    
    
    
    java.lang.RuntimeException: Error while creating KieBase[Message [id=1, kieBase=isDeclare, level=ERROR, path=D:JavaDevworkspaceDroolsProjectBaseProject	argetclasses
    ules.isDeclaredeclare.drl, line=4, column=0
       text=New declaration of com.entity.Person does not include field className], Message [id=2, kieBase=isDeclare, level=ERROR, path=D:JavaDevworkspaceDroolsProjectBaseProject	argetclasses
    ules.isDeclaredeclare.drl, line=4, column=0
       text=New declaration of com.entity.Person redeclared field age : 
    existing : java.lang.String vs declared : int], Message [id=3, kieBase=isDeclare, level=ERROR, path=D:JavaDevworkspaceDroolsProjectBaseProject	argetclasses
    ules.isDeclaredeclare.drl, line=4, column=0
       text=New declaration of com.entity.Person can't declare a different set of fields 
    existing : [age, className, name]
    declared : [age, name]
    diff : [--className]], Message [id=4, kieBase=isDeclare, level=ERROR, path=D:JavaDevworkspaceDroolsProjectBaseProject	argetclasses
    ules.isDeclaredeclare.drl, line=9, column=0
       text=Rule Compilation error The constructor Person(String, int) is undefined]]
    
        at org.drools.compiler.kie.builder.impl.KieContainerImpl.getKieBase(KieContainerImpl.java:363)
        at org.drools.compiler.kie.builder.impl.KieContainerImpl.newKieSession(KieContainerImpl.java:519)
        at org.drools.compiler.kie.builder.impl.KieContainerImpl.newKieSession(KieContainerImpl.java:487)
        at com.com.rulesDeclare.RulesDeclare.testDeclare(RulesDeclare.java:14)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
        at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
        at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
        at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
        at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

    将声明类型中的属性删除,再次执行,就不会报错。原因是规则文件编译冲突,规则并不知道自己到底需要用哪一种引用类型,所以只能是系统报错。

    声明类型中还有一个和Java继承相似得功能。也是通过关键字extends。

    创建规则内容:

    package rules.isDeclare
    
    declare PersonEx extends com.entity.Person
        type : String
    end
    
    rule "declareInsertExt"
    when 
    then 
        PersonEx p = new PersonEx();
        p.setType("1");
        p.setAge("20");
        p.setName("张三");
        insert(p);
    end
    
    rule "declareTestExtends"
    when 
        $p:PersonEx(name=="张三")
    then 
        System.out.println("hello" + $p.getName());
    end

    看下运行的结果:

    2019-08-11 18:05:17 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now FIRING_ALL_RULES
    使用declare测试insert后进行操作
    hello张三
    2019-08-11 18:05:17 [DEBUG]org.drools...DefaultAgenda - State was FIRING_ALL_RULES is now HALTING
    2019-08-11 18:05:17 [DEBUG]org.drools...DefaultAgenda - State was HALTING is now INACTIVE
    总共执行了4条规则
    2019-08-11 18:05:17 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now DISPOSED

    规则when

    规则文件中处理业务的核心在于规则体的灵活使用,简称规则,它的书写规范,和Java语言是相似的。LHS部分是when与then之间的语法。规则属性判断过程,只有在规则LHS中匹配结果是true时,才认为规则成立,才会跳转到RHS部分。如果说LHS部分是空,就表示这个规则永远都是true。当工作空间中Fact对象发生变化时,这个规则呢可能会再次被激活,我们可以使用之前学习过的no-loop属性得到解决。

    pattern匹配模式中,pattern表示一种约束条件。看一下它的组织结构:

    patternBinding:patternType ( constraints )

    匹配模式由零个或者多个约束组成,并且有一个可以选择的模式绑定,在最简单的格式中,没有内部的约束条件,通过一个给定类型的事实就可以进行模式匹配了。要注意下,不必是一些事实对象的实际类,模式可以引用子类,接口,函数等。

    引用匹配的对象,可以为一个模式绑定变量,例如:$c,这个前缀符号$其实不是必须的,但是在复杂的规则中非常有用,可以有助于去区别变量和字段。例如:$p:Person(age==30);

    模式中的括号内部是所有匹配的地方,约束可以是一个字段,或者是一个约束组,也可以是一个其内部的计算。约束可以使用, &&  || 符号分割。

    和Java中是一样的,比较运算符是有优先级的。进行与或非等运算时要注意短路机制。

    对象属性有3种类型的限制,单值限制,复合值限制和多限制。单值限制就是上面所说个那种样子,复合限制类似于数据库中查询语句中的in和not in。

    1.复合值限制in not in

    创建规则内容:

     1 package rules.isIn
     2 import com.entity.Person;
     3 import com.entity.School;
     4 
     5 rule "inTest"
     6 when
     7     School($cn:className)
     8     Person(className in (5, 6, $cn))
     9 then
    10     System.out.println("in test");
    11 end
    12 
    13 rule "notinTest"
    14 when
    15     School($cn:className)
    16     Person(className not in (5, 6, $cn))
    17 then
    18     System.out.println("not in test");
    19 end

    修改配置文件,继续添加节点:

        <kbase name="isIn" packages="rules.isIn">
            <ksession name="isIn"/>
        </kbase>

    创建测试调用代码:

     1 @Test
     2     public void testIn() {
     3 
     4         KieServices kss = KieServices.Factory.get();
     5         KieContainer kc = kss.getKieClasspathContainer();
     6         KieSession ks = kc.newKieSession("isIn");
     7 
     8         Person person = new Person();
     9         person.setClassName("3");
    10         ks.insert(person);
    11         School school = new School();
    12         school.setClassName("3");
    13         ks.insert(school);
    14         Person person2 = new Person();
    15         person2.setClassName("4");
    16         ks.insert(person2);
    17         int count = ks.fireAllRules();
    18         System.out.println("总共执行了" + count + "条规则");
    19         ks.dispose();
    20 
    21 
    22     }

    最后看下运行的效果:

    1 2019-08-12 23:32:14 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now FIRING_ALL_RULES
    2 in test
    3 not in test
    4 2019-08-12 23:32:14 [DEBUG]org.drools...DefaultAgenda - State was FIRING_ALL_RULES is now HALTING
    5 2019-08-12 23:32:14 [DEBUG]org.drools...DefaultAgenda - State was HALTING is now INACTIVE
    6 总共执行了2条规则
    7 2019-08-12 23:32:14 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now DISPOSED

    2.条件元素eval

    格式:eval(expression)

    条件元素eval是在最开始的示例中就列举过的。它可以代表任何语义的代码。并且返回一个boolean类型,也可以绑定在规则LHS中的变量,函数或者直接写常量进行比较。但是在实际编码的过程中,尽量少用eval作为比较符,因为会导致引擎的性能问题。

    3.条件元素not

    格式:not(conditionalElement)

    条件元素not是判断在工作内存中是否还存在某一个值,当not ec成立时就表示当前工作内存中不存在ec,可以认为是一定没有这个值。

    创建规则体内容:

    package rules.isNot
    import com.entity.Person;
    
    rule "testNot"
       when
           not Person();
       then
           System.out.println("测试Person一定不再工作内存中");
    end
    
    rule "testNotx2"
       when
           not(not Person());
       then
           System.out.println("测试Person一定在工作内存中");
    end

    在配置文件中节点中添加:

        <kbase name="isNot" packages="rules.isNot">
            <ksession name="isNot"/>
        </kbase>

    测试代码:

        @Test
        public void testIn() {
    
            KieServices kss = KieServices.Factory.get();
            KieContainer kc = kss.getKieClasspathContainer();
            KieSession ks = kc.newKieSession("isIn");
    
            Person person = new Person();
            person.setClassName("3");
            ks.insert(person);
            School school = new School();
            school.setClassName("3");
            ks.insert(school);
            Person person2 = new Person();
            person2.setClassName("4");
            ks.insert(person2);
            int count = ks.fireAllRules();
            System.out.println("总共执行了" + count + "条规则");
            ks.dispose();
    
    
        }

    看下运行结果:

    2019-08-13 22:31:02 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now FIRING_ALL_RULES
    测试Person一定在工作内存中
    2019-08-13 22:31:02 [DEBUG]org.drools...DefaultAgenda - State was FIRING_ALL_RULES is now HALTING
    2019-08-13 22:31:02 [DEBUG]org.drools...DefaultAgenda - State was HALTING is now INACTIVE
    总共执行了1条规则
    2019-08-13 22:31:02 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now DISPOSED

    符合预期。

    4.条件元素 exists 

    格式:exists(conditionalElement)

    条件元素exists的功能是和not相反的,指的是工作内存中是否存在某一个东西,可以认为是至少有一个。

    创建规则内容:

    package rules.isExists
    import com.entity.Person;
    
    rule "testExists"
       when
           exists Person();
       then
           System.out.println("测试Person一定在工作内存中");
    end
    
    rule "testExistsx2"
       when
           not (exists Person());
       then
           System.out.println("测试Person一定不在工作内存中");
    end

    创建客户端调用代码:

       @Test
        public void testExists() {
    
            KieServices kss = KieServices.Factory.get();
            KieContainer kc = kss.getKieClasspathContainer();
            KieSession ks = kc.newKieSession("isNot");
    
            Person person = new Person();
            person.setClassName("1");
            person.setAge("35");
            ks.insert(person);
    
            int count = ks.fireAllRules();
            System.out.println("总共执行了" + count + "条规则");
            ks.dispose();
    
    
        }

    看下运行结果:

    2019-08-13 22:39:43 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now FIRING_ALL_RULES
    测试Person一定在工作内存中
    2019-08-13 22:39:43 [DEBUG]org.drools...DefaultAgenda - State was FIRING_ALL_RULES is now HALTING
    2019-08-13 22:39:43 [DEBUG]org.drools...DefaultAgenda - State was HALTING is now INACTIVE
    总共执行了1条规则
    2019-08-13 22:39:43 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now DISPOSED

    符合预期。

    条件元素from

    结构:pattern from expression

    条件元素from很有意思,可以指定任意的资源,用于LHS部分的数据匹配,也可以用来对集合进行遍历。还可以用来对Java服务进行访问并且对结果进行遍历。还有global全局变量也可以提供Java服务。

    创建规则内容:

    package rules.isFrom
    import com.entity.Person
    import com.entity.School
    
    rule "testFrom"
    when
        $p:Person($ps:school)
        $s:School(className=="1") from $ps
    then
        System.out.println("test from");
    end

    修改配置文件:

    <kbase name="isFrom" packages="rules.isFrom">
            <ksession name="isFrom"/>
        </kbase>

    测试代码:

    @Test
        public void testFrom() {
            KieServices kss = KieServices.Factory.get();
            KieContainer kc = kss.getKieClasspathContainer();
            KieSession ks = kc.newKieSession("isFrom");
            Person person = new Person();
            person.setAge("30");
            person.setName("张三");
            person.setSchool(new School("1"));
            ks.insert(person);
            ks.insert(new School("2"));
            int count = ks.fireAllRules();
            System.out.println("总共执行了" + count + "条规则");
            ks.dispose();
        }

    运行结果:

    2019-08-14 22:37:36 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now FIRING_ALL_RULES
    test from
    2019-08-14 22:37:36 [DEBUG]org.drools...DefaultAgenda - State was FIRING_ALL_RULES is now HALTING
    2019-08-14 22:37:36 [DEBUG]org.drools...DefaultAgenda - State was HALTING is now INACTIVE
    总共执行了1条规则
    2019-08-14 22:37:36 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now DISPOSED

    上面的规则内容其实可以用下面的这种写法来替代:

    rule "testFrom2"
    when
        $p:Person()
        $s:School(className=="1") from $p.school
    then
        System.out.println("test from2");
    end

    条件元素from支持对象源,会返回一个对象集合,在这种情况下,from将会遍历集合中所有的对象,并分别匹配它们中每一个对象值。

    创建规则内容:

    rule "testFrom3"
    when
        $s:School()
        $p:Person(className=="1") from $s.classNameList
    then 
        System.out.println("testFrom3" + $p.getName());
    end

    创建调用端:

    @Test
        public void testFromList() {
            KieServices kss = KieServices.Factory.get();
            KieContainer kc = kss.getKieClasspathContainer();
            KieSession ks = kc.newKieSession("isFrom");
            Person person = new Person();
            person.setName("张三");
            person.setClassName("1");
            Person person2 = new Person();
            person2.setName("李四");
            person2.setClassName("1");
            Person person3 = new Person();
            person3.setName("王五");
            person3.setClassName("2");
            Person person4 = new Person();
            person4.setName("赵六");
            person4.setClassName("1");
            School school = new School();
            List<Person> classNameList = new ArrayList();
            classNameList.add(person);
            classNameList.add(person2);
            classNameList.add(person3);
            classNameList.add(person4);
            school.setClassNameList(classNameList);
            ks.insert(school);
            int count = ks.fireAllRules();
            System.out.println("总共执行了" + count + "条规则");
            ks.dispose();
        }

    运行后结果:

    2019-08-14 22:56:37 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now FIRING_ALL_RULES
    testFrom3赵六
    testFrom3李四
    testFrom3张三
    2019-08-14 22:56:37 [DEBUG]org.drools...DefaultAgenda - State was FIRING_ALL_RULES is now HALTING
    2019-08-14 22:56:37 [DEBUG]org.drools...DefaultAgenda - State was HALTING is now INACTIVE
    总共执行了3条规则
    2019-08-14 22:56:37 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now DISPOSED

    此外,要注意在使用属性时,特别是与lock-on-active规则属性联合使用时,因为这个属性可以产生不一样的效果。

    最后,from不仅可以在对象,集合中应用,还可以在函数中应用。

    条件元素collect

    pattern 'from' 'collect' (pattern from collect accumulate)

    条件元素collect需要结合from元素来使用。from是用来遍历的,而 from collect是用来汇总的。collect后的参数中还可以匹配 遍历 收集 统计的功能。

    创建规则体内容:

    package rules.isCollect
    import com.entity.Person
    import com.entity.School
    import java.util.ArrayList
    
    rule "test from collect"
    when
        $al: ArrayList() from collect($p:Person(className=="1"))
    then
        System.out.println("test from collect array list size:" + $al.size()); 
    end
    
    rule "test from collect pattern"
    when
        $al: ArrayList(size>=3) from collect($p:Person(className=="1"))
    then
        System.out.println("test from collect array list size:" + $al.size()); 
    end

    修改kmodule.xml配置文件:

    <kbase name="isCollect" packages="rules.isCollect">
            <ksession name="isCollect"/>
        </kbase>

    创建测试代码:

    @Test
        public void testFromCollect() {
            KieServices kss = KieServices.Factory.get();
            KieContainer kc = kss.getKieClasspathContainer();
            KieSession ks = kc.newKieSession("isCollect");
            Person person = new Person();
            person.setName("张三");
            person.setClassName("1");
            ks.insert(person);
            Person person2 = new Person();
            person2.setName("李四");
            person2.setClassName("1");
            ks.insert(person2);
            Person person3 = new Person();
            person3.setName("王五");
            person3.setClassName("2");
            ks.insert(person3);
            Person person4 = new Person();
            person4.setName("赵流");
            person4.setClassName("1");
            ks.insert(person4);
            int count = ks.fireAllRules();
            System.out.println("总共执行了" + count + "条规则");
            ks.dispose();
        }

    结果:

    2019-08-15 23:38:12 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now FIRING_ALL_RULES
    test from collect array list size:3
    test from collect array list size:3
    2019-08-15 23:38:12 [DEBUG]org.drools...DefaultAgenda - State was FIRING_ALL_RULES is now HALTING
    2019-08-15 23:38:12 [DEBUG]org.drools...DefaultAgenda - State was HALTING is now INACTIVE
    总共执行了2条规则
    2019-08-15 23:38:12 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now DISPOSED

    collect参数中使用from。添加规则体:

    rule "test from collect from"
    when
        $s:School()
        
        $al: ArrayList(size>=3) from collect($p:Person(className=="1") from $s.classNameList)
    then
        System.out.println("test from collect array list size:" + $al.size());
    end

    创建测试端调用代码:

    @Test
        public void testFromCollectFrom() {
            KieServices kss = KieServices.Factory.get();
            KieContainer kc = kss.getKieClasspathContainer();
            KieSession ks = kc.newKieSession("isCollect");
            Person person = new Person();
            person.setName("张三");
            person.setClassName("1");
    
            Person person2 = new Person();
            person2.setName("李四");
            person2.setClassName("1");
    
            Person person3 = new Person();
            person3.setName("王五");
            person3.setClassName("2");
    
            Person person4 = new Person();
            person4.setName("赵流");
            person4.setClassName("1");
    
            School school = new School();
            List classNameList= new ArrayList();
            classNameList.add(person);
            classNameList.add(person2);
            classNameList.add(person3);
            classNameList.add(person4);
            school.setClassNameList(classNameList);
            ks.insert(school);
    
            int count = ks.fireAllRules();
            System.out.println("总共执行了" + count + "条规则");
            ks.dispose();
        }

    运行结果:

    2019-08-15 23:43:16 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now FIRING_ALL_RULES
    test from collect array list size:0
    test from collect array list size:3
    2019-08-15 23:43:16 [DEBUG]org.drools...DefaultAgenda - State was FIRING_ALL_RULES is now HALTING
    2019-08-15 23:43:16 [DEBUG]org.drools...DefaultAgenda - State was HALTING is now INACTIVE
    总共执行了2条规则
    2019-08-15 23:43:16 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now DISPOSED

    符合预期。

    ◆ 条件元素规则的继承

    条件元素规则继承与java相似。因为Drools是以规则引擎是基于java开发的开源技术。在编写规则时,大部分的操作都离不开使用Java脚本对一类fact对象进行操作。同时Drools中语法也存在继承的逻辑关系,其目的是为了减少相同代码的出现,从而方便代码的优化和管理。

    创建规则内容:

    package rules.isExtends
    import com.entity.Person
    import com.entity.School
    
    rule "test extends No1"
    when
        $p:Person(name == "张小三")
    then
        System.out.println("输出张小三");
    end
    
    rule "test extends No2" extends "test extends No1"
    when
        $s:School(className == "1")
    then
        System.out.println("输出张三和1");
    end

    修改配置文件:

    <kbase name="isExtends" packages="rules.isExtends">
            <ksession name="isExtends"/>
        </kbase>

    创建测试代码:

       @Test
        public void testExtends() {
            KieServices kss = KieServices.Factory.get();
            KieContainer kc = kss.getKieClasspathContainer();
            KieSession ks = kc.newKieSession("isExtends");
            Person person = new Person();
            person.setName("张小三");
            School school = new School();
            school.setClassName("1");
            ks.insert(person);
            ks.insert(school);
            int count = ks.fireAllRules();
            System.out.println("总共执行了" + count + "条规则");
            ks.dispose();
        }

    运行结果:符合预期

    2019-08-16 08:45:11 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now FIRING_ALL_RULES
    输出张小三
    输出张三和1
    2019-08-16 08:45:11 [DEBUG]org.drools...DefaultAgenda - State was FIRING_ALL_RULES is now HALTING
    2019-08-16 08:45:11 [DEBUG]org.drools...DefaultAgenda - State was HALTING is now INACTIVE
    总共执行了2条规则
    2019-08-16 08:45:11 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now DISPOSED

     kmodule配置说明

    kmodule是非常重要的配置文件。它关系到规则库是否可以成功的创建以及KieSession的正确使用。将kmodule.xml文件放到src/main/resources/META-INF/文件夹下,内容如下:

        <kbase name="rule" packages="rules.rulesHello">
            <ksession name="testHelloWorld"/>
        </kbase>

    name: 

    必填,值类型String

    用于从KieContainer检索这个KieBase的名称。是规则库的名称,又是唯一的强制属性。最好规范命名,见名知意。

    packages:

    非必填,值类型 String

    默认的情况下,加载资源文件夹中所有Drools相关文件,这个属性目的是将当前路径下的规则文件在KieBase中编译。仅仅限于指定的软件包路径下的所有文件。这个值是可以多个的。中间用逗号分隔即可。如果路径是子文件,就必须用小数点进行区别,类似Java包。

    includes:

    非必填,值类型

    指一个KieBase被另一个KieBase2的配置中设置了includes='KieBase1',那么KieBase2就有了KieBase1所有资源了,当然这个值也可以是多个,中间任然使用逗号分隔开,有点类似继承的意思。

    default:

    非必填,值类型 true/false

    用来表示当前KieBase是否是次模块的默认值,因此可以从KieContainer中创建,而不会传递任何名称。每个模块中最多只能有一个默认的KieBase,默认值是false.

    equalsBehavior

    非必填 值类型 Indentity/equality 

    将新Fact事实对象插入到工作内存中时,定义了Drools的操作,使用了身份属性,那么它会创建一个新的FactHandle,除非相同的对象不存在与工作内存中,而只有新插入的对象不存在与工作内从中,而只有新插入的对象与已存在的事实对象不相等时才会相同。

    eventProcessingMode

    非必填 值类型 Cloud/stream

    当以云模式编译时,KieBase将事实视为正常事实,而在流模式下可以对其进行实践推理。

    declarativeAgenda

    菲必填 值类型Disabled enabled

    定义声明议程是否启用。

    KieSession属性声明

    name 

    必填 值类型 string

    KieSession的名称。用于从KieContainer中获取KieSession。唯一一个强制必填的属性。用于指定操作规则的会话。

    type

    非必填 值类型 stateful/stateless 指当前KieSession的类型是有状态还是没有状态的,默认不指定为有状态的。

    default

    非必填  值类型 true/false 

    定义这个KieSession是否是个模块的默认值,如果这个值是true,就可以从KieContainer中创建,而不会传递任何名称。在每个模块中,每个类型最多可以有一个默认的KieSession,且是有状态。

    clockType

    非必填 realtime/seudo

    定义事件时间戳是有系统时钟还是由应用程序控制的seudo时钟确定。这个时钟对于单元测试时间规则特别有用。

    beiefSystem

    非必填 simple/tms/defeasible

    定义KieSession使用的beiefSystem的类型。

    Spring整合Drools

    1.在pom.xml文件中引入相应的jar包

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>DroolsProject</artifactId>
            <groupId>com.sunlei</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>DroolsSpring</artifactId>
    
        <properties>
            <spring.version>4.2.6.RELEASE</spring.version>
        </properties>
    
        <dependencies>
    
            <dependency>
                <groupId>org.kie</groupId>
                <artifactId>kie-spring</artifactId>
                <version>7.10.0.Final</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.1.1</version>
            </dependency>
    
    
    
    
    
    
    
        </dependencies>
    
        <build>
            <resources>
                <resource>
                    <directory>
                        ${project.basedir} /src/main/resources
                    </directory>
                </resource>
            </resources>
    
        </build>
    
    
    </project>

    2.创建spring 配置文件,注意其中的节点配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:kie="http://drools.org/schema/kie-spring"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd http://drools.org/schema/kie-spring http://drools.org/schema/kie-spring.xsd">
    
        <kie:kmodule id = "kmodule">
            <kie:kbase name="kbase" packages="rules.isString">
                <kie:ksession name="ksession"/>
            </kie:kbase>
        </kie:kmodule>
    
        <bean id="kiePostProcessor"
              class="org.kie.spring.annotations.KModuleAnnotationPostProcessor"/>
    
    
    </beans>

    3.创建规则文件

    package rules.isString;
    rule "测试Spring + Drools规则"
        when
        then
            System.out.println("调用规则" + drools.getRule().getName());
    end;

    4.创建调用文件

    package com.ruleSpring;
    
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.kie.api.cdi.KSession;
    import org.kie.api.runtime.KieSession;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration({"classpath:Spring.xml"})
    public class TestSpring {
    
        @KSession("ksession")
        KieSession ksession;
    
        @Test
        public void runRules() {
            int count = ksession.fireAllRules();
            System.out.println("总共执行了" + count + "条规则");
            ksession.dispose();
        }
    
    
    
    
    }

    5.运行结果

    2019-08-22 23:11:47 [DEBUG]org.drools.....ClasspathKieProject - KieModule URL type=file url=/D:/JavaDev/workspace/DroolsProject/DroolsSpring/target/classes
    2019-08-22 23:11:47 [INFO ]org.kie..KModuleBeanFactoryPostProcessor - Adding KieModule from /D:/JavaDev/workspace/DroolsProject/DroolsSpring/target/classes to repository.
    2019-08-22 23:11:47 [INFO ]org.drools.....KieRepositoryImpl - KieModule was added: FileKieModule[releaseId=com.sunlei:DroolsSpring:1.0-SNAPSHOT,file=JavaDevworkspaceDroolsProjectDroolsSpring	argetclasses]
    2019-08-22 23:11:47 [DEBUG]org.drools.....KieRepositoryImpl - Cannot load a KieRepositoryScanner, using the DummyKieScanner
    2019-08-22 23:11:47 [ERROR]org.drools.....KieRepositoryImpl - Cannot load artifact com.sunlei:DroolsSpring:1.0-SNAPSHOT. You need kie-ci on the classpath to perform this operation
    2019-08-22 23:11:48 [WARN ]org.drools.....KieProject - No files found for KieBase kbase, searching folder JavaDevworkspaceDroolsProjectDroolsSpring	argetclasses
    2019-08-22 23:11:48 [ERROR]org.drools.....KieRepositoryImpl - Cannot load artifact com.sunlei:DroolsSpring:1.0-SNAPSHOT. You need kie-ci on the classpath to perform this operation
    2019-08-22 23:11:48 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now FIRING_ALL_RULES
    2019-08-22 23:11:48 [DEBUG]org.drools...DefaultAgenda - State was FIRING_ALL_RULES is now HALTING
    2019-08-22 23:11:48 [DEBUG]org.drools...DefaultAgenda - State was HALTING is now INACTIVE
    总共执行了0条规则
    2019-08-22 23:11:48 [DEBUG]org.drools...DefaultAgenda - State was INACTIVE is now DISPOSED

    能够成功运行,但是运行结果是错误的。暂时还不知道为什么。。。。。。

    规则then

    rule是then 与end之间的部分,是规则体中的重要组成部分之一。主要用来处理相关的业务。RHS是真正做事的部分,业务操作时,基本都是通过操作Fact事实对象,并将修改过或已经得到的结果返回Java代码,并进行处理。

    RHS部分是规则的结果或行动部分的通用名称,这个部分包含要执行操作的列表,RHS部分如果再次进行条件判断或执行其他语法显然是不好的。LHS部分提供了相关的判断。

    一般来说,RHS部分是规则体中的最小操作。只有规则体LHS部分全部满足条件时才会执行这部分。规则体的RHS部分也应保持较小,从而去提高规则的可读性和可维护性,如果发现RHS部分中需要调用其他语言或添加条件,那么就应该将这个规则分解成多个规则。RHS部分的主要目的是插入,删除,修改工作内存数据(Fact事实对象)。

    update(Fact事实对象):告诉引擎一个对象已经改变了(一个绑定在LHS部分上的引用,即$p:Person中的$p),修改成功后在工作内存中会已经发生变化。可能会导致规则再次被激活。注意只有在真正将工作内存中的值改变时,其他规则体才能正常对变化后的Fact事实对象进行判断操作。

    insert(Fact事实对象):将一个新的Fact事实对象放入到工作内存中,它不仅可以操作引用的Fact事实对象,还可以操作declare声明的Fact事实对象。

    insertLogical(new Object()):和insert是相似的,但是当没有更多的事实来支持当前触发规则的LHS部分时,这个Fact事实对象将会被自动删除。

    delete(handle):从工作内存中删除一个Fact事实对象,和update是相似的,都是通过引用LHS部分上绑定的值,

    update是去修改Fact事实对象的一种方式,Drools还提供了另外的一种方式,modify,它和update的功能是一样的。但是写法上有很大的不同。

    SpringBoot + Drools(1) 

    maven项目创建,pom.xml中文件如下:

      1 <?xml version="1.0" encoding="UTF-8"?>
      2 <project xmlns="http://maven.apache.org/POM/4.0.0"
      3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      5     <parent>
      6         <artifactId>Code</artifactId>
      7         <groupId>com.sunlei</groupId>
      8         <version>1.0-SNAPSHOT</version>
      9     </parent>
     10     <modelVersion>4.0.0</modelVersion>
     11 
     12     <artifactId>DroolsSpringBootTest</artifactId>
     13 
     14     <properties>
     15         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     16         <drools.version>7.10.0.Final</drools.version>
     17     </properties>
     18 
     19     <dependencies>
     20         <!--start drools -->
     21         <dependency>
     22             <groupId>org.drools</groupId>
     23             <artifactId>drools-core</artifactId>
     24             <version>${drools.version}</version>
     25         </dependency>
     26 
     27         <dependency>
     28             <groupId>org.drools</groupId>
     29             <artifactId>drools-compiler</artifactId>
     30             <version>${drools.version}</version>
     31         </dependency>
     32 
     33         <dependency>
     34             <groupId>org.kie</groupId>
     35             <artifactId>kie-spring</artifactId>
     36             <version>${drools.version}</version>
     37         </dependency>
     38 
     39         <dependency>
     40             <groupId>org.kie</groupId>
     41             <artifactId>kie-internal</artifactId>
     42             <version>${drools.version}</version>
     43         </dependency>
     44 
     45         <dependency>
     46             <groupId>org.drools</groupId>
     47             <artifactId>drools-templates</artifactId>
     48             <version>${drools.version}</version>
     49         </dependency>
     50         <!--end drools -->
     51 
     52         <dependency>
     53             <groupId>junit</groupId>
     54             <artifactId>junit</artifactId>
     55             <version>4.12</version>
     56         </dependency>
     57 
     58         <!--Spring boot start -->
     59         <dependency>
     60             <groupId>org.springframework.boot</groupId>
     61             <artifactId>spring-boot-starter-web</artifactId>
     62             <!-- 如果要配置log4j2, 就要先去除logging包 -->
     63             <exclusions>
     64                 <exclusion>
     65                     <groupId>org.springframework.boot</groupId>
     66                     <artifactId>spring-boot-starter-logging</artifactId>
     67                 </exclusion>
     68             </exclusions>
     69         </dependency>
     70 
     71         <dependency>
     72             <groupId>org.springframework.boot</groupId>
     73             <artifactId>spring-boot-starter-test</artifactId>
     74             <scope>test</scope>
     75         </dependency>
     76 
     77         <dependency>
     78             <groupId>org.springframework.boot</groupId>
     79             <artifactId>spring-boot-starter-data-redis</artifactId>
     80         </dependency>
     81 
     82         <dependency>
     83             <groupId>org.springframework.boot</groupId>
     84             <artifactId>spring-boot-starter-log4j2</artifactId>
     85         </dependency>
     86 
     87         <!--Spring boot end -->
     88 
     89     </dependencies>
     90 
     91     <build>
     92         <plugins>
     93             <plugin>
     94                 <groupId>org.springframework.boot</groupId>
     95                 <artifactId>spring-boot-maven-plugin</artifactId>
     96                 <configuration>
     97                     <fork>true</fork>
     98                 </configuration>
     99             </plugin>
    100         </plugins>
    101     </build>
    102 </project>

    在resources文件夹下创建规则文件:mytest.drl文件如下:

     1 package rules
     2 import com.entity.Person
     3 rule "测试SpringBootDrools"
     4 when
     5 then
     6     System.out.println("测试SpringBootDrools");
     7 end
     8 
     9 rule "测试insertPerson值"
    10 when
    11     $p:Person(name=="张三的歌")
    12 then
    13     System.out.println("测试insertPerson值");
    14 end

    创建配置文件DroolsConfiguration.java

     1 package com.config;
     2 
     3 import org.kie.api.KieBase;
     4 import org.kie.api.KieServices;
     5 import org.kie.api.builder.*;
     6 import org.kie.api.runtime.KieContainer;
     7 import org.kie.api.runtime.KieSession;
     8 import org.kie.internal.io.ResourceFactory;
     9 import org.kie.spring.KModuleBeanFactoryPostProcessor;
    10 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    11 import org.springframework.context.annotation.Bean;
    12 import org.springframework.context.annotation.Conditional;
    13 import org.springframework.context.annotation.Configuration;
    14 import org.springframework.core.io.Resource;
    15 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    16 import org.springframework.core.io.support.ResourcePatternResolver;
    17 
    18 import java.io.IOException;
    19 
    20 /**
    21  * drools config
    22  */
    23 @Configuration
    24 public class DroolsConfiguration {
    25 
    26     private static final String RULES_PATH = "rules/";
    27 
    28     private KieServices getKieServices() {
    29         return KieServices.Factory.get();
    30     }
    31 
    32     private Resource[] getRuleFiles() throws IOException {
    33         ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
    34         return resourcePatternResolver.getResources(String.format("classpath*:%s**/*.*", RULES_PATH));
    35     }
    36 
    37 
    38     @Bean
    39     @ConditionalOnMissingBean(KieFileSystem.class)
    40     public KieFileSystem kieFileSystem() throws IOException {
    41         KieFileSystem kieFileSystem = getKieServices().newKieFileSystem();
    42         for (Resource file : getRuleFiles()) {
    43             kieFileSystem.write(ResourceFactory.newClassPathResource(
    44                     RULES_PATH + file.getFilename(), "UTF-8"));
    45             return kieFileSystem;
    46         }
    47         return null;
    48     }
    49 
    50     @Bean
    51     @ConditionalOnMissingBean(KieContainer.class)
    52     public KieContainer kieContainer() throws IOException {
    53         final KieRepository kieRepository = getKieServices().getRepository();
    54         kieRepository.addKieModule(
    55                 new KieModule() {
    56                     @Override
    57                     public ReleaseId getReleaseId() {
    58                         return kieRepository.getDefaultReleaseId();
    59                     }
    60                 }
    61         );
    62 
    63         KieBuilder kieBuilder = getKieServices().newKieBuilder(kieFileSystem());
    64         kieBuilder.buildAll();
    65         return getKieServices().newKieContainer(kieRepository.getDefaultReleaseId());
    66     }
    67 
    68     @Bean
    69     @ConditionalOnMissingBean(KieBase.class)
    70     public KieBase kieBase() throws IOException {
    71         return kieContainer().getKieBase();
    72     }
    73 
    74     @Bean
    75     @ConditionalOnMissingBean(KieSession.class)
    76     public KieSession kieSession() throws IOException {
    77         return kieContainer().newKieSession();
    78     }
    79 
    80     @Bean
    81     @ConditionalOnMissingBean(KModuleBeanFactoryPostProcessor.class)
    82     public KModuleBeanFactoryPostProcessor kiePostProcessor() {
    83         return new KModuleBeanFactoryPostProcessor();
    84     }
    85 
    86 
    87 
    88 
    89 
    90 
    91 }

    创建service类:

     1 package com.service;
     2 
     3 import com.entity.Person;
     4 import org.kie.api.runtime.KieSession;
     5 import org.springframework.stereotype.Service;
     6 
     7 import javax.annotation.Resource;
     8 
     9 @Service
    10 public class TestService {
    11 
    12     @Resource
    13     private KieSession kieSession;
    14 
    15     public int testService01() {
    16         Person p = new Person();
    17         p.setName("张三的歌");
    18         kieSession.insert(p);
    19         int ruleFiredCount = kieSession.fireAllRules();
    20         return ruleFiredCount;
    21     }
    22 
    23 }

    创建Controller类:

     1 package com.controller;
     2 
     3 import com.service.TestService;
     4 import org.springframework.beans.factory.annotation.Autowired;
     5 import org.springframework.stereotype.Controller;
     6 import org.springframework.web.bind.annotation.RequestMapping;
     7 import org.springframework.web.bind.annotation.ResponseBody;
     8 
     9 @RequestMapping("/test")
    10 @Controller
    11 public class TestController {
    12 
    13     @Autowired
    14     private TestService testService;
    15 
    16     @ResponseBody
    17     @RequestMapping("/test001")
    18     public void test() {
    19         int count = testService.testService01();
    20         System.out.println("执行规则总数:" + count);
    21     }
    22 
    23 }

    创建启动类:

     1 package com;
     2 
     3 import org.slf4j.Logger;
     4 import org.slf4j.LoggerFactory;
     5 import org.springframework.boot.SpringApplication;
     6 import org.springframework.boot.autoconfigure.SpringBootApplication;
     7 
     8 @SpringBootApplication
     9 public class Application {
    10 
    11     protected static Logger logger = LoggerFactory.getLogger(Application.class);
    12 
    13     public static void main(String[] args) {
    14         SpringApplication.run(Application.class, args);
    15         logger.info("SpringBoot Start Success");
    16     }
    17 
    18 }

    启动项目,运行结果:

    测试SpringBootDrools
    测试insertPerson值
    执行规则总数:2

    SpringBoot + Drools(2) 

    创建maven项目,pom.xml引入依赖

      1 <?xml version="1.0" encoding="UTF-8"?>
      2 <project xmlns="http://maven.apache.org/POM/4.0.0"
      3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      5     <parent>
      6         <artifactId>Code</artifactId>
      7         <groupId>com.sunlei</groupId>
      8         <version>1.0-SNAPSHOT</version>
      9     </parent>
     10     <modelVersion>4.0.0</modelVersion>
     11 
     12     <artifactId>DroolsSpringBootTest2</artifactId>
     13 
     14     <properties>
     15         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     16         <drools.version>7.10.0.Final</drools.version>
     17         <log4j2.version>2.5</log4j2.version>
     18     </properties>
     19 
     20     <dependencies>
     21         <!--start drools -->
     22         <dependency>
     23             <groupId>org.drools</groupId>
     24             <artifactId>drools-core</artifactId>
     25             <version>${drools.version}</version>
     26         </dependency>
     27 
     28         <dependency>
     29             <groupId>org.drools</groupId>
     30             <artifactId>drools-compiler</artifactId>
     31             <version>${drools.version}</version>
     32         </dependency>
     33 
     34         <dependency>
     35             <groupId>org.kie</groupId>
     36             <artifactId>kie-spring</artifactId>
     37             <version>${drools.version}</version>
     38         </dependency>
     39 
     40         <dependency>
     41             <groupId>org.kie</groupId>
     42             <artifactId>kie-internal</artifactId>
     43             <version>${drools.version}</version>
     44         </dependency>
     45 
     46         <dependency>
     47             <groupId>org.drools</groupId>
     48             <artifactId>drools-templates</artifactId>
     49             <version>${drools.version}</version>
     50         </dependency>
     51         <!--end drools -->
     52 
     53         <!--Spring boot start -->
     54         <dependency>
     55             <groupId>org.springframework.boot</groupId>
     56             <artifactId>spring-boot-starter-web</artifactId>
     57             <exclusions>
     58                 <exclusion>
     59                     <groupId>org.springframework.boot</groupId>
     60                     <artifactId>spring-boot-starter-logging</artifactId>
     61                 </exclusion>
     62             </exclusions>
     63         </dependency>
     64 
     65         <dependency>
     66             <groupId>org.springframework.boot</groupId>
     67             <artifactId>spring-boot-starter-test</artifactId>
     68             <scope>test</scope>
     69         </dependency>
     70 
     71         <dependency>
     72             <groupId>org.springframework.boot</groupId>
     73             <artifactId>spring-boot-starter-data-redis</artifactId>
     74         </dependency>
     75 
     76         <!-- mysql -->
     77         <dependency>
     78             <groupId>mysql</groupId>
     79             <artifactId>mysql-connector-java</artifactId>
     80             <version>5.1.20</version>
     81         </dependency>
     82         <!-- mysql -->
     83 
     84         <!-- mybatis -->
     85         <dependency>
     86             <groupId>org.mybatis.spring.boot</groupId>
     87             <artifactId>mybatis-spring-boot-starter</artifactId>
     88             <version>1.1.1</version>
     89         </dependency>
     90 
     91         <dependency>
     92             <groupId>com.alibaba</groupId>
     93             <artifactId>fastjson</artifactId>
     94             <version>RELEASE</version>
     95         </dependency>
     96 
     97         <dependency>
     98             <groupId>com.google.code.json</groupId>
     99             <artifactId>gson</artifactId>
    100         </dependency>
    101         <!--Spring boot end -->
    102 
    103     </dependencies>
    104 
    105     <build>
    106         <plugins>
    107             <plugin>
    108                 <groupId>org.springframework.boot</groupId>
    109                 <artifactId>spring-boot-maven-plugin</artifactId>
    110                 <configuration>
    111                     <fork>true</fork>
    112                 </configuration>
    113             </plugin>
    114             <plugin>
    115                 <groupId>org.apache.maven.plugins</groupId>
    116                 <artifactId>maven-compiler-plugin</artifactId>
    117                 <configuration>
    118                     <source>7</source>
    119                     <target>7</target>
    120                 </configuration>
    121             </plugin>
    122         </plugins>
    123     </build>
    124 
    125 
    126 
    127 </project>

    配置文件和Mapper文件:

     1 <?xml version="1.0" encoding="UTF-8" ?>
     2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     3         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
     4 
     5 <mapper namespace="com.dao.PersonDao">
     6 
     7     <sql id = "Base_Column_List">
     8         rule_name
     9     </sql>
    10 
    11     <select id="listAll" resultType="java.lang.String">
    12         select * from person
    13     </select>
    14 </mapper>
    server.port=8081
    spring.jpa.show-sql=true
    spring.datasource.url=jdbc:mysql://127.0.0.1:3306/droolstest?useUnicode=true&characterEncoding=UTF-8
    spring.datasource.username=root
    spring.datasource.password=root
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    spring.datasource.max-active=10
    spring.datasource.max-idle=5
    spring.datasource.min-idle=0

    创建controller

     1 package com.controller;
     2 
     3 
     4 import com.service.PersonService;
     5 import com.entity.Person;
     6 import org.springframework.stereotype.Controller;
     7 import org.springframework.web.bind.annotation.RequestBody;
     8 import org.springframework.web.bind.annotation.RequestMapping;
     9 import org.springframework.web.bind.annotation.RequestMethod;
    10 import org.springframework.web.bind.annotation.ResponseBody;
    11 
    12 import javax.annotation.Resource;
    13 import javax.servlet.http.HttpServletRequest;
    14 import java.util.HashMap;
    15 import java.util.List;
    16 import java.util.Map;
    17 
    18 
    19 @RequestMapping("/person")
    20 @Controller
    21 public class PersonController {
    22 
    23     @Resource
    24     private PersonService promoteService;
    25 
    26     @ResponseBody
    27     @RequestMapping(value = "/list", method = RequestMethod.POST, produces = "application/json")
    28     public Map<String, Object> testList(HttpServletRequest request, @RequestBody String requestBody) {
    29         Map<String, Object> map = new HashMap<>();
    30         List<Person> personList = promoteService.listPerson();
    31         map.put("personList", personList);
    32         return map;
    33     }
    34 }

    创建启动类文件:

    package com;
    
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.tomcat.jdbc.pool.DataSource;
    import org.mybatis.spring.SqlSessionFactoryBean;
    import org.mybatis.spring.annotation.MapperScan;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    import org.springframework.jdbc.datasource.DataSourceTransactionManager;
    import org.springframework.transaction.PlatformTransactionManager;
    
    @SpringBootApplication
    @MapperScan("org.dao")
    public class Application {
    
        protected static Logger logger = LoggerFactory.getLogger(Application.class);
    
        @Bean
        @ConfigurationProperties(prefix = "spring.datasource")
        public DataSource dataSource() {
            return new DataSource();
        }
    
        @Bean
        public SqlSessionFactory sqlSessionFactoryBean() throws Exception {
            SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
            sqlSessionFactoryBean.setDataSource(dataSource());
            PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath*:mapper/*.xml"));
            return sqlSessionFactoryBean.getObject();
        }
    
        @Bean
        public PlatformTransactionManager transactionManager() {
            return new DataSourceTransactionManager(dataSource());
        }
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
            logger.info("SpringBoot2 Start Success");
        }
    
    }

    ...

  • 相关阅读:
    http://ftp.netfilter.org/pub/iptables/
    安装iptables layer 7 模块
    在Debian etch上 为内核添加netfilterlayer7v2 ,ipp2p0.8.2模块
    解决虚拟机安装 Linux 移植到别处网卡起不来的问题
    在Debian 4.0rc3上编译内核2.6.24时加入Layer7模块笔记[防火墙中在TCP/IP第七层Layer7应用层阻挡QQ,MSN等软件的应用]
    Debian 4
    實作 Layer 7 封包過濾
    DevExpress cxSpreadSheet 自动换行时中文乱码问题的解决【转】
    ABC控件在Delphi7中的安装方法【转】
    取出SQL SERVER字段中的数字
  • 原文地址:https://www.cnblogs.com/sunl123/p/11318304.html
Copyright © 2011-2022 走看看