1
go1.15
gf master
orm中的ScanList功能,在复杂情况下会失效
示例代码:
// 多个用户,每个用户有多本书,每本书有一个出版社信息
//出版社
type PublishingHouse struct {
Id int `json:"id"`
}
type Book struct {
Id int `json:"id"`
Name string `json:"name"`
UserId int `json:"user_id"`
CreateAt *gtime.Time `json:"created_at"`
PublishingHouse PublishingHouse `json:"publishing_house"` //如果去掉这一属性能赋值成功,但实际在多层嵌套时,中间一些层,基本上都会是这样的形式
}
type User struct {
Id int `json:"id"`
Nickname string `json:"nickname"`
CreateAt *gtime.Time `json:"created_at"`
}
type UserEntity struct {
User
Books []Book `json:"books"`
}
func createTableUser() string {
db := g.Database()
db.SetDebug(true)
tableName := "users_" + gconv.String(gtime.Now().Nanosecond())
if _, err := db.Exec(fmt.Sprintf(`
CREATE TABLE %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
nickname varchar(45) NULL,
created_at datetime NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableName,
)); err != nil {
gtest.Fatal(err)
}
return tableName
}
func createTableBook() string {
db := g.Database()
db.SetDebug(true)
tableName := "books_" + gconv.String(gtime.Now().Nanosecond())
if _, err := db.Exec(fmt.Sprintf(`
CREATE TABLE %s (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
name varchar(45) NULL,
user_id int(10) NULL,
created_at datetime NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`, tableName,
)); err != nil {
gtest.Fatal(err)
}
return tableName
}
func fillData(tableName1 string, tableName2 string) {
db := g.Database()
for i := 0; i < 5; i++ {
user := &User{
Nickname: "张" + gconv.String(i),
}
if rs, err := db.Table(tableName1).Save(user); err == nil {
rsLid, _ := rs.LastInsertId()
for j := 0; j < 3; j++ {
book := &Book{
Name: "书" + gconv.String(j),
UserId: gconv.Int(rsLid),
}
db.Table(tableName2).Save(book)
}
}
}
}
// 删除表
func dropTable(table []string) {
db := g.Database()
for _, v := range table {
if _, err := db.Exec(fmt.Sprintf("DROP TABLE IF EXISTS `%s`", v)); err != nil {
gtest.Error(err)
}
}
}
func TestScanList(t *testing.T) {
userName := createTableUser()
bookName := createTableBook()
fillData(userName, bookName)
db := g.Database()
var entity []UserEntity
_ = db.Table(userName).Structs(&entity)
_ = db.Table(bookName).Where("user_id", gdb.ListItemValuesUnique(&entity, "Id")).
ScanList(&entity, "Books", "User", "user_id:Id")
dropTable([]string{userName, bookName})
for _, v := range entity {
if v.Books == nil {
g.Dump("err!")
} else {
g.Dump("ok!")
}
}
g.Dump("done!")
}