代码之家  ›  专栏  ›  技术社区  ›  Mayukh Sarkar

如何使用GORM一次读取一行SQLite数据库

  •  0
  • Mayukh Sarkar  · 技术社区  · 7 年前

    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

    上面的代码词很完美。但有两个问题

    1. 我需要为我打算在for循环中使用的每个列声明变量 for rows.Next()

    2. 我需要使用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获得正确的数据。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Mayukh Sarkar    7 年前

    我找到了答案。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)
        }
    }