Я пробую свои силы на golang и gorm для создания новой функции в моем текущем проекте.
У меня следующая структура базы данных в MySQL.
![enter image description here](https://i.stack.imgur.com/CZnlc.png)
UserMaster Таблица находится на вершине иерархии, а ее столбец первичного ключа используется многими другими таблицами, и они сами используйте его в качестве основных столбцов. UserLogin таблица является одной из таких таблиц. Это не идеальный дизайн базы данных, но это структура базы данных, над которой я буду работать, и нет никаких шансов, что структура может быть изменена.
Ниже приведены классы моделей, которые я создал для UserMaster и UserLogin в go.
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"
}
Я хочу sh создать строки в таблицах UserMaster и UserLogin с помощью gorm, просто сохранив полностью заполненный экземпляр UserMaster.
Ниже приведен код Я написал для этого.
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, "someuser009@yopmail.com", "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.
Проблема заключается в том, как Горм выполняет это работа с базой данных. Далее следуют запросы SQL, регистрируемые терминалом (поскольку я использую функцию Debug()
для объекта gorm db).
INSERT INTO `usermaster` (`UserId`,`CreatedDate`,`IsActive`)
VALUES ('1601F7E41E29','2020-03-22 22:24:08',false)
UPDATE `userlogin` SET `UserName` = 'someuser009@yopmail.com',
`EmailId` = 'someuser009@yopmail.com', `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','someuser009@yopmail.com','someuser009@yopmail.com',
'j;dfasdasdf','SomeSalt','0000-00-00 00:00:00')
Как вы заметили выше, gorm выполняет 2 запроса INSERT, 1 UPDATE и 1 SELECT. вставить в две таблицы, в то время как должно быть выполнено только 2 INSERT-запроса.
Я много искал об этом на различных форумах golang и gorm, но не нашел ничего, что могло бы объяснить это поведение.
Любая помощь / руководство / направление для решения этой проблемы будет принята с благодарностью.