time.Time类型数据
问题
使用gorm时,定义与时间相关的字段时,一般定义的类型为time.Time
。
go
type CommonBaseModel struct {
ID string `gorm:"primary_key" json:"userId"`
CreatedAt *LocalTime `json:"created_at,omitempty"`
UpdatedAt *LocalTime `json:"updated_at,omitempty"`
DeletedAt *gorm.DeletedAt `gorm:"index" json:"deleted_at,omitempty"`
}
当在执行查询操作时,获取的值为ISO 8601
格式,格式为2021-06-15T10:14:02.973528+08:00
具体含义:
- 日期格式:YYYY-MM-DD
2021-06-15
- YYYY表示四位数的年份
- MM表示两位数的月份
- DD表示两位数的日期
- 时间格式:hh:mm:ss.ms
10:14:02.973528
- hh表示两位数的小时
- mm表示两位数的分钟
- ss表示两位数的秒
- ms表示微秒
- 日期和时间结合:YYYY-MM-DDThh:mm:ss.ms
T
- 使用字母’T’来分隔日期和时间
- 时区
+08:00
解决办法
version
gorm.io/gorm v1.25.12
gorm.io/driver/mysql v1.5.7
使用自定义数据类型解决
1、定义自定义的类型
go
type LocalTime time.Time
2、重写MarshalJSON方法来实现数据解析
go
func (t *LocalTime) MarshalJSON() ([]byte, error) {
tTime := time.Time(*t)
return []byte(fmt.Sprintf("\"%v\"", tTime.Format("2006-01-02 15:04:05"))), nil
}
3、实现Scanner和Valuer接口
go
func (t *LocalTime) Value() (driver.Value, error) {
var zeroTime time.Time
tlt := time.Time(t)
//判断给定时间是否和默认零时间的时间戳相同
if tlt.UnixNano() == zeroTime.UnixNano() {
return nil, nil
}
return tlt, nil
}
func (t *LocalTime) Scan(v interface{}) error {
if value, ok := v.(time.Time); ok {
*t = LocalTime(value)
return nil
}
return fmt.Errorf("can not convert %v to timestamp", v)
}
排除某些字段
gorm查询时,通过Select
方法选择特定字段进行数据查询,当数据字段很多时,仅需要排除某个或几个字段时,使用Omit
方法进行字段的排除 但数据的数据仍有字段名称只是值为空,可以使用omitempty空值省略,排除字段。
具体代码
UserModel
go
type User struct {
CommonBaseModel `gorm:"embedded"`
Name string `gorm:"comment:用户名" json:"name"`
PassWord string `gorm:"comment:密码" json:"password,omitempty"`
Avatar string `gorm:"comment:头像" json:"avatar"`
Gender string `gorm:"column:gender;default:male;type:varchar(6);comment:male表示男,female表示女" json:"gender"` //gorm为数据库字段约束
Phone string `valid:"matches(^1[3-9]{1}\\d{9}$)" json:"phone"` //valid为条件约束
Email string `valid:"email" json:"email"`
Identity string `gorm:"comment:用户身份" json:"identity,omitempty"`
ClientIp string `valid:"ipv4" gorm:"comment:设备IP" json:"client_ip,omitempty"`
ClientPort string `gorm:"comment:设备端口" json:"client_port,omitempty"`
Salt string `gorm:"comment:用户密码MD5盐值" json:"salt,omitempty"`
LoginTime *time.Time `gorm:"column:login_time" json:"login_time,omitempty"`
HeartBeatTime *time.Time `gorm:"column:heart_beat_time" json:"heart_beat_time"`
LoginOutTime *time.Time `gorm:"column:login_out_time" json:"login_out_time,omitempty"`
IsLoginOut bool `json:"is_login_out"`
DeviceInfo string `json:"device_info"` //登录设备
}
func (table *User) UserTableName() string {
return "users"
}
获取列表数据
go
// GetUserList 获取用户列表
func GetUserList() ([]*models.User, error) {
var list []*models.User
if tx := global.DB.Omit("Salt", "Identity",
"PassWord", "ClientIp", "ClientPort", "UpdatedAt", "DeletedAt").Find(&list); tx.Error != nil {
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, tx.Error
}
return list, nil
}