关于解决 go 存到数据库中自定义类型为null 取出来却是空结构体(0值)问题
关于解决 go 存到数据库中自定义类型为null 取出来却是空结构体(0值)问题
在我存储Message表的时候,我定义Message为空,存到数据库中也是为null,但是读取出来的时候,却变成了一个初始化为空的结构体,并不是nil。
Test:
package handler
import (
"database/sql/driver"
"encoding/json"
"github.com/zeromicro/go-zero/core/logx"
"gorm.io/gorm"
"im_server/common/models"
"im_server/core"
"testing"
)
type Message struct {
// 此MODEL是自定义结构体
models.MODEL
Content string `json:"content"`
SystemHint *SystemHint `json:"system_hint"`
}
// SystemHint 系统提示
type SystemHint struct {
Type int8 `json:"type"` // 系统违规提示 1-涉黄 2-涉恐 3-涉证 4-不正当言论
}
// Scan 处理从数据库取出的数据
func (t *SystemHint) Scan(value any) error {
return json.Unmarshal(value.([]byte), t)
}
// Value 处理存入数据库的数据
func (t *SystemHint) Value() (driver.Value, error) {
b, err := json.Marshal(t)
return string(b), err
}
func MigrateTable(db *gorm.DB) {
err := db.AutoMigrate(&Message{})
if err != nil {
logx.Error(err)
return
}
err = db.Create(&Message{}).Error
if err != nil {
logx.Error(err)
}
}
func TestMul(t *testing.T) {
// InitGorm是自定义连接函数
db := core.InitGorm("root:1234@tcp(127.0.0.1:3306)/test_db?charset=utf8mb4&parseTime=True&loc=Local")
MigrateTable(db)
message := Message{}
logx.Infof("message: %+v", message)
err := db.Take(&message, 1).Error
logx.Infof("message: %+v", message)
if err != nil {
logx.Errorf("err: %+v", err)
}
}

随后发现,在我将数据库中的SystemHint字段的null删除为空之后,读取出来的SystemHint正确的变成了nil,说明自定义的SystemHint的Scan方法如果遇到的是null,就会自动转换为0值。那么如果仍然需要nil值,就需要在Value方法中变化。
我发现,在SystemHint的成员函数中,将t *SystemHint的结构体指针更改为结构体t SystemHint,如果存储的SystemHint为nil,那么存到数据库中就不会变成null,而是为空,这样Scan读取出来的时候,就是nil
// Value 处理存入数据库的数据
func (t SystemHint) Value() (driver.Value, error) {
b, err := json.Marshal(t)
return string(b), err
}
运行之后数据库结果如下:

日志如下:


浙公网安备 33010602011771号