backend/pkg/library/cassandra/README.md

159 lines
3.6 KiB
Markdown
Raw Normal View History

2025-11-18 09:45:38 +00:00
# Cassandra2 - 新一代 Cassandra 客戶端
Cassandra2 是重新設計的 Cassandra 客戶端,提供更簡潔的 API、更好的類型安全性和更清晰的架構。
## 特色
-**Repository 模式**:每個 Repository 綁定一個 keyspace無需到處傳遞
-**類型安全**:使用泛型,編譯期類型檢查
-**簡潔的 API**:統一的查詢介面,流暢的鏈式調用
-**符合 cursor.md 原則**:小介面、依賴注入、顯式錯誤處理
## 快速開始
### 1. 初始化
```go
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. 定義資料模型
```go
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
```go
// 獲取 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
```go
// 條件查詢
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 操作
```go
batch := repo.Batch(ctx)
batch.Insert(user1).
Insert(user2).
Update(user3)
err = batch.Commit(ctx)
```
### 6. Transaction 操作
```go
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)
```go
db.Insert(ctx, user, "keyspace")
db.Model(ctx, &User{}, "keyspace").Where(...).Scan(&result)
```
### 新 API (Cassandra 2)
```go
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` - 技術設計文檔