Sam*_*ech 3 database struct go sqlx
我刚刚开始学习 Go 语言。我写了以下简单的程序。
在这里,我试图用所有书籍和相关作者填充结构。
Bookstruct 已嵌入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)
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我运行它时,它给出了以下错误
[samtech@sam sqlxapp]$ go run main.go
2016/02/11 18:45:46 Scan error: missing destination name name
exit status 1
Run Code Online (Sandbox Code Playgroud)
我在做什么错?
我还尝试将Book结构中的字段标记更改为
Bauther Auther `db:"auther,prefix=auth."`
Run Code Online (Sandbox Code Playgroud)
并将查询更改为
rows, err := db.Queryx("Select b.*, auth.name from books b left outer join authers auth on auth.ID=b.auther;")
Run Code Online (Sandbox Code Playgroud)
但它不会做任何改变。
编辑
经过几次尝试和错误,我终于让它工作了。
我必须稍微更改我创建的模型。我改变了 Book 结构
type Book struct {
ID int
Title string
Year int
Bauther Auther
}
Run Code Online (Sandbox Code Playgroud)
到
type Book struct {
ID int // Key
Title string
Year int
AutherID int `db:"auther"` // FKey
Auther
}
Run Code Online (Sandbox Code Playgroud)
现在,它运行良好。我做的错误是,我将Bauther字段添加为Auther. Sqlx 无法理解。但是当我添加Auther为匿名嵌入式结构时,问题解决了。
但它引入了另一个问题:)
由于 ID 字段存在Book于Auther两个结构中。现在 ScanStructBook.ID在所有行中填充0。
我能做些什么来避免它?
目前 sqlx 似乎不可能做到这一点。这有一个未解决的问题:https : //github.com/jmoiron/sqlx/issues/131
但是,您可以在不使用 sqlx 的情况下轻松做到这一点:
package main
import (
"database/sql"
"fmt"
"log"
"time"
_ "github.com/lib/pq"
)
type Book struct {
ID int
Title string
Year int
Bauther Auther
}
type Auther struct {
ID int
Name string
Dob time.Time
}
func main() {
db, err := sql.Open("postgres", "postgres://localhost/testdb?sslmode=disable")
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.Query("Select b.id, b.title, b.year, a.id, a.name, a.dob 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{}
if err := rows.Scan(&b.ID, &b.Title, &b.Year, &b.Bauther.ID, &b.Bauther.Name, &b.Bauther.Dob); err != nil {
log.Fatal(err)
}
books = append(books, b)
}
// print all books
for _, b := range books {
fmt.Printf("%v", b)
}
}
Run Code Online (Sandbox Code Playgroud)
基本上你必须在你的SELECT语句中明确你的列,这样你才能知道它们的顺序。然后,您创建结构并以与SELECT语句中的列相同的顺序扫描到每个元素。
| 归档时间: |
|
| 查看次数: |
5510 次 |
| 最近记录: |