Go-Pakettests liefern häufig Hinweise darauf, wie Dinge zu tun sind. Zum Beispiel von database/sql/sql_test.go
,
func TestQuery(t *testing.T) {
rows, err := db.Query("SELECT|people|age,name|")
if err != nil {
t.Fatalf("Query: %v", err)
}
type row struct {
age int
name string
}
got := []row{}
for rows.Next() {
var r row
err = rows.Scan(&r.age, &r.name)
if err != nil {
t.Fatalf("Scan: %v", err)
}
got = append(got, r)
}
}
func TestQueryRow(t *testing.T) {
var name string
var age int
var birthday time.Time
err := db.QueryRow("SELECT|people|age,name|age=?", 3).Scan(&age)
}
Was für Ihre Frage, wenn Sie eine Zeile in eine Struktur abfragen, zu etwas führen würde wie:
var row struct {
age int
name string
}
err = db.QueryRow("SELECT|people|age,name|age=?", 3).Scan(&row.age, &row.name)
Ich weiß, dass dies Ihrer Lösung ähnlich sieht, aber es ist wichtig zu zeigen, wie Sie eine Lösung finden.
Ich empfehle github.com/jmoiron/sqlx .
Aus der README:
Die README-Datei enthält auch ein Code-Snippet, das das Scannen einer Zeile in eine Struktur demonstriert:
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) }
Beachten Sie, dass wir nicht jede Spalte manuell einem Feld der Struktur zuordnen mussten. sqlx verfügt über einige Standardzuordnungen für Strukturfelder zu Datenbankspalten sowie über die Angabe von Datenbankspalten mithilfe von Tags (beachten Sie das
TelephoneCode
Feld derPlace
obigen Struktur). Mehr dazu lesen Sie in der Dokumentation .quelle
Hier ist eine Möglichkeit, dies zu tun: Weisen Sie einfach alle Strukturwerte manuell in der
Scan
Funktion zu.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 } }
quelle
sql.NullString
die Struktur verwenden und konvertieren,JSON
dann ist die generierte nicht freundlich, muss eineVO
oder so etwas verwendenrows, err := connection.Query("SELECT `id`, `username`, `email` FROM `users`") if err != nil { panic(err.Error()) } for rows.Next() { var user User if err := rows.Scan(&user.Id, &user.Username, &user.Email); err != nil { log.Println(err.Error()) } users = append(users, user) }
Vollständiges Beispiel
quelle
Dafür gibt es ein Paket: sqlstruct
Als ich das letzte Mal nachgesehen habe, hat es leider keine eingebetteten Strukturen unterstützt (die einfach zu implementieren sind - ich hatte in wenigen Stunden einen funktionierenden Prototyp).
Ich habe gerade die Änderungen übernommen, die ich an sqlstruct vorgenommen habe
quelle
Verwenden Sie: go-models- mysql sqlbuilder
val, err = m.ScanRowType(row, (*UserTb)(nil))
oder den vollständigen Code
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 }
quelle
Hier ist eine Bibliothek nur dafür: scany .
Sie können es so verwenden:
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`)
Es ist gut dokumentiert und einfach zu bearbeiten.
Haftungsausschluss: Ich bin der Autor dieser Bibliothek.
quelle