有開發(fā)者引用物理學(xué)隱喻:“粒子的位置與動量不可同時確定”,暗示在框架設(shè)計中,通用性與專用性難以兼得。更有人直言,任何嘗試“大一統(tǒng)”的框架,最終都會淪為“四不像”,不僅丟掉了數(shù)據(jù)庫的強事務(wù)優(yōu)勢,也沒能發(fā)揮出例如 Elasticsearch 的能力。
面對這些質(zhì)疑,dbVisitor 依然堅定地提出了"One API Access Any DataBase"的愿景。為什么我敢這么說?今天我們就來拆解這個爭議,聊聊 dbVisitor 敢于挑戰(zhàn)“大一統(tǒng)”的底氣究竟在哪里。
我們對 API 的誤解
要理解為什么 “大一統(tǒng)” 是可行的,我們首先需要厘清兩個長期以來混淆視聽的誤區(qū)。
1. API 業(yè)務(wù)化
目前的 Java 數(shù)據(jù)庫訪問領(lǐng)域,出現(xiàn)了一種明顯的趨勢:API 越來越“業(yè)務(wù)化”。
什么是業(yè)務(wù)化?
為了解決特定領(lǐng)域的復(fù)雜查詢問題,數(shù)據(jù)庫訪問框架開始追求極致的開發(fā)效率。 例如一些優(yōu)秀項目:SqlToy-ORM 在處理極致的分頁優(yōu)化、緩存翻譯以及層次化數(shù)據(jù)查詢(如遞歸查詢)方面表現(xiàn)卓越, 往往能用極簡的配置解決令人頭禿的 SQL 難題;而 Easy-Query 則在類型安全的動態(tài)查詢構(gòu)建上做到了極致,讓你在 Java 代碼中就能以結(jié)構(gòu)化的方式編寫出極其復(fù)雜的業(yè)務(wù)邏輯。
價值:對于特定領(lǐng)域的復(fù)雜查詢(如多表關(guān)聯(lián)、動態(tài)聚合、行轉(zhuǎn)列)它們甚至能通過很少的代碼替代幾十行原生 SQL。這種效率提升是巨大的,值得充分肯定。
局限:這種“神器”級別的 API 往往與數(shù)據(jù)庫的特性強綁定。例如 MySQL 的復(fù)雜查詢邏輯,直接照搬到 MongoDB 或 Elasticsearch 上是完全行不通的。
dbVisitor 的選擇:回歸基座
回顧 Hibernate、MyBatis、DBUtils 甚至 JDBC 本身,這些生命力持久的項目都有一個共性:職責(zé)單一、目標(biāo)明確。它們不做業(yè)務(wù)邏輯,而是專注做基座。
MyBatis Plus 在國內(nèi)的巨大成功,正是建立在 MyBatis 這個堅實的 “非業(yè)務(wù)化” 基座之上。MyBatis 負(fù)責(zé)映射,MP 負(fù)責(zé)提供更高級的特性和封裝。
通用性的價值在于做“房屋的骨架”。dbVisitor 的目標(biāo)并非替代 Easy-Query 這類工具去解決具體業(yè)務(wù)的復(fù)雜查詢,而是立志成為新時代的數(shù)據(jù)訪問基座。 只有基座穩(wěn)固且統(tǒng)一,上層的業(yè)務(wù)生態(tài)(就像 MyBatis 生態(tài))才能在不同數(shù)據(jù)源上百花齊放。
2. “簡單模式無用論” 的謬誤
反對者常由兩個觀點:
“CRUD 太簡單,統(tǒng)一了也沒價值”
“統(tǒng)一 API 無法跨越數(shù)據(jù)庫特性的鴻溝”
反駁觀點一:簡單 CRUD 的普世價值
如果你的世界里只有 MySQL 和 Oracle,那么非常確實,JDBC 已經(jīng)統(tǒng)一了,再造輪子沒意義。 但如果你的技術(shù)棧加入了MongoDB、Elasticsearch、Redis呢?
MongoDB 插入一條數(shù)據(jù)用 “db.collection.insertOne()”
Elasticsearch 插入一條數(shù)據(jù)用 “POST /indexName/_doc ...”
Redis 插入一條數(shù)據(jù)用 “set xxx”命令
這些“簡單”的操作,API 風(fēng)格天差地別。在"One API Access Any DataBase"的愿景下,能用統(tǒng)一的insert(entity)完成上述所有操作,本身就具有極高的普世價值,它消除了認(rèn)知切換的成本。
反駁觀點二:API 不僅僅是查詢構(gòu)造器
這是一個巨大的思維誤區(qū):“統(tǒng)一 API” 不等于 “統(tǒng)一成某一特定的接口”。
查詢構(gòu)造器是不是 API?當(dāng)然是!
Mapper 接口(Dao)是不是 API?當(dāng)然是!
MyBatis 的 Mapper XML 綁定是不是 API?當(dāng)然是!
底層的JDBC Connection是不是 API?更是!
人們鄙棄 Mapper + XML,往往是因為它寫起來繁瑣(重復(fù)勞動),但在架構(gòu)層面,Mapper 接口綁定 DSL是最符合“行為中心”的 API 設(shè)計。 它將“業(yè)務(wù)意圖”(方法名)與“具體實現(xiàn)”(SQL/DSL)剝離。
只要我們不再執(zhí)著于用 Java 代碼去描述一切查詢,而是接受“API 定義行為”這個理念,跨越數(shù)據(jù)庫特性的鴻溝就可以迎刃而解。
dbVisitor 的核心思想
沒有靈丹妙藥,任何試圖發(fā)明一種 “萬能 Java 語法”來生成所有數(shù)據(jù)庫查詢的嘗試,都注定失敗。
dbVisitor 之所以敢說“可以”,是因為其核心思想并非去消滅差異尋求發(fā)明萬能語法, 而是通過JDBC 標(biāo)準(zhǔn)化和分層抽象來管理差異。并通過獨特的雙層適配器架構(gòu)來彌合鴻溝:
JDBC 標(biāo)準(zhǔn)化
這層是 dbVisitor 達(dá)成 “One API Access Any DataBase” 愿景的根基。
復(fù)用 JDBC 標(biāo)準(zhǔn)
沒有發(fā)明新協(xié)議,而是為 NoSQL(MongoDB, Elasticsearch, Redis)編寫了遵循 JDBC 規(guī)范的驅(qū)動。 并使用這些數(shù)據(jù)庫官方原始的 DSL 語言來進(jìn)行數(shù)據(jù)庫操作。這些驅(qū)動在內(nèi)部也僅僅是將 JDBC 的操作映射到各自的原生 SDK 調(diào)用上,并將返回值映射成 JDBC 標(biāo)準(zhǔn)方式。
Request/Response 模型
為了簡化異構(gòu)數(shù)據(jù)源的接入,復(fù)雜的 JDBC 狀態(tài)管理被簡化為輕量級的 Request/Response 模型。這使得你可以用很少的代碼即可接入一個全新的非標(biāo)準(zhǔn)的數(shù)據(jù)源。 新的數(shù)據(jù)源,甚至直接被HikariCP管理。在使用它們的時候,除了查詢語法不是 SQL 意外其它完全一致。
正是基于上述特征 dbVisitor 在進(jìn)行適配 Elasticsearch 時只使用了約 20 個類,總共 2300 行代碼,極其輕量。
One API
這里的“One API”并非指用一個死板的接口去涵蓋一切,而是指構(gòu)建 一種統(tǒng)一的數(shù)據(jù)交互標(biāo)準(zhǔn), dbVisitor 的設(shè)計哲學(xué)認(rèn)為,真正的統(tǒng)一不是強行把所有數(shù)據(jù)庫操作都塞進(jìn)同一個狹窄的入口,而是通過分層抽象在不同的維度上提供統(tǒng)一的體驗。
![]()
dbVisitor 為不同的場景設(shè)計了不同級別的抽象接口,以應(yīng)對不同的行為需求:
LambdaQuery(屏蔽差異) Mapper / XML(管理差異) JDBC Template(透傳執(zhí)行) 統(tǒng)一 API ≠ 統(tǒng)一能力
盡管 dbVisitor 統(tǒng)一了 insert/update/commit 等調(diào)用形式,但它不能改變底層數(shù)據(jù)庫的物理特性。 對于 MongoDB、Elasticsearch 等弱事務(wù)或無事務(wù)的存儲,調(diào)用commit()可能只是邏輯上的空操作,并不意味著具備了關(guān)系型數(shù)據(jù)庫的 ACID 強一致性保障。
實戰(zhàn):多維度的統(tǒng)一體驗
讓我們通過代碼,看看這套理念是如何落地的。
1. 簡單維度(類型安全)
無論底層是 MySQL 還是 Elasticsearch,標(biāo)準(zhǔn)的 CRUD 代碼完全一致。
![]()
2. 業(yè)務(wù)維度(行為為中心)
當(dāng)我們需要發(fā)揮 ES 的聚合能力或 MySQL 的復(fù)雜 Join 時,Mapper 接口是最佳選擇。dbVisitor 提供了三種使用 Mapper 的姿勢,你可以根據(jù)業(yè)務(wù)復(fù)雜度靈活混用。
方式一:純 Java 構(gòu)建
這是 dbVisitor 一種方式,通過繼承 BaseMapper并利用 Java 8 的default 方法,你可以在 Mapper 接口內(nèi)部直接使用查詢構(gòu)造器完成 DAL 邏輯。 這種方式既避免了 XML 的繁瑣,又不像注解那樣將 SQL 硬編碼在 Java 文件中,完美實現(xiàn)了“零 SQL”開發(fā)。
![]()
方式二:基于注解
對于中等復(fù)雜度的查詢,直接在接口方法上使用注解是最簡潔的方式。你無需編寫額外的 XML 文件,即可完成 SQL 或 DSL 的綁定。
![]()
方式三:基于 Mapper 文件
當(dāng) SQL 變得極度復(fù)雜(如幾百行的報表 SQL),或者公司有嚴(yán)格的 DBA 審查流程(需分離 SQL 文件)時,XML 依然是不可替代的方案。
Java 接口(定義行為):
![]()
XML 實現(xiàn)(定義邏輯):這里展示了 dbVisitor 的強大之處:在 XML 中寫不同數(shù)據(jù)庫的方言。
![]()
3. 靈活維度:(原生體驗)
這是 dbVisitor 的“逃生艙”。當(dāng)上層所有的抽象都無法滿足你的特殊需求時,比如需要極致的性能優(yōu)化、使用數(shù)據(jù)庫特有的非標(biāo)指令,或者集成QueryDSL等第三方框架,你可以退回到這層。
場景一:原生 SQL/Shell 透傳
直接下發(fā)數(shù)據(jù)庫能識別的原生命令,無需任何轉(zhuǎn)譯。
![]()
場景二:底層 API 可達(dá)
你可以隨時打破封裝,直接操作底層的Connection。對于 NoSQL 數(shù)據(jù)源,dbVisitor 的驅(qū)動層也遵循了 JDBC 的Wrapper規(guī)范,允許你 unwrap 出官方的原生驅(qū)動對象。
![]()
為何選擇 dbVisitor?
很多人會問:“這不就是把 MyBatis 和 Spring 縫合了一下嗎?” 其實并非如此。dbVisitor 不是簡單的“膠水”,而是基于統(tǒng)一架構(gòu)的重新設(shè)計。
![]()
1. 獨立的雙層適配能力
dbVisitor 是One API + Driver。 即便你不打算替換現(xiàn)在的 MyBatis,你依然可以單獨使用 dbVisitor 的JDBC Driver。把它放入你的 Spring Boot + MyBatis 項目中,你的 MyBatis 立刻就具備了操作 MongoDB 和 Elasticsearch 的能力! 這是一種“降維打擊”般的兼容性。
2. 底層架構(gòu)的高度統(tǒng)一
如果你嘗試過在項目中混用 MyBatis 和 Spring JDBC,你會發(fā)現(xiàn)割裂感很強:
MyBatis 的TypeHandler在 Spring JDBC 里用不了。
Spring 的RowMapper在 MyBatis 里無法復(fù)用。
事務(wù)管理器配合往往有坑。
JDBC Template、LambdaQuery、Mapper XML 全部共享同一套TypeHandler 機制、同一套Session 管理、同一套元數(shù)據(jù)映射。 在 dbVisitor 中,你可以在 Lambda 查詢中復(fù)用 Mapper 定義的 ResultMap,這種底層的一致性是簡單的拼湊無法比擬的。
3. 生態(tài)框架的無關(guān)性
這是 dbVisitor 區(qū)別于 Spring Data 或 MyBatis-Plus 的另一個重要特征。 dbVisitor 的核心不依賴 Spring,也不依賴任何 Web 容器。它基于純 Java (JDK 8+) 和 JDBC 標(biāo)準(zhǔn)構(gòu)建。 這意味著:
你可以在Spring Boot中用它。
你可以在Solon、Vert.x、Quarkus中用它。
你甚至可以在一個沒有任何依賴的 Main 方法控制臺程序中直接 new 出來使用它。
這種零耦合的特性,讓它不僅能適應(yīng)現(xiàn)有的各種技術(shù)棧,更能在未來的架構(gòu)演進(jìn)中保持生命力,不會被綁定在某個特定框架的戰(zhàn)車上。
結(jié)語
物理學(xué)告訴我們要敬畏差異,但軟件工程告訴我們要通過抽象來管理復(fù)雜。
dbVisitor 并不試圖用“大一統(tǒng)”去掩蓋數(shù)據(jù)庫的特性,而是通過提供一個統(tǒng)一的基座(JDBC Driver)和分層的 API 設(shè)計,讓開發(fā)者在簡單場景享受“大一統(tǒng)”的便利,在復(fù)雜場景擁有“原生級”的掌控。這就是 dbVisitor 敢于挑戰(zhàn)數(shù)據(jù)訪問“大一統(tǒng)”的底氣。
- 項目首頁:https://www.dbvisitor.net/
- 項目源碼:https://gitee.com/zycgit/dbvisitor
如果你對這個項目非常感興趣不妨 “加個關(guān)注” 及對我支持一下。
特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺“網(wǎng)易號”用戶上傳并發(fā)布,本平臺僅提供信息存儲服務(wù)。
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.