gorm查询结果无法填充到结构体中 gorm框架 gorm字段标签 gorm特性 gorm中文版、英文版和源码地址

导读:本篇文章讲解 gorm查询结果无法填充到结构体中 gorm框架 gorm字段标签 gorm特性 gorm中文版、英文版和源码地址,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

问题

今天使用gorm开发时,明明定义了结构体,但gorm没有把数据填充到结构体对象中,这是为什么呢?如代码所示:

// 定义结构体
type ComplaintCount struct {
    Pending                    int64  
    Processed                  int64  
    BetweenOneDayAndThreeDay   int64  
    BetweenThreeDayAndSevenDay int64 
    BeyondSevenDay             int64  
}

//方法执行
func CountComplaint(c context.Context, params map[string]interface{}) (ret *ComplaintCount, err error) {

    db := dao.db.Table("complaint")
    db = db.Select(`count( IF ( status = 1, 1, NULL ) ) as Pending, 
                    count( IF ( status = 2, 1, NULL ) ) as Processed,
                    count(IF(TIMESTAMPDIFF(day,createdAt,NOW())>=0 AND TIMESTAMPDIFF(day,createdAt,NOW())<2 AND status = 1,1,NULL)) as BetweenOneDayAndThreeDay,
                    count(IF(TIMESTAMPDIFF(day,createdAt,NOW())>=2 AND TIMESTAMPDIFF(day,createdAt,NOW())<6 AND status = 1 ,1,NULL)) BetweenThreeDayAndSevenDay,
                    count(IF(TIMESTAMPDIFF(day,createdAt,NOW())>=6 AND status = 1 ,1,NULL)) AS BeyondSevenDay `)
    var result ComplaintCount
    
    err = db.Find(&result).Error
    if err != nil {
        return
    }
    ret = &result
    return
}

但是,原生的SQL语句是有数据的,这是为什么呢?我们就要去了解gorm。

gorm

它是什么

gorm是使用go语言写的orm框架,即关系对象模型【object relation model 】就,就像我们java中的mybatis、hibernate框架一样。

它的特性

  • 全功能 ORM。

  • 关联 (Has One,Has Many,Belongs To,Many To Many,多态,单表继承)。

  • Create,Save,Update,Delete,Find 中钩子方法。

  • 支持 Preload、Joins 的预加载。

  • 事务,嵌套事务,Save Point,Rollback To Saved Point。

  • Context、预编译模式、DryRun 模式。

  • 批量插入,FindInBatches,Find/Create with Map,使用 SQL 表达式、Context Valuer 进行 CRUD。

  • SQL 构建器,Upsert,数据库锁,Optimizer/Index/Comment Hint,命名参数,子查询。

  • 复合主键,索引,约束。

  • Auto Migration。

  • 自定义 Logger。

  • 灵活的可扩展插件 API:Database Resolver(多数据库,读写分离)、Prometheus…

  • 每个特性都经过了测试的重重考验。

  • 开发者友好。

定义模型

type Model struct {
  ID        uint           `gorm:"primaryKey"`
  CreatedAt time.Time
  UpdatedAt time.Time
  DeletedAt gorm.DeletedAt `gorm:"index"`
}

你会发现,在声明model结构体时,会有一个字段标签gorm,这个字段标签有什么作用呢?即设置结构体与数据表字段的对应关系,如下表格所示:

字段标签

标签名 说明
column 指定 db 列名
type 列数据类型,推荐使用兼容性好的通用类型,例如:所有数据库都支持 bool、int、uint、float、string、time、bytes 并且可以和其他标签一起使用,例如:not null、size, autoIncrement… 像 varbinary(8) 这样指定数据库数据类型也是支持的。在使用指定数据库数据类型时,它需要是完整的数据库数据类型,如:MEDIUMINT UNSIGNED not NULL AUTO_INCREMENT
serializer specifies serializer for how to serialize and deserialize data into db, e.g: serializer:json/gob/unixtime
size specifies column data size/length, e.g: size:256
primaryKey specifies column as primary key
unique specifies column as unique
default specifies column default value
precision specifies column precision
scale specifies column scale
not null specifies column as NOT NULL
autoIncrement specifies column auto incrementable
autoIncrementIncrement auto increment step, controls the interval between successive column values
embedded embed the field
embeddedPrefix column name prefix for embedded fields
autoCreateTime track current time when creating, for int fields, it will track unix seconds, use value nano/milli to
autoUpdateTime track current time when creating/updating, for int fields, it will track unix seconds, use value nano/milli to track unix nano/milli seconds, e.g: autoUpdateTime:milli
index create index with options, use same name for multiple fields creates composite indexes, refer Indexes for details
uniqueIndex same as index, but create uniqued index
check creates check constraint, eg: check:age > 13, refer Constraints
<- set field’s write permission, <-:create create-only field, <-:update update-only field, <-:false no write permission, <- create and update permission
-> set field’s read permission, ->:false no read permission
ignore this field, – no read/write permission, -:migration no migrate permission, -:all no read/write/migrate permission
comment add comment for field when migration

问题解决

由表格中的定义可知,原来gorm在定义模型时,需要说明列名,也就是说,该列名至少有两个作用

  1. 将go结构体的属性对应相应表的字段名

  2. 将go结构体的属性对应查询语句的别名

上面的查询语句满足第二个条件,因而,结构体需要修改为这样的:

type ComplaintCount struct {
    Pending                    int64 `gorm:"column:Pending"`
    Processed                  int64 `gorm:"column:Processed"`
    BetweenOneDayAndThreeDay   int64 `gorm:"column:BetweenOneDayAndThreeDay"`
    BetweenThreeDayAndSevenDay int64 `gorm:"column:BetweenThreeDayAndSevenDay"`
    BeyondSevenDay             int64 `gorm:"column:BeyondSevenDay"`
}

如此修改,便有数据了。

备注

中文教程地址

中文版

英文教程

英文版

源码地址

githup地址

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/99231.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!