donglu5612 2018-07-30 09:29
浏览 147
已采纳

无法使用* DB.Rows()获取所有行

I'm new to gorm so if I misunderstand something, please point it out.

I'm writing small application using MySQL and I decide to use gorm as ORM. Source code and output is following.

package main

import (
    "fmt"
    "log"

    "github.com/jinzhu/gorm"
    _ "github.com/jinzhu/gorm/dialects/mysql"
)

type Group struct {
    gorm.Model
    Name string `gorm:"not null;unique"`
}

func openDB() *gorm.DB {
    user := "ipmonitor"
    password := "testpassword"
    database := "ipmonitor"

    mysqlURL := "%s:%s@/%s?charset=utf8mb4&parseTime=True&loc=Local"

    db, err := gorm.Open("mysql", fmt.Sprintf(mysqlURL, user, password, database))
    if err != nil {
        log.Fatalln(err)
    }

    return db
}

func initDB(db *gorm.DB) {
    db = db.Set("gorm:table_options", "ENGINE=InnoDB CHARSET=utf8mb4")
    db.AutoMigrate(&Group{})

    result := db.Create(&Group{Name: "foo"})
    if result.Error != nil {
        log.Fatalln(result.Error)
    }
    result = db.Create(&Group{Name: "bar"})
    if result.Error != nil {
        log.Fatalln(result.Error)
    }
    result = db.Create(&Group{Name: "baz"})
    if result.Error != nil {
        log.Fatalln(result.Error)
    }
}

func main() {
    db := openDB()
    db.LogMode(true)
    initDB(db)

    records := db.Find(&Group{})
    if records.Error != nil {
        log.Fatalln(records.Error)
    }

    log.Printf("%d rows found.", records.RowsAffected)
    rows, err := records.Rows()
    if err != nil {
        log.Fatalln(err)
    }
    defer rows.Close()

    for rows.Next() {
        var group Group
        err := db.ScanRows(rows, &group)
        if err != nil {
            log.Fatalln(err)
        }

        log.Printf("%+v
", group)
    }
    if rows.Err() != nil {
        log.Fatalln(rows.Err())
    }
}

Output

(dbtest.go:33)
[2018-07-30 18:12:33]  [9.96ms]  CREATE TABLE `groups` (`id` int unsigned AUTO_INCREMENT,`created_at` timestamp NULL,`updated_at` timestamp NULL,`deleted_at` timestamp NULL,`name` varchar(255) NOT NULL UNIQUE , PRIMARY KEY (`id`)) ENGINE=InnoDB CHARSET=utf8mb4
[0 rows affected or returned ]

(dbtest.go:33)
[2018-07-30 18:12:33]  [6.95ms]  CREATE INDEX idx_groups_deleted_at ON `groups`(deleted_at)
[0 rows affected or returned ]

(dbtest.go:35)
[2018-07-30 18:12:33]  [0.89ms]  INSERT INTO `groups` (`created_at`,`updated_at`,`deleted_at`,`name`) VALUES ('2018-07-30 18:12:33','2018-07-30 18:12:33',NULL,'foo')
[1 rows affected or returned ]

(dbtest.go:39)
[2018-07-30 18:12:33]  [0.99ms]  INSERT INTO `groups` (`created_at`,`updated_at`,`deleted_at`,`name`) VALUES ('2018-07-30 18:12:33','2018-07-30 18:12:33',NULL,'bar')
[1 rows affected or returned ]

(dbtest.go:43)
[2018-07-30 18:12:33]  [0.88ms]  INSERT INTO `groups` (`created_at`,`updated_at`,`deleted_at`,`name`) VALUES ('2018-07-30 18:12:33','2018-07-30 18:12:33',NULL,'baz')
[1 rows affected or returned ]

(dbtest.go:54)
[2018-07-30 18:12:33]  [0.63ms]  SELECT * FROM `groups`  WHERE `groups`.`deleted_at` IS NULL
[3 rows affected or returned ]
2018/07/30 18:12:33 3 rows found.

(dbtest.go:60)
[2018-07-30 18:12:33]  [0.77ms]  SELECT * FROM `groups`  WHERE `groups`.`deleted_at` IS NULL AND `groups`.`id` = '3'
[0 rows affected or returned ]
2018/07/30 18:12:33 {Model:{ID:3 CreatedAt:2018-07-30 18:12:34 +0900 JST UpdatedAt:2018-07-30 18:12:34 +0900 JST DeletedAt:<nil>} Name:baz}

MySQL

mysql> select * from groups;
+----+---------------------+---------------------+------------+------+
| id | created_at          | updated_at          | deleted_at | name |
+----+---------------------+---------------------+------------+------+
|  1 | 2018-07-30 18:12:34 | 2018-07-30 18:12:34 | NULL       | foo  |
|  2 | 2018-07-30 18:12:34 | 2018-07-30 18:12:34 | NULL       | bar  |
|  3 | 2018-07-30 18:12:34 | 2018-07-30 18:12:34 | NULL       | baz  |
+----+---------------------+---------------------+------------+------+
3 rows in set (0.00 sec)

I expect that *DB.Find().Rows() method returns multiple rows but it seems only return last row.

According to gorm debug output, it seems that unspecified condition is added when SELECT statement is executed.

After googling, I can't figure out the cause of problem. Why my code doesn't work?

Thanks.

  • 写回答

1条回答 默认 最新

  • douchaqi3369 2018-07-30 09:42
    关注

    You can try this alternate approach:

    var records []Group
    db.Find(&records)
    

    All data will be available as an array in records.

    If you need to handle the errors:

    if err := db.Find(&records).Error; err != nil {
      log.Fatalln(err)
    }
    log.Printf("%d rows found.", len(records))
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误