如何使用 GORM 一次一行读取 SQLite 数据库
How to read a SQLite database using GORM one row at a time
我有以下代码
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/mattn/go-sqlite3"
)
func getDatabaseHandle(dbpath string) (*sql.DB, error) {
database, err := sql.Open("sqlite3", dbpath)
if err != nil {
log.Printf("Failed to create the handle")
return nil, err
}
if err = database.Ping(); err != nil {
fmt.Printf("Failed to keep connection alive")
return nil, err
}
return database, nil
}
func getAllRows(database *sql.DB, table string) {
query := fmt.Sprintf("SELECT User, AppName FROM %s LIMIT 10", table)
rows, err := database.Query(query)
if err != nil {
panic(err)
}
defer rows.Close()
for rows.Next() {
var id int
var app string
rows.Scan(&id, &app)
fmt.Println(id, app)
}
}
func main() {
db, err := getDatabaseHandle("./gozo.db")
if err != nil {
panic(err)
}
defer db.Close()
getAllRows(db, "timesheet")
}
这是针对具有以下列的 SQLite 数据库
id, User, Matter, AppName, AppDesc, Duration, Type, Timestamp
以上码字完美。但是有两个问题
我需要为我打算在执行 for rows.Next()
的 for 循环中使用的每个列声明变量,这很烦人并且不容易模块化。
我需要使用 ORM 工具来实现数据库的可移植性和所有功能。
因此我绑定了 GORM,这是我的代码
type Timesheet struct {
id int
User int
Matter int
AppName string
AppDesc string
Duration int64
Type string
Timestamp string
}
// TableName -- Sets the table name
func (ts Timesheet) TableName() string {
return "timesheet"
}
func main() {
db, err := gorm.Open("sqlite3", "./gozo.db")
if err != nil {
panic(err)
}
defer db.Close()
var ts []Timesheet
db.Find(&ts).Limit(5)
fmt.Println(ts)
}
但这并没有给我正确的数据,而是给了我所有的值 0。此外,这并没有使用每一行扫描迭代,所以我可以在执行一些其他相关操作的同时包装这个 go 并发。这似乎是在提取所有数据,这也是错误的。请告诉我如何使用 GORM 循环扫描每一行并获取正确的数据。
我找到了答案。 GORM 文档并不那么冗长,但流畅的内容可能就是答案。
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/sqlite"
)
// Product -- Represents a product
type Product struct {
gorm.Model
Code string
Price uint
}
// TableName setting the table name
func (Product) TableName() string {
return "allProducts"
}
func main() {
db, err := gorm.Open("sqlite3", "test.db")
if err != nil {
panic("failed to connect database")
}
defer db.Close()
var product Product
rows, err := db.Model(&Product{}).Rows()
defer rows.Close()
if err != nil {
panic(err)
}
for rows.Next() {
db.ScanRows(rows, &product)
fmt.Println(product)
}
}
我有以下代码
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/mattn/go-sqlite3"
)
func getDatabaseHandle(dbpath string) (*sql.DB, error) {
database, err := sql.Open("sqlite3", dbpath)
if err != nil {
log.Printf("Failed to create the handle")
return nil, err
}
if err = database.Ping(); err != nil {
fmt.Printf("Failed to keep connection alive")
return nil, err
}
return database, nil
}
func getAllRows(database *sql.DB, table string) {
query := fmt.Sprintf("SELECT User, AppName FROM %s LIMIT 10", table)
rows, err := database.Query(query)
if err != nil {
panic(err)
}
defer rows.Close()
for rows.Next() {
var id int
var app string
rows.Scan(&id, &app)
fmt.Println(id, app)
}
}
func main() {
db, err := getDatabaseHandle("./gozo.db")
if err != nil {
panic(err)
}
defer db.Close()
getAllRows(db, "timesheet")
}
这是针对具有以下列的 SQLite 数据库
id, User, Matter, AppName, AppDesc, Duration, Type, Timestamp
以上码字完美。但是有两个问题
我需要为我打算在执行
for rows.Next()
的 for 循环中使用的每个列声明变量,这很烦人并且不容易模块化。我需要使用 ORM 工具来实现数据库的可移植性和所有功能。
因此我绑定了 GORM,这是我的代码
type Timesheet struct {
id int
User int
Matter int
AppName string
AppDesc string
Duration int64
Type string
Timestamp string
}
// TableName -- Sets the table name
func (ts Timesheet) TableName() string {
return "timesheet"
}
func main() {
db, err := gorm.Open("sqlite3", "./gozo.db")
if err != nil {
panic(err)
}
defer db.Close()
var ts []Timesheet
db.Find(&ts).Limit(5)
fmt.Println(ts)
}
但这并没有给我正确的数据,而是给了我所有的值 0。此外,这并没有使用每一行扫描迭代,所以我可以在执行一些其他相关操作的同时包装这个 go 并发。这似乎是在提取所有数据,这也是错误的。请告诉我如何使用 GORM 循环扫描每一行并获取正确的数据。
我找到了答案。 GORM 文档并不那么冗长,但流畅的内容可能就是答案。
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/sqlite"
)
// Product -- Represents a product
type Product struct {
gorm.Model
Code string
Price uint
}
// TableName setting the table name
func (Product) TableName() string {
return "allProducts"
}
func main() {
db, err := gorm.Open("sqlite3", "test.db")
if err != nil {
panic("failed to connect database")
}
defer db.Close()
var product Product
rows, err := db.Model(&Product{}).Rows()
defer rows.Close()
if err != nil {
panic(err)
}
for rows.Next() {
db.ScanRows(rows, &product)
fmt.Println(product)
}
}