gorm执行的不必要的查询,用于在数据库表中插入数据

问题描述 投票:2回答:1

我正在尝试使用golang和gorm在当前项目中创建新功能。

我在MySQL中具有以下数据库结构。

enter image description here

UserMaster表位于层次结构的顶部,其主键列被许多其他表引用,它们本身将其用作主列。 UserLogin表就是这样的表之一。这不是完美的数据库设计,但这是我将要处理的db结构,并且没有机会可以更改该结构。

以下是我在go中为UserMaster和UserLogin创建的模型类。>

type UserMaster struct {
    UserId      string    `gorm:"column:UserId;PRIMARY_KEY";size:20`
    CreatedDate time.Time `gorm:"column:CreatedDate"`
    IsActive    bool      `gorm:"column:IsActive"`
    UserLogin   UserLogin `gorm:"foreignkey:Id"`
}

type UserLogin struct {
    Id            string    `gorm:"column:Id;PRIMARY_KEY";size:20"`
    UserName      string    `gorm:"column:UserName;unique"`
    EmailId       string    `gorm:"column:EmailId;unique"`
    PasswordHash  string    `gorm:"column:PasswordHash"`
    PasswordSalt  string    `gorm:"column:PasswordSalt"`
    LastLoginDate time.Time `gorm:"column:LastLoginDate"`
}

func (UserMaster) TableName() string {
    return "usermaster"
}

func (UserLogin) TableName() string {
    return "userlogin"
}

我希望通过保存完全填充的UserMaster实例,通过gorm在UserMaster和UserLogin表中创建行。

以下是我为此编写的代码。

func main() {
    db, err := gorm.Open("mysql", "user:password@tcp(localhost:3306)/ormsample")

    if err != nil {
        panic("Failed to connect the database.")
    }

    defer db.Close()

    createNewUser(db, "[email protected]", "j;dfasdasdf")
}

func createNewUser(db *gorm.DB, emailId string, password string) UserMaster {
    userId := createUserId()

    newUser := &UserMaster{}
    newUser.UserId = userId
    newUser.CreatedDate = time.Now()
    newUser.UserLogin = UserLogin{}
    newUser.UserLogin.UserName = emailId
    newUser.UserLogin.EmailId = emailId
    newUser.UserLogin.PasswordHash = password
    newUser.UserLogin.PasswordSalt = "SomeSalt"

    db.Debug().Model(&newUser).Create(&newUser)

    return *newUser
}

func createUserId() string {
    uuidWithHyphen := uuid.New()
    uuid := strings.Replace(uuidWithHyphen.String(), "-", "", -1)

    return strings.ToUpper(uuid[:12])
}

整个过程按预期工作,这意味着它正在向UserMaster和UserLogin表插入记录。

问题是gorm执行此数据库操作的方式。以下是正在终端上记录的SQL查询(我在gorm db对象上使用Debug()函数)。

INSERT INTO `usermaster` (`UserId`,`CreatedDate`,`IsActive`) 
    VALUES ('1601F7E41E29','2020-03-22 22:24:08',false) 

UPDATE `userlogin` SET `UserName` = '[email protected]', 
  `EmailId` = '[email protected]', `PasswordHash` = 'j;dfasdasdf', 
  `PasswordSalt` = 'SomeSalt', `LastLoginDate` = '0000-00-00 00:00:00'  
  WHERE `userlogin`.`Id` = '1601F7E41E29'

SELECT * FROM `userlogin`  WHERE `userlogin`.`Id` = '1601F7E41E29' 
 ORDER BY `userlogin`.`Id` ASC LIMIT 1

INSERT INTO `userlogin` (`Id`,`UserName`,`EmailId`,`PasswordHash`,`PasswordSalt`,`LastLoginDate`)
VALUES ('1601F7E41E29','[email protected]','[email protected]',
 'j;dfasdasdf','SomeSalt','0000-00-00 00:00:00')

正如您在上面注意到的,gorm执行2个INSERT,1个UPDATE和1个SELECT查询以插入到两个表中,而只应执行2个INSERT查询。

我在golang和gorm的各种论坛上进行了很多搜索,但没有发现任何可以解释这种现象的东西。

非常感谢您提供帮助/指导/指导来解决此问题。

我正在尝试使用golang和gorm在当前项目中创建新功能。我在MySQL中具有以下数据库结构。 UserMaster表位于层次结构的顶部,其主要层次是...

go gorm gorm-mysql
1个回答
0
投票

同时使用Model(&user)Create(&user)可能会造成问题。Model()主要在更新现有数据之前使用,这可能会导致额外的查询。对于仅创建,您可以尝试]

© www.soinside.com 2019 - 2024. All rights reserved.