Golang SQL仓库层Rel:简洁(洋葱)架构实践指南

Golang SQL仓库层Rel:简洁(洋葱)架构实践指南 rel 是一个用于 Go 语言的类 ORM 库,旨在成为洋葱架构的存储库层。它是可测试的,并自带测试库。rel 还具有可扩展的查询构建器,允许您使用构建器或原生 SQL 编写查询。

指南:https://fs02.github.io/rel

GitHub GitHub

Fs02/rel

Fs02/rel

用于整洁(洋葱)架构的 Golang SQL 存储库层。 - Fs02/rel


更多关于Golang SQL仓库层Rel:简洁(洋葱)架构实践指南的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang SQL仓库层Rel:简洁(洋葱)架构实践指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在洋葱架构中,仓库层负责数据访问逻辑,而rel库为此提供了优雅的解决方案。以下是一个实践示例,展示如何定义模型、初始化仓库并执行查询:

package main

import (
    "context"
    "fmt"
    "github.com/Fs02/rel"
    "github.com/Fs02/rel/adapter/sqlite"
)

// 定义模型
type User struct {
    ID   int    `db:"id"`
    Name string `db:"name"`
}

func main() {
    // 初始化适配器
    adapter, _ := sqlite.Open(":memory:")
    defer adapter.Close()
    
    // 创建仓库
    repo := rel.New(adapter)
    
    // 自动迁移
    repo.Migrate(context.Background(), &User{})
    
    // 插入数据
    user := User{Name: "Alice"}
    repo.Insert(context.Background(), &user)
    
    // 查询构建器示例
    var users []User
    repo.FindAll(context.Background(), &users, rel.Where(rel.Eq("name", "Alice")))
    
    // 原生SQL查询
    repo.Query(context.Background(), &users, "SELECT * FROM users WHERE name = ?", "Alice")
    
    fmt.Printf("Found %d users\n", len(users))
}

rel的查询构建器支持链式调用:

// 复杂查询示例
repo.Find(context.Background(), &users,
    rel.Select("id", "name"),
    rel.Where(rel.And(
        rel.Gt("id", 1),
        rel.Like("name", "%A%"),
    )),
    rel.OrderBy("id"),
    rel.Limit(10),
)

测试支持通过reltest包实现:

package user_test

import (
    "testing"
    "github.com/Fs02/rel"
    "github.com/Fs02/rel/reltest"
)

func TestUserRepository(t *testing.T) {
    var (
        repo = reltest.New()
        user = User{ID: 1, Name: "Alice"}
    )
    
    // 模拟期望的查询
    repo.ExpectFind(rel.Eq("id", 1)).Result(user)
    
    // 执行测试逻辑
    // ...
    
    repo.AssertExpectations(t)
}

rel通过适配器模式支持多种数据库:

// PostgreSQL适配器
import "github.com/Fs02/rel/adapter/postgres"

adapter, _ := postgres.Open("postgres://user:pass@localhost/db")
repo := rel.New(adapter)

// MySQL适配器
import "github.com/Fs02/rel/adapter/mysql"

adapter, _ := mysql.Open("user:pass@/dbname")
repo := rel.New(adapter)

事务处理示例:

repo.Transaction(context.Background(), func(ctx context.Context) error {
    // 在事务中执行多个操作
    repo.Insert(ctx, &User{Name: "Bob"})
    repo.Update(ctx, &User{ID: 1, Name: "Alice Updated"})
    return nil
})

rel的设计确实符合洋葱架构原则,将数据访问逻辑隔离在仓库层,使业务逻辑保持独立于持久化细节。

回到顶部