Java | 在 Java 中执行动态表达式语句: 前中后缀、SpEL、OGNL、Groovy、Jexl3
亲爱的编程学习爱好者,如果你点开了这篇文章,说明你对《Java | 在 Java 中执行动态表达式语句: 前中后缀、SpEL、OGNL、Groovy、Jexl3》很感兴趣。本篇文章就来给大家详细解析一下,主要介绍一下MySQL、Java、groovy,希望所有认真读完的童鞋们,都有实质性的提高。
在一些规则集或者工作流项目中,经常会遇到动态解析表达式并执行得出结果的功能。
规则引擎是一种嵌入在应用程序中的组件,它可以将业务规则从业务代码中剥离出来,使用预先定义好的语义规范来实现这些剥离出来的业务规则;规则引擎通过接受输入的数据,进行业务规则的评估,并做出业务决策。
工作流(Workflow),是对工作流程及其各操作步骤之间业务规则的抽象、概括描述。 工作流建模,即将工作流程中的工作如何前后组织在一起的逻辑和规则,在计算机中以恰当的模型表達并对其实施计算。 工作流要解决的主要问题是:为实现某个业务目标,利用计算机在多个参与者之间按某种预定规则自动传递文档、信息或者任务。
Table of Contents
前缀、中缀、后缀表达式(逆波兰表达式)
最早接触的表达式解析是在上数据结构的时候,当时课设作业是 “ 做一个简单的四则混合运算语句解析并计算结果 ”,简单说就是计算器。
中缀表达式
将运算符写在两个操作数中间的表达式,称作中缀表达式。
中缀表达式是我们最熟悉和阅读最容易的表达式
比如:
ognl ognl 3.2.18
MemberAccess memberAccess = new AbstractMemberAccess() {
@Override
public boolean isAccessible(Map context, Object target, Member member, String propertyName) {
int modifiers = member.getModifiers();
return Modifier.isPublic(modifiers);
}
};
OgnlContext context = (OgnlContext) Ognl.createDefaultContext(this,
memberAccess,
new DefaultClassResolver(),
new DefaultTypeConverter());
context.put("verifyStatus", 1);
Object expression = Ognl.parseExpression("#verifyStatus == 1");
boolean result =(boolean) Ognl.getValue(expression, context, context.getRoot());
Assert.assertTrue(result);SpEL
SpEL(Spring Expression Language),即Spring表达式语言。它是一种类似JSP的EL表达式、但又比后者更为强大有用的表达式语言。
ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("#verifyStatus == 1");
EvaluationContext context = new StandardEvaluationContext();
context.setVariable("verifyStatus", 1);
boolean result = (boolean) expression.getValue(context);
Assert.assertTrue(result);Jexl/Jexl3
引入依赖
org.apache.commons commons-jexl3 3.1
执行简单的表达式
JexlEngine jexl = new JexlBuilder().create();
JexlContext jc = new MapContext();
jc.set("verifyStatus", 1);
JexlExpression expression = jexl.createExpression("verifyStatus == 1");
boolean result = (boolean) expression.evaluate(jc);
Assert.assertTrue(result);Groovy
Groovy 是一个很好的选择,其具备完备的 Groovy 和 Java 语法的解析执行功能。
引入依赖, 这个可以根据需要引入最新版本
org.codehaus.groovy groovy 2.5.6
执行表达式
Binding binding = new Binding();
binding.setVariable("verifyStatus", 1);
GroovyShell shell = new GroovyShell(binding);
boolean result = (boolean) shell.evaluate("verifyStatus == 1");
Assert.assertTrue(result);扩展
经常用 MyBatis 的一定用过动态语句
这里我们简化一下
该示例主要为了讲解,不一定好用, 其中
select id, invite_code, phone, name
from user
where status = 1
@if(:inviteCode != null) { and invite_code = :inviteCode }在处理这种 SQL 中,我们可以先用正则,将
Listresults = StringUtil.matches(sql, "@if([\\s\\S]*?)}");
通过这种方式匹配到
String text = "@if(:inviteCode != null) { and invite_code = :inviteCode }";
List sqlFragment = StringUtil.matches(text, "\\(([\\s\\S]*?)\\)|\\{([\\s\\S]*?)\\}"); 分离出
- :inviteCode != null
- and invite_code = :inviteCode
其中
ListsqlFragmentParam = StringUtil.matches(":inviteCode != null", "\\?\\d+(\\.[A-Za-z]+)?|:[A-Za-z0-9]+(\\.[A-Za-z]+)?");
得到 inviteCode,并通过某种方式找到对应的值,
JexlEngine jexl = new JexlBuilder().create();
JexlContext jc = new MapContext();
jc.set(":inviteCode", "ddddsdfa");
JexlExpression expression = jexl.createExpression(sqlExp);
boolean needAppendSQL = (boolean) expression.evaluate(jc);通过 needAppendSQL 来决定是否拼接 SQL, 这样一个简单的动态 SQL 就实现了,上面用的 Jexl 写的,你可以改成上面任意一种方案,这里只做演示
具体代码,仅供参考
@Test
public void testSQL() {
String sql = "select id, invite_code, phone, name \n"
+ "from user \n"
+ "where status = 1 \n"
+ "@if(:inviteCode != null) { and invite_code = :inviteCode }";
Map params = new HashMap();
params.put("inviteCode", "dd");
System.out.println(parseJexl(sql, params));
}
public String parseJexl(String jexlSql, Map params) {
// 判断是否包含 @if
List results = StringUtil.matches(jexlSql, "@if([\\s\\S]*?)}");
if (results.isEmpty()) {
return jexlSql;
}
JexlEngine jexl = new JexlBuilder().create();
JexlContext jc = new MapContext();
for (String e : results) {
List sqlFragment = StringUtil.matches(e, "\\(([\\s\\S]*?)\\)|\\{([\\s\\S]*?)\\}");
String sqlExp = sqlFragment.get(0).trim().substring(1, sqlFragment.get(0).length() - 1);
List sqlFragmentParam = StringUtil.matches(sqlExp, "\\?\\d+(\\.[A-Za-z]+)?|:[A-Za-z0-9]+(\\.[A-Za-z]+)?");
for (String param : sqlFragmentParam) {
String newSQLExp = "_" + param.substring(1);
sqlExp = sqlExp.replace(param, newSQLExp);
jc.set(newSQLExp, params.get(param.substring(1)));
}
JexlExpression expression = jexl.createExpression(sqlExp);
Boolean needAppendSQL = (Boolean) expression.evaluate(jc);
if (needAppendSQL) {
jexlSql = jexlSql.replace(e, sqlFragment.get(1).trim().substring(1, sqlFragment.get(1).length() - 1));
} else {
jexlSql = jexlSql.replace(e, "");
}
}
return jexlSql;
} 参考
关于 OGNL、SpEL、Jexl3 和 Groovy 的具体用法可以参考文档
- http://commons.apache.org/pro...
- https://docs.spring.io/spring...
- http://groovy-lang.org/syntax...
- http://commons.apache.org/pro...
今天关于《Java | 在 Java 中执行动态表达式语句: 前中后缀、SpEL、OGNL、Groovy、Jexl3》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!
ubuntu-20.04.1-desktop上phpipam的其他功能扩展
- 上一篇
- ubuntu-20.04.1-desktop上phpipam的其他功能扩展
- 下一篇
- 解决部署zabbix时 Row size too large (> 8126)的问题
-
- 欢呼的手机
- 这篇文章内容出现的刚刚好,太细致了,太给力了,已加入收藏夹了,关注作者了!希望作者能多写数据库相关的文章。
- 2023-02-25 03:05:32
-
- 稳重的小兔子
- 这篇技术文章真及时,好细啊,很好,收藏了,关注老哥了!希望老哥能多写数据库相关的文章。
- 2023-02-07 17:46:36
-
- 文艺的小土豆
- 太全面了,收藏了,感谢楼主的这篇文章内容,我会继续支持!
- 2023-02-05 16:49:20
-
- 务实的泥猴桃
- 感谢大佬分享,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,帮助很大,总算是懂了,感谢楼主分享技术文章!
- 2023-01-25 20:21:05
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 6073次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 6492次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 6302次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 8265次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 6899次使用
-
- golang MySQL实现对数据库表存储获取操作示例
- 2022-12-22 499浏览
-
- 搞一个自娱自乐的博客(二) 架构搭建
- 2023-02-16 244浏览
-
- B-Tree、B+Tree以及B-link Tree
- 2023-01-19 235浏览
-
- mysql面试题
- 2023-01-17 157浏览
-
- MySQL数据表简单查询
- 2023-01-10 101浏览

