type Place struct {
Country string
City sql.NullString
TelephoneCode int `db:"telcode"`
}
// Loop through rows using only one struct
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)
}
func getUser(name string) (*User, error) {
var u User
// this calls sql.Open, etc.
db := getConnection()
// note the below syntax only works for postgres
err := db.QueryRow("SELECT * FROM users WHERE name = $1", name).Scan(&u.Id, &u.Name, &u.Score)
if err != nil {
return &User{}, err
} else {
return &u, nil
}
}
type User struct {
Name string
Id int
Score int
}
// db is your *sql.DB instance
// ctx is your current context.Context instance
// Use sqlscan.Select to query multiple records.
var users []*User
sqlscan.Select(ctx, db, &users, `SELECT name, id, score FROM users`)
// Use sqlscan.Get to query exactly one record.
var user User
sqlscan.Get(ctx, db, &user, `SELECT name, id, score FROM users WHERE id=123`)
import (
"context"
"fmt"
"github.com/vingarcia/ksql"
"github.com/vingarcia/ksql/adapters/kpgx"
)
type User struct {
Id int `ksql:"id"`
Name string `ksql:"name"`
Score int `ksql:"score"`
}
// Just a simple struct containing the table name and
// the name of the ID column or columns:
var UsersTable = ksql.NewTable("users", "id")
func main() {
ctx := context.Background()
dsn := "host=localhost user=postgres password=postgres dbname=postgres port=5432 sslmode=disable TimeZone=UTC"
db, err := kpgx.New(ctx, dsn, ksql.Config{})
if err != nil {
panic("failed to connect database")
}
// Lets insert a user so the query below has something to return:
err = db.Insert(ctx, UsersTable, &User{
Name: "SomeUser",
Score: 42,
})
if err != nil {
panic(err)
}
var user User
err = db.QueryOne(ctx, &user, "FROM users WHERE name = $1", "SomeUser")
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", user) // {Id:1 Name:SomeUser Score:42}
}
import (
"database/sql"
"fmt"
lib "github.com/eehsiao/go-models-lib"
mysql "github.com/eehsiao/go-models-mysql"
)
// MyUserDao : extend from mysql.Dao
type MyUserDao struct {
*mysql.Dao
}
// UserTb : sql table struct that to store into mysql
type UserTb struct {
Name sql.NullString `TbField:"Name"`
Id int `TbField:"Id"`
Score int `TbField:"Score"`
}
// GetFirstUser : this is a data logical function, you can write more logical in there
// sample data logical function to get the first user
func (m *MyUserDao) GetFirstUser() (user *User, err error) {
m.Select("Name", "Id", "Score").From("user").Limit(1)
fmt.Println("GetFirstUser", m.BuildSelectSQL().BuildedSQL())
var (
val interface{}
row *sql.Row
)
if row, err = m.GetRow(); err == nil {
if val, err = m.ScanRowType(row, (*UserTb)(nil)); err == nil {
u, _ := val.(*UserTb)
user = &User{
Name: lib.Iif(u.Name.Valid, u.Nae.String, "").(string),
Id: u.Id,
Score: u.Score,
}
}
}
row, val = nil, nil
return
}
8条答案
按热度按时间pqwbnv8z1#
Go包测试经常提供关于做事方式的线索。例如,从
database/sql/sql_test.go
,字符串
对于您的问题,将行查询到结构中,将转换为如下内容:
型
我知道这看起来与您的解决方案相似,但展示如何找到解决方案很重要。
pgvzfuti2#
我推荐github.com/jmoiron/sqlx。
来自README:
sqlx是一个库,它在go的标准
database/sql
库上提供了一组扩展。sql.DB
、sql.TX
、sql.Stmt
等的sqlx版本。它们都保持底层接口不变,因此它们的接口是标准接口的超集。这使得使用database/sql和sqlx集成现有的代码库相对容易。主要的附加概念是:
Get
和Select
可以快速地从查询转换到结构/切片README还包括一个代码片段,演示如何将行扫描到结构中:
字符串
请注意,我们不必手动将每个列Map到结构的字段。sqlx有一些默认的结构字段到数据库列的Map,并且能够使用标记指定数据库列(注意上面
Place
结构的TelephoneCode
字段)。您可以在文档中阅读更多关于它的信息。dgtucam13#
这里有一种方法--在
Scan
函数中手动分配所有结构体值。字符串
xfb7svmp4#
字符串
Full example
j9per5c45#
这里有一个图书馆就是为了这个:scany的数据。
你可以这样使用它:
字符串
它有很好的文档记录,易于使用。
免责声明:我是这个图书馆的作者。
yk9xbfzb6#
有专门的套餐sqlstruct
不幸的是,上次我检查它不支持嵌入式结构(这对于你自己实现来说是微不足道的--我在几个小时内就有了一个工作原型)。
我刚刚提交了对sqlstruct所做的更改
iqih9akk7#
这里已经有一些很好的答案了,我想添加一个我写的SQL库,只是为了解决这个问题,在最常用的Golang库上做一个简单的查询是多么复杂;它被称为KSQL(不是Kafka的,K代表KISS或保持愚蠢的简单)。
使用它,你可以像这样将用户扫描到一个结构体中:
字符串
qq24tv8q8#
用途:go-models-mysqlsqlbuilder
字符串
或完整代码
型