replace variables with structs queriing with golang

huangapple go评论82阅读模式
英文:

replace variables with structs queriing with golang

问题

我有一个可以工作的代码片段:

db, err := sql.Open("mysql", "pwd@tcp(ip:port)/db")
if err != nil {
	panic(err.Error())
}
rows, err := db.Query("select username from users")
if err != nil {
	panic(err.Error())
}
var (
	username string
)
for rows.Next() {
	err = rows.Scan(
		&name,
	)
	if err != nil {
		panic(err)
	}
	fmt.Println(username)
}

但是,...是否可以用结构体替代以下代码段:

var (
	username string
)

err = rows.Scan(
	&name,
)

我问这个问题是因为每次我想添加新字段时,我需要:

  • 在查询中添加字段
  • 在"var"块中创建新变量
  • 将变量添加到扫描中

我可以定义一个结构体并在一个地方更新字段吗?或者,...有一些最佳实践来构建查询和提取数据吗?

英文:

I've this snippet of code that works:

db, err := sql.Open("mysql", "pwd@tcp(ip:port)/db")
if err != nil {
	panic(err.Error())
}
rows, err := db.Query("select username from users")
if err != nil {
	panic(err.Error())
}
var (
	username string
)
for rows.Next() {
	err = rows.Scan(
		&name,
	)
	if err != nil {
		panic(err)
	}
	fmt.Println(username)
}

But, ... is it possible to substitute

var (
	username string
)

and
err = rows.Scan(
&name,
)

with a struct?

I ask this because every time I want to add new field I need to

  • add field inside the query
  • create new variable in "var" block
  • add variable to scan

May I define a struct and update fields in just one place? Or, ... are there some best practice to build queries and fetch them?

答案1

得分: 2

你可以这样做:

type user struct {
	Name  string
	Pass  string
	Email string
	Age   int
}

func main() {
	db, err := sql.Open("mysql", "pwd@tcp(ip:port)/db")
	if err != nil {
		panic(err.Error())
	}
	rows, err := db.Query("select user, pass, email, age from users")
	if err != nil {
		panic(err.Error())
	}
	var (
		users []user
	)
	for rows.Next() {
		u := user{}
		err = rows.Scan(
			&u.Name, &u.Pass, &u.Email, &u.Age,
		)
		if err != nil {
			panic(err)
		}

		users = append(users, u)
	}
	fmt.Println(users)
}

希望对你有帮助!

英文:

You can do something like this:

type user struct {
	Name  string
	Pass  string
	Email string
	Age   int
}

func main() {
	db, err := sql.Open("mysql", "pwd@tcp(ip:port)/db")
	if err != nil {
		panic(err.Error())
	}
	rows, err := db.Query("select user, pass, email, age from users")
	if err != nil {
		panic(err.Error())
	}
	var (
		users []user
	)
	for rows.Next() {
		u := user{}
		err = rows.Scan(
			&u.Name, &u.Pass, &u.Email, &u.Age,
		)
		if err != nil {
			panic(err)
		}

		users = append(users, u)
	}
	fmt.Println(users)
}

答案2

得分: 1

如果你愿意使用一个库,https://github.com/jmoiron/sqlx 是非常适合这个任务的。

place := Place{}
rows, err := db.Queryx("SELECT * FROM place")
for rows.Next() {
    err := rows.StructScan(&place)
    if err != nil {
        log.Fatalln(err)
    } 
    fmt.Printf("%#v\n", place)
}

在 github 的 readme 中有一些基本用法 https://github.com/jmoiron/sqlx,以及维护者编写的一些“标准”文档 http://jmoiron.github.io/sqlx/,还有 godoc http://godoc.org/github.com/jmoiron/sqlx

需要注意的一点是,sqlx 做出了类似于 Go 编译器强制你使用已创建变量的设计选择。所以如果你选择了一个在结构体中不存在的列,它会抛出一个错误。这样做的原因是合理的,并且促进了良好的 sql 实践。当你只需要一个列时,使用 Select * 是非常昂贵的。在这里可以看到他的注释 http://jmoiron.github.io/sqlx/#safety

英文:

If you are willing to use a library, https://github.com/jmoiron/sqlx is perfect for the job.

place := Place{}
rows, err := db.Queryx("SELECT * FROM place")
for rows.Next() {
    err := rows.StructScan(&place)
    if err != nil {
        log.Fatalln(err)
    } 
    fmt.Printf("%#v\n", place)
}

There is some basic usage in the github readme https://github.com/jmoiron/sqlx as well as some "standard" documentation the maintainer has written http://jmoiron.github.io/sqlx/ and finally, the godoc http://godoc.org/github.com/jmoiron/sqlx

One thing to note, is that sqlx made the design choice similar to the way the go compiler forces you to use variables that you have created. So if you select a column that isn't in your struct, it throws an error. The reasons for this are sound and promote good sql practices. Select * when you only need one column is crazy expensive. See his notes here http://jmoiron.github.io/sqlx/#safety

huangapple
  • 本文由 发表于 2017年8月2日 15:11:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/45453890.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定