作為一名 Java 開發(fā)者,你一定經(jīng)歷過被 MyBatis XML 支配的恐懼。
當你打開一個 UserMapper.xml,迎面而來的是幾百行甚至上千行的 , , , 標簽。原本清爽的 SQL 語句被這些 XML 標簽切割得支離破碎,仿佛老太太的裹腳布——又臭又長。
如果你也受夠了在 XML 標簽里寫邏輯,受夠了為了一個簡單的非空判斷就要寫三行 XML,那么請繼續(xù)往下看。dbVisitor 的動態(tài) SQL 規(guī)則機制,也許就是你一直在尋找的 "剪刀"。
MyBatis 的 XML 地獄
讓我們先回顧一下,一個標準的、帶有幾個查詢條件的 MyBatis SQL 是什么樣子的:
這段代碼的問題在哪里,已經(jīng)不用多言!這種 一坨一坨 的開發(fā)體驗看到就難受至極,更別提還要去維護它。
革命性的解法
dbVisitor 作為一個新一代的數(shù)據(jù)庫訪問工具,最核心的設計理念之一就是:讓 SQL 回歸 SQL。
利用 dbVisitor 獨創(chuàng)的 規(guī)則機制,上面的 XML 代碼可以精簡為:
@{and, create_time >= :createTime}假設只傳入?yún)?shù) name="Tom",生成的 SQL 如下:
SELECT * FROM tb_user WHERE name = ?是不是瞬間清爽了?沒有了尖括號的視覺干擾,沒有了冗余的 XML 閉合標簽,只有純粹的 SQL 邏輯。
你可能會問:@{and, ...} 到底做了什么?它是簡單的字符串拼接嗎?
當然不是!dbVisitor 的規(guī)則是非常智能的,以 @{and, name = :name} 為例,它內(nèi)置了以下邏輯:
智能判空
引擎會自動檢查 key = :key 表達式中的參數(shù)。如果參數(shù) :key 為 null,整個 @{and} 規(guī)則塊會被自動忽略,不會生成任何 SQL。
(注意:空字符串""被視為有效值,不會忽略)
WHERE 處理
如果內(nèi)容不為空 @{and} 會識別它是否是 WHERE 子句的開頭。如果是開頭(例如前面沒有1=1),它會自動抹去 AND,直接生成 WHERE name = ?
(這一點類似 MyBatis 的標簽,但更加隱形)
這一切都是自動發(fā)生的,你只需要聲明規(guī)則,剩下的交給 dbVisitor。
條件判斷本該如此性感
MyBatis 中 90% 的 標簽都是為了做兩件事:
參數(shù)不為空時,追加查詢條件。
開關開啟時,追加查詢條件。
dbVisitor 將這兩類高頻場景直接內(nèi)化為最基礎的規(guī)則,無需任何復雜的標簽嵌套。
智能補全
自動檢查條件狀態(tài)選擇是否需要自動補全 WHERE/AND/OR 關鍵字。
@{and, name = :name} -- 生成 and name = ?2. 智能判空
@{and} 和 @{or} 這是最常用的判空規(guī)則,它們會自動檢查參數(shù)是否為 null。
@{or, age > :age} -- 僅當 age 不為空時生成 or age > ?3. 開關控制
@{ifand} 和 @{ifor} 當你需要用布爾值來控制 SQL 時就會使用他們。
SELECT * FROM tb_user @{ifand, !showAll, is_delete = 0}對比 MyBatis 的臃腫寫法以及像老鼠屎一樣無處不在的 1=1
僅僅是一個簡單的條件,dbVisitor 讓你少寫了 3 行代碼,減少無用的條件判斷,這就是效率。
一行代碼的 IN 查詢
MyBatis 的 標簽簡直是反人類設計:collection, item, open, close... 配置項多達七八個,而且為了防止集合為空導致 SQL 語法錯誤,通常還得在外面套一層,簡直令人窒息:
if>而在 dbVisitor 中,利用 @{ifand} 和 @{in} 兩個規(guī)則的 嵌套使用,你只需要一行:
@{ifand, !idList.isEmpty, id IN @{in, :idList}}對比一下,這代碼量節(jié)省的可不是一點點,而是 降維打擊!
忘掉 , 忘掉逗號
在寫 Update 語句時,處理末尾的逗號是最煩人的。dbVisitor 的 @{set}規(guī)則完美解決,引擎會自動處理字段間的逗號:
WHERE id = #{id}MyBatis 用了一大堆標簽來解決這個問題:
WHERE id = #{id}?? 雖然 @{set} 規(guī)則很強大,但規(guī)則的判斷是依賴已經(jīng)生成的 SQL 進行推斷。
當規(guī)則沒有匹配時,一些意外情況:
WHERE id = :id分支判斷的救星
MyBatis 的 - - 結構冗長得令人發(fā)指,寫起來仿佛在填表。最大的麻煩在于即便是使用 @Select 注解仍然逃脫不了 XML 的魔咒。
@Param("content") String content);dbVisitor 讓你用 SQL 的思維寫 SQL,更符合編程直覺。同樣的場景,dbVisitor 只需要這樣:
CASE 規(guī)則 IF-ELSE 模式
}CASE 規(guī)則 Switch 模式 換一個例子:根據(jù) encryptMode 的值選擇加密方式。
}像樂高積木一樣組合
規(guī)則引擎最強大的地方在于其 可組合性。規(guī)則可以像樂高積木一樣嵌套使用。這意味著你可以用 @{case} 的結果去驅(qū)動 @{and} 或者在 @{else} 里寫一組 @{if}
比如一個常見的權限控制場景:
如果是管理員 (ADMIN),查詢所有數(shù)據(jù);
如果是部門經(jīng)理 (MGR),查詢本部門數(shù)據(jù);
如果是普通員工,只能查自己的數(shù)據(jù)。
}注意看,外層的 @{and} 會自動處理連接詞:
當 role 是 'ADMIN' 時,@{case} 輸出空,整個 @{and} 消失。
當 role 是 'MGR' 時,內(nèi)部輸出 dept_id = ?,外層自動加上 AND。
這種自然的嵌套組合,讓你能用 SQL 結構直接表達復雜的業(yè)務邏輯,而不是在 Java 代碼和 XML 之間反復橫跳。
這就結束了?
規(guī)則的強大之處在于無處不在。你不需要為了使用動態(tài) SQL 而強迫自己切換開發(fā)模式。無論你身處哪個層級,dbVisitor 的動態(tài)規(guī)則都能無縫集成。
1. 在 編程式 API (JdbcTemplate) 中使用
不需要 StringBuilder,不需要拼接字符串。
"SELECT * FROM users @{and, name = :name}", args);2. 在 聲明式 API (注解) 中使用
徹底擺脫 @Script 或者
特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺“網(wǎng)易號”用戶上傳并發(fā)布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.