为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 gorm 从数据库返回新创建的记录

如何使用 gorm 从数据库返回新创建的记录

Go
不负相思意 2022-12-26 16:23:34
我有一个创建新用户的函数,但是获取用户值的推荐方法不包括数据库创建的自动生成的值(id,created_at)type User struct {    Id         string `json:"id" gorm:"primaryKey"`    Email      string `json:"email"`    Password   string `json:"password"`    Created_At string `json:"created_at"`    Updated_At string `json:"updated_at"`    Deleted_At string `json:"deleted_at"`}type UserRequest struct {    Email    string `json:"email"`    Password string `json:"password"`}func CreateUserRepo(newUser UserRequest) (*User, error) {    user := User{Email: newUser.Email, Password: newUser.Password}    fmt.Println(user)    result := services.PostgresSQLDB.Select("Email", "Password").Create(&user)    fmt.Println(result.RowsAffected)    if result.Error != nil {        modules.Logger.Error(result.Error)        return nil, result.Error    }    return &user, nil}你可以看到我为 id 和 created_at 得到了一个空字符串,尽管这些值是由我的数据库自动生成的。{    "id": "",    "email": "test@test.com",    "password": "password",    "created_at": "",    "updated_at": "",    "deleted_at": ""}
查看完整描述

2 回答

?
郎朗坤

TA贡献1921条经验 获得超9个赞

我终于在不包含的情况下找到了答案。


添加默认的 return 子句,返回所有新创建的值。 https://gorm.io/docs/update.html#Returning-Data-From-Modified-Rows


Clauses.(clause.Returning{})

模型.go


type User struct {

    ID        uuid.UUID      `json:"id" gorm:"primaryKey:type:uuid"`

    Email     string         `json:"email"`

    Password  string         `json:"password"`

    CreatedAt time.Time      `json:"created_at"`

    UpdatedAt time.Time      `json:"updated_at"`

    DeletedAt gorm.DeletedAt `json:"deleted_at"`

}

存储库.go


func CreateUserRepo(newUser UserRequest) (*User, error) {


    hash, errHash := modules.HashPassword(newUser.Password)


    if errHash != nil {

        return nil, errHash

    }


    user := User{Email: newUser.Email, Password: *hash}

    result := services.PostgresSQLDB.Clauses(clause.Returning{}).Select("Email", "Password").Create(&user)

    fmt.Println(result.RowsAffected)

    fmt.Println(&user)


    if result.Error != nil {

        modules.Logger.Error(result.Error)

        return nil, result.Error

    }


    return &user, nil


}


查看完整回答
反对 回复 2022-12-26
?
慕神8447489

TA贡献1780条经验 获得超1个赞

据我所知,GORM 不支持任何其他的主键整数自动递增。BeforeCreate因此,要么将其保留在 PostgreSQL 端(就像您所做的那样),要么在创建对象(使用钩子)之前在 Go 中生成自己的 UUID 。


另外,gorm.Model定义如下:


type Model struct {

  ID        uint           `gorm:"primaryKey"`

  CreatedAt time.Time

  UpdatedAt time.Time

  DeletedAt gorm.DeletedAt `gorm:"index"`

}

您不必使用它,但如果不需要,请添加gorm:"primaryKey"到您的主键字段。默认情况下主字段有自动递增,对于你的情况,我建议用禁用它autoIncrement:false。


type User struct {

    Id        uuid.UUID      `gorm:"primaryKey;autoIncrement:false" json:"id"`

    Email     string         `json:"email"`

    Password  string         `json:"password"`

}

当您让 PostgreSQL 处理默认值(而不是 GORM)时,您必须再次查询该对象才能访问您的idUUID 和created_atTIMESTAMP。


另请注意,您可以GormValuerInterface在创建时使用 SQL Expr。但是您仍然需要再次查询您的记录。( https://gorm.io/docs/data_types.html#GormValuerInterface )


如果您有兴趣在 Go 端处理所有问题,这里有一个带和不带gorm.Model.


package main


import (

    "fmt"

    "time"


    "github.com/google/uuid"

    "gorm.io/driver/sqlite"

    "gorm.io/gorm"

)


var DB *gorm.DB


type User struct {

    UUID      uuid.UUID `gorm:"primaryKey;autoIncrement:false"`

    Name      string

    CreatedAt time.Time

}


type UserWithGormModel struct {

    gorm.Model

    UUID uuid.UUID `gorm:"primaryKey;autoIncrement:false"`

    Name string

}


func (u *User) BeforeCreate(tx *gorm.DB) (err error) {


    // This is an example, refer to https://pkg.go.dev/github.com/google/UUID for good usage

    u.UUID = uuid.New()


    u.CreatedAt = time.Now()


    return

}


func (u *UserWithGormModel) BeforeCreate(tx *gorm.DB) (err error) {


    // This is an example, refer to https://pkg.go.dev/github.com/google/UUID for good usage

    u.UUID = uuid.New()


    return

}


func ConnectDatabase() {


    database, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})

    if err != nil {

        panic("failed to connect database")

    }


    if err != nil {

        panic("Failed to connect to database!")

    }


    database.AutoMigrate(&User{}, &UserWithGormModel{})


    DB = database

}


func main() {

    ConnectDatabase()


    user := User{Name: "Bob"}

    DB.Create(&user)

    fmt.Printf("User{UUID: %s, User.Name: %s, CreatedAt: %s}\n", user.UUID, user.Name, user.CreatedAt)


    user2 := UserWithGormModel{Name: "John"}

    DB.Create(&user2)

    fmt.Printf("UserWithGormModel{UUID: %s, Name: %s, CreatedAt: %s}\n", user2.UUID, user2.Name, user2.CreatedAt)

}

输出:


User{UUID: 8551636a-540f-4733-8179-3f0cc45daf4f, User.Name: Bob, CreatedAt: 2022-06-28 11:40:10.9225724 +0200 CEST}

UserWithGormModel{UUID: 2a6f94bd-a42b-4316-90be-0e93ea5091a6, Name: John, CreatedAt: 2022-06-28 11:40:10.9318004 +0200 CEST}



查看完整回答
反对 回复 2022-12-26
  • 2 回答
  • 0 关注
  • 221 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信