backend/pkg/library/cassandra/README.md

3.6 KiB
Raw Blame History

Cassandra2 - 新一代 Cassandra 客戶端

Cassandra2 是重新設計的 Cassandra 客戶端,提供更簡潔的 API、更好的類型安全性和更清晰的架構。

特色

  • Repository 模式:每個 Repository 綁定一個 keyspace無需到處傳遞
  • 類型安全:使用泛型,編譯期類型檢查
  • 簡潔的 API:統一的查詢介面,流暢的鏈式調用
  • 符合 cursor.md 原則:小介面、依賴注入、顯式錯誤處理

快速開始

1. 初始化

import "your-module/pkg/library/cassandra"

// 創建 DB 連接
db, err := cassandra2.New(
    cassandra2.WithHosts("localhost"),
    cassandra2.WithKeyspace("my_keyspace"),
    cassandra2.WithPort(9042),
)
if err != nil {
    log.Fatal(err)
}
defer db.Close()

2. 定義資料模型

type User struct {
    ID        gocql.UUID `db:"id" partition_key:"true"`
    Name      string     `db:"name"`
    Email     string     `db:"email"`
    CreatedAt time.Time  `db:"created_at"`
}

func (u User) TableName() string {
    return "users"
}

3. 使用 Repository

// 獲取 Repository
repo, err := db.Repository[User]("my_keyspace")

// 插入
user := User{
    ID:        gocql.TimeUUID(),
    Name:      "Alice",
    Email:     "alice@example.com",
    CreatedAt: time.Now(),
}
err = repo.Insert(ctx, user)

// 查詢
var result User
result, err = repo.Get(ctx, user.ID)

// 更新
user.Email = "newemail@example.com"
err = repo.Update(ctx, user)

// 刪除
err = repo.Delete(ctx, user.ID)

4. 使用 Query Builder

// 條件查詢
var users []User
err = repo.Query().
    Where(cassandra2.Eq("status", "active")).
    OrderBy("created_at", cassandra2.DESC).
    Limit(10).
    Scan(ctx, &users)

// 單筆查詢
user, err := repo.Query().
    Where(cassandra2.Eq("id", userID)).
    One(ctx)

// 計數
count, err := repo.Query().
    Where(cassandra2.Eq("status", "active")).
    Count(ctx)

5. Batch 操作

batch := repo.Batch(ctx)
batch.Insert(user1).
    Insert(user2).
    Update(user3)
err = batch.Commit(ctx)

6. Transaction 操作

tx := db.Begin(ctx, "my_keyspace")
tx.Insert(user1)
tx.Update(user2)
if err := tx.Commit(ctx); err != nil {
    tx.Rollback(ctx)
}

API 對比

舊 API (Cassandra 1)

db.Insert(ctx, user, "keyspace")
db.Model(ctx, &User{}, "keyspace").Where(...).Scan(&result)

新 API (Cassandra 2)

repo := db.Repository[User]("keyspace")
repo.Insert(ctx, user)
repo.Query().Where(...).Scan(ctx, &result)

主要改進

  1. 移除 keyspace 參數Repository 綁定 keyspace無需重複傳遞
  2. 類型安全:使用泛型,編譯期檢查
  3. 統一 API:只有一套查詢介面
  4. 更好的錯誤處理:統一的錯誤類型,支援 errors.Is/As

注意事項

  1. 主鍵查詢Get 方法需要完整的 Primary Key。如果是多欄位主鍵需要傳入包含所有主鍵欄位的 struct。
  2. 更新行為Update 預設只更新非零值欄位,使用 UpdateAll 可更新所有欄位。
  3. Transaction:這是補償式交易,不是真正的 ACID 交易,適用於最終一致性場景。

遷移指南

從 Cassandra 1 遷移到 Cassandra 2

  1. cassandra.NewCassandraDB 改為 cassandra2.New
  2. db.Insert(ctx, doc, keyspace) 改為 repo.Insert(ctx, doc),其中 repo = db.Repository[Type](keyspace)
  3. db.Model(...) 改為 repo.Query()
  4. 更新錯誤處理:使用 cassandra2.IsNotFound 等函數

文檔

詳細的技術設計請參考:

  • REFACTORING_PLAN.md - 重構計畫
  • TECHNICAL_DESIGN.md - 技術設計文檔