问题
今天使用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在定义模型时,需要说明列名,也就是说,该列名至少有两个作用
-
将go结构体的属性对应相应表的字段名
-
将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"`
}
如此修改,便有数据了。
备注
中文教程地址
英文教程
源码地址
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/99231.html