我刚开始学习Go语言。
我写了下面这个简单的程序。
在这里,我试图用所有书籍和相关作者填充结构体。
Book
结构体嵌入了 Author
结构体。
package main
import (
"fmt"
"log"
"time"
"github.com/jmoiron/sqlx"
_ "github.com/lib/pq"
)
type Book struct {
ID int
Title string
Year int
Bauther Auther `db:"auther"`
}
type Auther struct {
ID int
Name string
Dob time.Time
}
func main() {
db, err := sqlx.Open("postgres", "host=localhost user=testuser dbname=testdb password=testuser")
if err != nil {
log.Fatal("DB Conn error: ", err)
}
if err = db.Ping(); err != nil {
log.Fatal("DB Ping error: ", err)
}
defer db.Close()
rows, err := db.Queryx("Select b.*, a.name from books b left outer join authers a on a.ID=b.auther;")
if err != nil {
log.Fatal("DB Query error: ", err)
}
defer rows.Close()
var books []*Book
for rows.Next() {
var b = &Book{}
err := rows.StructScan(b)
if err != nil {
log.Fatal("Scan error: ", err)
}
books = append(books, b)
}
// print all books
for _, b := range books {
fmt.Printf("%v", b)
}
}
但是当我运行它时,会出现以下错误。
[samtech@sam sqlxapp]$ go run main.go
2016/02/11 18:45:46 Scan error: missing destination name name
exit status 1
我做错了什么?
我还尝试将Book
结构体中的字段标签更改为
Bauther Auther `db:"auther,prefix=auth."`
并将查询更改为
rows, err := db.Queryx("Select b.*, auth.name from books b left outer join authers auth on auth.ID=b.auther;")
但这并没有产生任何变化。
编辑
经过多次尝试和错误,最终我让它工作了。
我不得不略微更改我创建的模型。我将Book结构体从
type Book struct {
ID int
Title string
Year int
Bauther Auther
}
to
type Book struct {
ID int // Key
Title string
Year int
AutherID int `db:"auther"` // FKey
Auther
}
现在,它工作得很好。我的错误在于将
Bauther
字段添加为 Auther
。Sqlx 不能理解它。但是当我将 Auther
添加为匿名嵌入式结构时,问题得到了解决。但是它引入了另一个问题 :)
由于 ID 字段存在于 Book 和 Auther 中的两个结构体中,因此 ScanStruct 在所有行中都使用 0 填充 Book.ID。
有什么方法可以避免这种情况吗?