傳統 ORM 框架(Hibernate、MyBatis)雖成熟,但配置繁瑣、學習曲線陡峭、且易產生 N+1 查詢等效能問題。Java 8 引入 Stream API 後,Speedment 等新型 ORM 應運而生,讓開發者能用標準 Java 流語法直接操作資料庫,實現「代碼即查詢」,大幅提升開發效率與可讀性。
Stream<Entity> 進行中間/終端操作。mysql> explain hare; +-------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(45) | NO | | NULL | | | color | varchar(45) | NO | | NULL | | | age | int(11) | NO | | NULL | | +-------+-------------+------+-----+---------+----------------+
public interface Hare extends Entity<Hare> {
// 靜態欄位引用,支援類型安全查詢
ReferenceComparableField<Hare, Integer> ID = ...;
ReferenceComparableStringField<Hare> NAME = ...;
ReferenceComparableStringField<Hare> COLOR = ...;
ReferenceComparableField<Hare, Integer> AGE = ...;
// Getter/Setter
Integer getId(); Hare setId(Integer id);
String getName(); Hare setName(String name);
String getColor(); Hare setColor(String color);
Integer getAge(); Hare setAge(Integer age);
// 關聯導航(替代 JOIN)
Stream<Carrot> findCarrotsByOwner();
Stream<Carrot> findCarrotsByRival();
Stream<Carrot> findCarrots();
}
// 1. 查詢年齡 > 8 的兔子
List<Hare> oldHares = hareManager.stream()
.filter(Hare.AGE.greaterThan(8))
.collect(Collectors.toList());
// 2. 統計年齡 > 8 的兔子數量(自動優化為 SELECT COUNT(*))
long count = hareManager.stream()
.filter(Hare.AGE.greaterThan(8))
.count();
// 3. 複雜管道:篩選 → 投影 → 排序 → 統計(自動優化,不載入完整物件)
long noOldHares = hareManager.stream()
.filter(Hare.AGE.greaterThan(8))
.mapToInt(Hare::getAge)
.sorted()
.count(); // 等價於 SELECT COUNT(*) FROM hare WHERE age > 8
// 4. 分頁查詢
List<Hare> page = hareManager.stream()
.sorted(Hare.NAME.comparator())
.skip(20)
.limit(10)
.collect(toList());
filter、map、sorted)構建邏輯計劃,不執行查詢。collect、count、findFirst)觸發 SQL 生成與執行。Predicate、消除無效操作(如 count() 前的 sorted()、mapToInt()),生成最優 SQL。| 流操作 | 生成 SQL |
|---|---|
.filter(AGE.gt(8)).collect(toList()) | SELECT * FROM hare WHERE age > 8 |
.filter(AGE.gt(8)).count() | SELECT COUNT(*) FROM hare WHERE age > 8 |
.filter(AGE.gt(8)).mapToInt(Hare::getAge).sorted().count() | SELECT COUNT(*) FROM hare WHERE age > 8 (消除排序/投影) |
.sorted(NAME).skip(20).limit(10) | SELECT * FROM hare ORDER BY name LIMIT 10 OFFSET 20 |
| 分類 | 方法 | 說明 |
|---|---|---|
| 中間操作 | filter(Predicate) | 篩選,支援欄位引用 Hare.AGE.greaterThan(8) |
map(Function) / mapToInt 等 | 轉換/投影 | |
sorted() / sorted(Comparator) | 排序,支援欄位 Hare.NAME.comparator() | |
skip(long) / limit(long) | 分頁 | |
distinct() | 去重 | |
peek(Consumer) | 側效調試 | |
| 終端操作 | collect(Collector) | 收集為 List/Set/Map |
count() | 統計 | |
findFirst() / findAny() | 查找單筆 | |
forEach(Consumer) | 遍歷消費 | |
reduce() | 聚合 |
// 獲取兔子擁有的胡蘿蔔流(自動處理關聯)
Stream<Carrot> carrots = hare.findCarrotsByOwner();
// 結合主流查詢:名字以 "B" 開頭的兔子,及其擁有的紅色胡蘿蔔
hareManager.stream()
.filter(Hare.NAME.startsWith("B"))
.flatMap(h -> h.findCarrotsByOwner().filter(Carrot.COLOR.equal("Red")))
.forEach(System.out::println);
Speedment.transaction(() -> { ... }) 或手動 Transaction API。speedment.json。CacheManager),減少熱點查詢壓力。persist()、update()、remove() 支援批次提交。RawStream 執行原生 SQL 並映射實體。Speedment 以 Java 8 Stream 為核心抽象,實現了類型安全、零 SQL、自動優化、代碼生成的現代化資料存取體驗。對於綠地項目或微服務新模組,極大降低 ORM 學習與維護成本;對於存量系統,可作為新功能模組的輕量級選擇漸進式引入。核心優勢在於讓開發者專注業務邏輯,而非 SQL 與映射細節。