Golang中实体与存储库的实现

Golang中实体与存储库的实现 你好,

我设计了一个依赖于数据库实体和仓库的应用程序,如下所示。然而,我不确定我的设计在 Go 语言中是否是可接受的?

谢谢

用法

repo := repository{// db goes here}
.... := repo.findOneByID(// uuid goes here)
.... := repo.insert(// entity goes here)

entity.go

package user

type entity struct {
	uuid string
	name string
}

repository.go

package user

type repository struct {
	db *sql.DB
}

func (r repository) findOneByID(id string) (*entity, err) {
	// Execute `SELECT` query here
	// ...
	return entity, err
}

func (r repository) insert(e *entity) (string, error) {
	// Execute `INSERT` query here
	// ...
	return uuid, err
}

更多关于Golang中实体与存储库的实现的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

在我看来这没问题。我不会返回一个指向实体的指针。它非常小巧轻量,你可以直接返回实体值。

更多关于Golang中实体与存储库的实现的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这是一个在Go中实现实体和存储库的常见模式,但有几个地方可以改进以符合Go的惯用写法:

1. 导出类型和方法 在Go中,只有导出的标识符(首字母大写)才能被其他包访问。你的实体和存储库应该被导出:

// entity.go
package user

type Entity struct {
    UUID string
    Name string
}
// repository.go
package user

type Repository struct {
    db *sql.DB
}

func (r *Repository) FindOneByID(id string) (*Entity, error) {
    var entity Entity
    err := r.db.QueryRow("SELECT uuid, name FROM users WHERE uuid = $1", id).
        Scan(&entity.UUID, &entity.Name)
    if err != nil {
        return nil, err
    }
    return &entity, nil
}

func (r *Repository) Insert(e *Entity) error {
    _, err := r.db.Exec("INSERT INTO users (uuid, name) VALUES ($1, $2)", 
        e.UUID, e.Name)
    return err
}

2. 使用指针接收器 对于会修改接收器状态的方法,应该使用指针接收器:

func (r *Repository) Update(e *Entity) error {
    _, err := r.db.Exec("UPDATE users SET name = $1 WHERE uuid = $2",
        e.Name, e.UUID)
    return err
}

3. 添加构造函数 提供一个构造函数来初始化Repository:

func NewRepository(db *sql.DB) *Repository {
    return &Repository{db: db}
}

4. 使用接口(可选) 为了更好的可测试性和抽象,可以定义接口:

type UserRepository interface {
    FindOneByID(id string) (*Entity, error)
    Insert(e *Entity) error
    Update(e *Entity) error
    Delete(id string) error
}

使用示例:

// 初始化
db, _ := sql.Open("postgres", "connection_string")
repo := user.NewRepository(db)

// 创建实体
user := &user.Entity{
    UUID: "123e4567-e89b-12d3-a456-426614174000",
    Name: "John Doe",
}

// 插入
err := repo.Insert(user)
if err != nil {
    log.Fatal(err)
}

// 查询
foundUser, err := repo.FindOneByID(user.UUID)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Found user: %+v\n", foundUser)

这个设计在Go社区中是常见的,特别是对于需要与数据库交互的应用程序。关键点是确保类型的可导出性、使用指针接收器进行状态修改,以及考虑添加接口以便于测试和实现替换。

回到顶部