在日常開發中,我們經常需要對對象集合進行篩選、投影、排序等操作,這與 SQL 對關係表的 SELECT 操作極其相似。本文介紹一種通用機制,讓開發者能在 Java 對象數組或 Collection 上直接使用類 SQL 的查詢語義,實現屬性選擇、條件過濾、結果排序,且不修改原始數據源。
整個機制由七個核心接口/類組成,各司其職:
| 組件 | 職責 |
|---|---|
Invoker | 封裝方法調用,單一方法 boolean invoke(Object o),用於提取對象屬性值 |
Condition | 封裝過濾邏輯,單一方法 boolean passes(Object o),判斷對象是否滿足條件 |
SelectInstruction | 對應 SELECT 子句中的單個列,包含列名與 Invoker,數組形式構成完整投影列表 |
OrderInstruction | 對應 ORDER BY 子句單項,包含 Invoker(提取排序鍵)與 Comparator(比較策略),數組順序決定優先級 |
SelectStatement | 封裝完整查詢語句:數據源、投影列表、條件列表、排序列表 |
Executor | 執行引擎,接收 SelectStatement 並返回 ResultTable |
ResultTable | 結果集容器,內部以 Object[][] 存儲,便於轉換顯示 |
Collection)SelectInstruction[] 指定輸出列及別名Condition[] 表達 WHERE 條件OrderInstruction[] 表達 ORDER BY 排序規則SelectStatementExecutor.execute(statement) 獲取 ResultTable每個 SelectInstruction 綁定一個 Invoker,執行時對源對象逐個調用,返回值作為該列單元格值。若列名為 *,則自動包裝該類所有 getter 方法。
Condition 接口將業務規則與查詢引擎分離,開發者只需實現 passes() 即可表達任意複雜條件。無條件時傳入空數組。
OrderInstruction 組合 Invoker 與 Comparator,若無自定義比較器則回退至 Comparable 自然順序。數組順序即優先級順序。
雖然機制基於通用接口靈活強大,但濫用可能導致代碼難以維護。建議在報表導出、動態查詢界面、臨時數據分析等場景使用;核心業務邏輯仍推薦使用 Stream API 或專用查詢庫(如 JSQLParser、QueryDSL)以獲得類型安全與 IDE 支持。