欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MyBatis OGNL 表達式的避坑指南

 更新時間:2025年09月19日 09:56:22   作者:陳三一  
本文主要介紹了MyBatis OGNL 表達式的避坑指南,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

MyBatis 中 OGNL 表達式的那些 “坑”:從字符串比較案例說起

在 MyBatis 開發(fā)中,<if>標簽的test屬性是實現動態(tài) SQL 的核心,但很多開發(fā)者會遇到 “明明變量值符合預期,條件卻不生效” 的問題。這背后往往是OGNL(Object-Graph Navigation Language)表達式的解析規(guī)則在 “作祟”。本文將通過兩個真實案例,拆解 OGNL 對字符串、字符、數字的處理邏輯,幫你徹底避開這類陷阱。

一、先看兩個 “反直覺” 的案例

在分析原理前,我們先明確核心變量背景:startInstLdgrHierCd是字符串類型,只是不同場景下值不同,卻導致了完全不同的條件判斷結果。

案例 1:變量值為 "0" 時的差異

當startInstLdgrHierCd = "0"(字符串 "0")時,三種寫法結果天差地別:

寫法是否成立疑問
<if test="startInstLdgrHierCd == '0'">? 不成立明明值都是 "0",為什么不生效?
<if test="startInstLdgrHierCd == 0">? 成立字符串和數字怎么能相等?
<if test='startInstLdgrHierCd == "0"'>? 成立換了引號包裹,為什么又生效了?

案例 2:變量值為 "01" 時的反轉

當startInstLdgrHierCd = "01"(字符串 "01")時,之前不生效的寫法突然有效了:

<!-- 此時條件成立,與案例1中"0"的情況完全相反 -->
<if test="startInstLdgrHierCd == '01'"> 
  AND HQ_INSID = #{startInstId} 
</if>

這兩個案例的核心矛盾,都指向 OGNL 對 “引號內容的類型解析” 和 “類型比較規(guī)則”—— 這也是 MyBatis 動態(tài) SQL 中最容易踩的坑。

二、OGNL 表達式的核心規(guī)則(必懂)

要解決上述問題,必須先掌握 OGNL 在 MyBatis 中的 3 個關鍵解析邏輯,這是所有判斷的基礎:

1. 單引號' '的解析:字符還是字符串?

OGNL 對單引號內容的判斷,完全取決于字符數量

  • 單引號內只有「1 個字符」(如'0'、'A')→ 解析為「char 類型(字符)」;

  • 單引號內有「2 個及以上字符」(如'01'、'AB')→ 解析為「String 類型(字符串)」。

這是案例 1 和案例 2 結果差異的核心原因,很多開發(fā)者誤以為 “單引號一定是字符”,實則不然。

2. 雙引號" "的解析:固定為字符串

無論雙引號內有多少個字符(如"0"、"01"),OGNL 都會統(tǒng)一解析為「String 類型(字符串)」。但要注意:XML 屬性值本身需要用引號包裹(單引號或雙引號),因此雙引號的使用會受 XML 語法限制(比如test用雙引號時,內部雙引號會被 XML 解析器當作屬性結束符,導致語法錯誤)。

3. 類型比較規(guī)則:嚴格優(yōu)先,自動轉換為輔

OGNL 比較兩個值時,遵循 “先看類型,再看值” 的邏輯:

  • 類型相同:直接比較值是否相等(如 String 與 String、int 與 int);

  • 類型不同:僅在 “字符串與數字” 之間會嘗試自動類型轉換(字符串轉數字),其他類型組合(如 String 與 char)直接判定為不相等。

三、逐案拆解:為什么結果不一樣?

結合上述規(guī)則,我們重新分析兩個案例,所有 “反直覺” 的現象都會迎刃而解。

案例 1:變量值為 "0"(字符串)的三種寫法

變量startInstLdgrHierCd的類型是 String,值為 "0",我們逐一拆解三種寫法的判斷邏輯:

寫法 1: → 不成立

  • 右邊'0':1 個字符 → OGNL 解析為「char 類型」;
  • 左邊變量:String 類型;
  • 比較邏輯:String 與 char 類型不同,且 OGNL 不支持這兩種類型的自動轉換 → 直接判定為不相等(結果為 false)。

類比 Java 代碼:String a = "0"; char b = '0'; a == b → 結果 false。

寫法 2: → 成立

  • 右邊0:無引號 → OGNL 解析為「int 類型(數字)」;
  • 左邊變量:String 類型;
  • 比較邏輯:String 與 int 類型不同,但 OGNL 支持 “字符串轉數字” 的自動轉換 → 字符串 "0" 轉成數字 0 后,與右邊的 0 相等(結果為 true)。

類比 Java 代碼:String a = "0"; int b = 0; Integer.parseInt(a) == b → 結果 true。

寫法 3: → 成立

  • 外層test用單引號包裹:內部的"0"不會被 XML 解析器誤判,OGNL 正常解析為「String 類型」;
  • 右邊"0":雙引號 → 解析為 String 類型;
  • 左邊變量:String 類型;
  • 比較邏輯:類型相同(均為 String),值均為 "0" → 判定為相等(結果為 true)。

案例 2:變量值為 "01"(字符串)的寫法

變量startInstLdgrHierCd的類型是 String,值為 "01",分析<if test="startInstLdgrHierCd == '01'">

  • 右邊'01':2 個字符 → OGNL 解析為「String 類型」;
  • 左邊變量:String 類型;
  • 比較邏輯:類型相同(均為 String),值均為 "01" → 判定為相等(結果為 true)。

