首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >MyBatis 动态 SQL 为什么这么灵活?背后靠的是 OGNL

MyBatis 动态 SQL 为什么这么灵活?背后靠的是 OGNL

原创
作者头像
JavaEdge
发布2025-12-27 19:04:54
发布2025-12-27 19:04:54
460
举报

本文已收录在Github关注我,紧跟本系列专栏文章,咱们下篇再续!

  • 🚀 魔都架构师 | 全网30W技术追随者
  • 🔧 大厂分布式系统/数据中台实战专家
  • 🏆 主导交易系统百万级流量调优 & 车联网平台架构
  • 🧠 AIGC应用开发先行者 | 区块链落地实践者
  • 🌍 以技术驱动创新,我们的征途是改变世界!
  • 👉 实战干货:编程严选网

0 前言

OGNL(Object Graph Navigation Language,对象图导航语言),在 Struts2 时代是绝对的核心,而在如今 Spring Boot 和 MyBatis 架构,依然在幕后扮演着极其关键的角色。

1 啥是OGNL?

如果把你的 Java 程序比作一座巨大的城市,里面的对象就是一栋栋大楼,而对象的属性就是大楼里的房间。

1.1 传统方式

你想去某个房间,得亲自走楼梯、开门(手动编写 getUser().getAddress().getCity())。如果中间有一个门锁了(为 null),你就摔倒了(NullPointerException)。

1.2 OGNL 方式

你只需要输入一个地址字符串 "user.address.city",OGNL 就像一个智能导航仪,自动帮你穿梭在大楼之间,找到那个房间并取出东西。

核心定义:OGNL 是一种表达式语言(EL),通过简单的字符串语法,就可存取 Java 对象树中的任意属性、调用方法、甚至进行简单的逻辑运算。

2 MyBatis中的动态 SQL

OGNL 是 MyBatis 动态 SQL 的灵魂。

2.1 业务背景

假设你正在开发一个电商平台的订单搜索功能。用户可按订单状态、时间范围、关键词进行筛选。不用 OGNL,可能要写无数个 if-else

2.2 落地实现

MyBatis XML看到的test表达式就是OGNL:

代码语言:xml
复制
<select id="findOrders" resultType="Order">
  SELECT * FROM orders
  WHERE 1=1
  <if test="status != null and status != ''">
    AND status = #{status}
  </if>
  <if test="keywords != null and keywords.length() > 0">
    AND title LIKE CONCAT('%', #{keywords}, '%')
  </if>
</select>

为啥这要用OGNL?因为它解耦“逻辑判断”和“SQL”。你无需在 Java 代码里拼装字符串,只需在 XML 里写简单的“导航公式”,OGNL自动帮你解析参数对象里的值。

3 “热修改”与线上排查

3.1 业务背景

你的微服务已上线,突然发现某接口返回数据异常。你想知:现在内存里某个全局配置变量的值到底是多少? 或想在不重启服务时,临时修改一下某个 Bean 的开关状态

3.2 落地实现:结合 Arthas

Java 诊断利器 Arthas 深度集成 OGNL。可直接在命令行输入 OGNL 表达式来“窥探”运行中的系统。

查看静态变量的值
代码语言:bash
复制
# 查看类中静态变量的值
ognl '@com.example.ConfigManager@getConfig().getTimeout()'
线上“开挂”修改配置
代码语言:bash
复制
# 动态修改线上运行中的某个开关
ognl '#config=@com.example.ConfigManager@instance, #config.setEnableDebug(true)'

微服务架构下,节点众多,重启代价大。利用 OGNL 的动态执行能力,可在不触动代码前提下,精准观察和干预生产环境的对象状态。

4 避坑

虽然 OGNL 很强大,但在分布式设计意:

性能损耗

OGNL 毕竟是基于反射和解析的。在高性能、高并发的内层循环中,频繁使用复杂的表达式会导致 CPU 抖动。最佳实践:复杂的逻辑尽量在 Java 代码中处理好,传给 OGNL 的应该是“结果”。

安全风险

这就是著名的“Struts2 漏洞”根源。如果你的系统允许用户输入 OGNL 表达式并在后台执行,攻击者可以通过构造特殊的字符串(如执行 Runtime.getRuntime().exec("rm -rf /"))来控制你的服务器。最佳实践:绝不要将用户输入的参数直接作为 OGNL 表达式执行。

5 总结

OGNL 不是什么深奥的数学模型,它就是一个“胶水工具”。它让字符串内存对象之间建立了一座桥梁:

  • MyBatis 里,它是 SQL 的“指挥官”。
  • Arthas 里,它是线上的“透视镜”。
  • 数据校验 里,它是灵活的“规则引擎”。

掌握了 OGNL,你不仅能写出更优雅的动态 SQL,更能在系统出问题时,通过表达式直接与内存对话。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0 前言
  • 1 啥是OGNL?
    • 1.1 传统方式
    • 1.2 OGNL 方式
  • 2 MyBatis中的动态 SQL
    • 2.1 业务背景
    • 2.2 落地实现
  • 3 “热修改”与线上排查
    • 3.1 业务背景
    • 3.2 落地实现:结合 Arthas
      • 查看静态变量的值
      • 线上“开挂”修改配置
  • 4 避坑
    • 性能损耗
    • 安全风险
  • 5 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档