:toc: = Expression Execution This section describes the different ways to execute expressions in QLExpress4. == Use Map as the context - `execute(String, Map, QLOptions)` - Description: According to the method comments, use a `Map` as the context; the keys in the `Map` are the variable names used in the script, and the values are the corresponding variable values. - Typical scenario: Build a `Map` from external business data and pass it in so the script can access variables directly by name. [source,java,indent=0] ---- Express4Runner express4Runner = new Express4Runner(InitOptions.DEFAULT_OPTIONS); Map context = new HashMap<>(); context.put("a", 1); context.put("b", 2); context.put("c", 3); Object result = express4Runner.execute("a + b * c", context, QLOptions.DEFAULT_OPTIONS).getResult(); assertEquals(7, result); ---- == Use object fields as the context - `execute(String, Object, QLOptions)` - Description: Use a plain Java object as the context; variable names in the script correspond to the object's field names (or accessible getters). - Typical scenario: When you already have a DTO/POJO that carries the context data, pass the object directly so the script can read its fields. // Note: This references the test code for execution with an object context. [source,java,indent=0] ---- MyObj myObj = new MyObj(); myObj.a = 1; myObj.b = "test"; Express4Runner express4Runner = new Express4Runner(InitOptions.DEFAULT_OPTIONS); Object result = express4Runner.execute("a+b", myObj, QLOptions.DEFAULT_OPTIONS).getResult(); assertEquals("1test", result); ---- == Use a set of aliased objects - `executeWithAliasObjects(String, QLOptions, Object...)` - Description: Pass objects annotated with `@QLAlias`; the annotation value becomes the variable name in the context. Objects without the annotation are ignored. - Typical scenario: Expose object properties/methods with Chinese (or domain-specific) aliases so rule authors can write scripts more intuitively. [source,java,indent=0] ---- Order order = new Order(); order.setOrderNum("OR123455"); order.setAmount(100); User user = new User(); user.setName("jack"); user.setVip(true); // Calculate the Final Order Amount Express4Runner express4Runner = new Express4Runner(InitOptions.builder().securityStrategy(QLSecurityStrategy.open()).build()); Number result = (Number)express4Runner .executeWithAliasObjects("用户.是vip? 订单.金额 * 0.8 : 订单.金额", QLOptions.DEFAULT_OPTIONS, order, user) .getResult(); assertEquals(80, result.intValue()); ---- == Use a custom `ExpressContext` - `execute(String, ExpressContext, QLOptions)` - Description: This overload allows passing a custom context that implements `ExpressContext` (for example, a dynamic variable context). The other `execute` overloads ultimately delegate to this method. - Typical scenario: When you need on-demand, by-name evaluation of variable values, read/write isolation, or integration with external storage, a custom context is the most flexible choice. [source,java,indent=0] ---- Express4Runner express4Runner = new Express4Runner(InitOptions.DEFAULT_OPTIONS); Map staticContext = new HashMap<>(); staticContext.put("语文", 88); staticContext.put("数学", 99); staticContext.put("英语", 95); QLOptions defaultOptions = QLOptions.DEFAULT_OPTIONS; DynamicVariableContext dynamicContext = new DynamicVariableContext(express4Runner, staticContext, defaultOptions); dynamicContext.put("平均成绩", "(语文+数学+英语)/3.0"); dynamicContext.put("是否优秀", "平均成绩>90"); // dynamic var assertTrue((Boolean)express4Runner.execute("是否优秀", dynamicContext, defaultOptions).getResult()); assertEquals(94, ((Number)express4Runner.execute("平均成绩", dynamicContext, defaultOptions).getResult()).intValue()); // static var assertEquals(187, ((Number)express4Runner.execute("语文+数学", dynamicContext, defaultOptions).getResult()).intValue()); ----