這就解釋了為什么 “同樣是單引號”,值為 "0" 時不生效,值為 "01" 時卻生效 —— 核心是單引號內字符數量改變了解析后的類型。

四、避坑指南:MyBatis OGNL 的最佳實踐

通過以上分析,我們可以總結出 3 條實用規(guī)則,徹底避免 OGNL 表達式的類型混淆問題:

1. 字符串比較:統(tǒng)一用 “單引號包 test,雙引號包值”

這是最安全的寫法,能明確指定兩邊都是 String 類型,完全避開單引號解析的陷阱:

<!-- 推薦寫法:test用單引號,值用雙引號 -->
<if test='startInstLdgrHierCd == "0"'>
<if test='startInstLdgrHierCd == "01"'>

2. 避免 “字符串與數字” 的直接比較

雖然 OGNL 支持字符串轉數字,但這種自動轉換存在風險(比如字符串無法轉數字時會報錯,如"A" == 0會拋出轉換異常)。若業(yè)務需要比較數字,建議先將變量轉為數字類型(如在 Java 代碼中處理),再在test中比較:

// 錯誤:直接用字符串比較數字
String startInstLdgrHierCd = "0";
// 正確:先轉為數字
Integer ldgrHierCd = Integer.parseInt(startInstLdgrHierCd);
param.put("ldgrHierCd", ldgrHierCd);
<!-- 此時兩邊都是int類型,無轉換風險 -->
<if test="ldgrHierCd == 0">

3. 單引號僅用于 “單個字符” 的比較(謹慎使用)

若確實需要比較 char 類型(如變量是 Character 類型),再用單引號,且務必確保值是單個字符:

<!-- 變量是Character類型時才推薦 -->
<if test="charVar == 'Y'">

五、總結

MyBatis 的 OGNL 表達式看似簡單,實則暗藏 “類型解析” 的細節(jié)。很多開發(fā)者踩坑的本質,是忽略了 “單引號的字符數量影響類型” 和 “OGNL 的自動轉換規(guī)則”。

記住核心結論:

  • 單引號內 1 個字符→char,≥2 個字符→String;
  • 雙引號永遠是 String,推薦用test='變量 == "值"';
  • 避免字符串與數字直接比較,優(yōu)先統(tǒng)一類型。

掌握這些規(guī)則后,你就能輕松應對 MyBatis 動態(tài) SQL 的各種條件判斷,再也不用為 “條件不生效” 而頭疼了!

到此這篇關于MyBatis OGNL 表達式的避坑指南的文章就介紹到這了,更多相關MyBatis OGNL 表達式內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Springboot 跨域配置無效及接口訪問報錯的解決方法

    Springboot 跨域配置無效及接口訪問報錯的解決方法

    這篇文章主要介紹了Springboot 跨域配置無效及接口訪問報錯的解決方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • java數據庫數據分批讀取的實現示例

    java數據庫數據分批讀取的實現示例

    在處理大量數據時,直接從數據庫一次性讀取所有數據可能會導致內存溢出或者性能下降,本文就來介紹一下java數據庫數據分批讀取的實現示例,感興趣的可以了解一下
    2024-01-01
  • spring mvc url匹配禁用后綴訪問操作

    spring mvc url匹配禁用后綴訪問操作

    這篇文章主要介紹了spring mvc url匹配禁用后綴訪問操作,具有很好的參考價值,希望對大家有所幫助。以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家
    2021-07-07
  • java數組排列組合問題匯總

    java數組排列組合問題匯總

    這篇文章主要為大家詳細匯總了java數組排列組合問題,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • SpringBoot @Cacheable自定義KeyGenerator方式

    SpringBoot @Cacheable自定義KeyGenerator方式

    這篇文章主要介紹了SpringBoot @Cacheable自定義KeyGenerator方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Springboot+Poi導入Excel表格實現過程詳解

    Springboot+Poi導入Excel表格實現過程詳解

    這篇文章主要介紹了Springboot+Poi導入Excel表格實現過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09
  • Java中的字節(jié)流InputStream和OutputStream詳解

    Java中的字節(jié)流InputStream和OutputStream詳解

    這篇文章主要介紹了Java中的字節(jié)流InputStream和OutputStream詳解,繼承自InputStream的流都是用于向程序中輸入數據,且數據的單位為字節(jié)8bit,我們看到的具體的某一些管道,凡是以InputStream結尾的管道,都是以字節(jié)的形式向我們的程序輸入數據,需要的朋友可以參考下
    2023-10-10
  • java wagon如何打包文件到不同服務器

    java wagon如何打包文件到不同服務器

    這篇文章主要介紹了java wagon如何打包文件到不同服務器,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-06-06
  • Java的設計模式之代理模式使用詳解

    Java的設計模式之代理模式使用詳解

    這篇文章主要介紹了Java的設計模式之代理模式使用詳解,代理模式是23種設計模式之一,它關心的主要是過程,而不是結果,代理模式主要提供了對目標對象的間接訪問方式,即通過代理對象來訪問目標對象,需要的朋友可以參考下
    2024-01-01
  • 關于RequestMapping注解的作用說明

    關于RequestMapping注解的作用說明

    這篇文章主要介紹了關于RequestMapping注解的作用說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教。
    2022-01-01

最新評論