gorm:分离数据库内存储模型和查询发送模型

7lrncoxx  于 2022-12-07  发布在  Go
关注(0)|答案(1)|浏览(141)

什么是发送一个gorm模型的有效方法,该模型与用于在数据库中存储数据的gorm模型不相同?
Post模型(结构)用于在DB中存储数据。

type Post struct {
    gorm.Model
    Title string 
    Body  string 
}

但我想使用这个PostRead gorm模型,将其发送回用户。因为稍后可能会有额外的变量添加到此模型中,这些变量不会存储在此数据库中。(或者额外的变量可能来自其他服务或数据库)

type PostRead struct {
    ID    string `json:"id" gorm:"primary_key"`
    Title string `json:"title"`
    Body  string `json:"body"`
    CreatedAt time.Time `json:"createAt"`
    UpdatedAt time.Time `json:"updatedAt"`
    ...
    <other variables to be added later>
}

以下是我当前的控制器代码,用于发送数据:

func PostGetAll(c *gin.Context) {
    posts, err := services.PostGetAllService()

    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": err})
        return
    }

    c.JSON(http.StatusOK, gin.H{"posts": posts})
}

这里是我的服务代码,从数据库中获取数据:

func PostGetAllService() ([]models.Post, error) {
    var posts []models.Post
    result := initializers.DB.Find(&posts)

    if result.Error != nil {
        return nil, errors.New(result.Error.Error())
    }

    return posts, nil
}

注意:我知道我可以在控制器函数PostGetAll()中创建一个PostRead的SliceArray,然后使用append()将来自帖子(Post)的数据添加到SliceArray中。但对我来说,这似乎是解决这个问题的丰富方法,因此我想知道是否存在更好的解决方案?
更高效的解决方案

slmsl1lt

slmsl1lt1#

我不完全确定你的问题,但还是让我来帮你吧。
通常我会这样做,但我相信有更好的方法来做。
对于模型,我将准备他们在一个像下面这样的pkg。

// For reading data from form.
type CreatePostForm struct {
    Title string `json:"title"`
    Body  string `json:"body"`
}

// For interactions with database.
type Post struct {
    gorm.Model
    Title string 
    Body  string
}

type Posts []Post

// For data transfer object (sending over to UI etc).
type PostDto struct {
    Title       string 
    Body        string
    CreatedDate time.Time
    CreatedBy   string
}

type PostsDto []PostDto

// Convert form data into database model for database operations.
func (p PostCreateForm) ToCreateModel() (*Post, error) {
    // Process logic here which is basically creating a new Post model and returning it..
}

// Convert database model into DTO to reply to request etc.
func (p Post) ToDto() (*PostDto, error) {
    // Process logic here which is basically creating a new PostDto model and returning it..
}

// Convert many Posts to many DTOs.
func (ps Posts) ToDto() PostsDto {
    dtos := make(PostsDto, len(ps))
    for key, post := range ps {
        dtos[key] = post.ToDto()
    }

    return dtos
}

从数据库中获取数据后,基本上可以通过使用Posts.ToDto()等方法将Posts类型转换为PostsDto类型。
DB适配器将位于另一个pkg中,该pkg基本上负责阅读/写入数据库的工作,我不会与您分享,因为您的问题更多的是发送另一组数据进行CRUD操作。
再次,我希望这将帮助你,但我仍然认为可能有一个更好的方法来做。

相关问题