我有一个现有的mysql表,它使用mysql的UUID_SHORT()函数来生成唯一的ID。该表的简化版本:
CREATE TABLE `users` (
`user_uuid` bigint(20) unsigned NOT NULL,
`user_name` varchar(64) NOT NULL
);
将通过以下方式创建新用户:
INSERT INTO users (user_uuid, user_name) values (UUID_SHORT(), "new user name");
我开始使用gorm实现数据库模型,并且我在如何告诉gorm和数据库/ sql在创建新的User实例时调用UUID_SHORT()时写了一个空白。
来自model / users.go:
package model
type User struct {
UserUUID uint64 `gorm:"column:user_uuid;primary_key:yes";sql:"notnull;default:uuid_short"`
UserName string `sql:"notnull"`
}
func (user User) TableName() string {
return "users"
}
来自model / users_test.go:
package model_test
import (
"testing"
".../model"
".../model/testutil"
)
func TestUserCreate(t *testing.T) {
user := model.User{
// UserUUID: **HOW DO I CALL UUID_SHORT() HERE?**,
UserName: "Go Test",
}
// testutil.DB is the successful result of gorm.Open("mysql", ...)
testutil.DB.Create(&user)
}
如何在保存实例时为user_uuid列调用UUID_SHORT()?
答案 0 :(得分:3)
为了在UUID_SHORT()
调用中调用MySQL的model.User
,您似乎需要在到达testutil.DB.Create(&user)
之前对数据库进行额外的SQL调用在某些时候排队。
找到一种方法将gorm
用于MySQL UUID_SHORT()
调用本身可能会很好,但这可能最终需要更多的工作来映射单个行值(user_uuid
在这种情况下)用于model.User
(可能只需要struct
的UUID_SHORT()
。
因此,使用更简单的方法可能会有所帮助。以下代码是使用sql
package (特别是UUID_SHORT()
用户定义函数,在这种情况下如何找到get_uuid_short()
的基本(尽管可能很差*)示例):
package model_test
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
"github.com/jinzhu/gorm"
"github.com/stretchr/testify/assert"
"log"
"testing"
)
type User struct {
UserUUID uint64 `gorm:"column:user_uuid;primary_key:yes";sql:"notnull;default:uuid_short"`
UserName string `sql:"notnull"`
}
func (user User) TableName() string {
return "users"
}
func get_uuid_short() uint64 {
var uuid_short uint64
/* connect to db using `sql` package */
db, err := sql.Open("mysql", "username:password@tcp(127.0.0.1:3306)/uuid_test")
if err != nil {
log.Fatal(err)
}
/* select UUID_SHORT() */
rows, err := db.Query("select UUID_SHORT()")
if err != nil {
log.Fatal(err)
}
defer db.Close()
/* get value of uuid_short */
for rows.Next() {
err := rows.Scan(&uuid_short)
if err != nil {
log.Fatal(err)
}
}
return uuid_short
}
func TestUserCreate(t *testing.T) {
user := User{
UserUUID: get_uuid_short(), /* get next UUID_SHORT() value */
UserName: "Go Test",
}
db, err := gorm.Open("mysql", "username:password@/uuid_test?charset=utf8&parseTime=True&loc=Local")
db.Create(&user)
assert.Nil(t, err)
}
在MySQL表中有这样的结果:
mysql> select * from users;
+-------------------+-----------+
| user_uuid | user_name |
+-------------------+-----------+
| 24070794506141712 | Go Test |
| 24070794506141713 | Go Test |
| 24070794506141714 | Go Test |
+-------------------+-----------+
3 rows in set (0.00 sec)
*注意:此代码可能无法解决多个用户同时调用get_uuid_short()
的时间(尽管MySQL可能已经提供了处理此问题的方法)。