您的位置:首页 > 科技 > 能源 > 做电影网站如何不侵权_赣州经开区疫情最新情况_如何网页优化_百度指数关键词

做电影网站如何不侵权_赣州经开区疫情最新情况_如何网页优化_百度指数关键词

2024/11/15 1:33:05 来源:https://blog.csdn.net/2301_77868664/article/details/143369307  浏览:    关键词:做电影网站如何不侵权_赣州经开区疫情最新情况_如何网页优化_百度指数关键词
做电影网站如何不侵权_赣州经开区疫情最新情况_如何网页优化_百度指数关键词

       很多情况下,我们有存JSON的需求,那么就需要使用到gorm中的自定义数据类型了。自定义的数据类型必须实现 Scanner 和 Valuer 接口,简单地说,在入库的时候转换一下,变成普通字符串记性存储,查询的时候,映射为结构体。

一、JSON 自定义数据类型

       JSON数据用的比较多,我们在迁移数据库之前,我们需要先对自定义数据类型进行接口函数的重新定义,只需要定义 Scanner 和 Valuer 函数即可,否则会迁移数据库失败。下面,我们来看一看代码是什么??

type Info struct {Like []string `json:"like"`Addr string `json:"addr"`Age int `json:"age"`
}// Scan 实现 sql.Scanner 接口, Scan 将 value 扫描到 Jsonb
func (j *Info) Scan(value interface{}) error {bytes, ok := value.([]byte)if !ok {return errors.New(fmt.Sprintf("Failed to unmarshal JSONB value:", value))}result := Info{}err := json.Unmarshal(bytes, &result)*j = resultreturn err
}// value 实现 driver.Valuer 接口, Value 返回 json value
func (j Info) Value() (driver.Value, error) {return json.Marshal(j)
}

注意:这里千万不要自作聪明,去改指针方法或者接受者方法,Scan是指针方法,Value是接收者方法。

1.1 插入数据

我们可以使用 create 方法去插入数据,代码如下:

type User struct {ID int64Name string `gorm:"size:32"`Info Info `gorm:"type:longtext" json:"info"`
}DB.Create(&User{Name: "加油旭杏",Info: Info{Age:  20,Addr: "湖北武汉",Like: []string{"唱", "跳", "rap"},},
})

1.2 查询数据

var user UserDB.Take(&user, 1)
fmt.Println(user.Name, user.Info.Like)

二、序列化

       如果只是存储 json 数据,完全可以使用 gorm 的序列化,自带 json,我们的自定义类型不需要写上述的两个函数接口,只需要在建立数据库的结构体的字段后添加一个字段即可:`gorm:"serializer:json"`,代码如下:

type User struct {ID   int64Name string `gorm:"size:32"`Info Info   `gorm:"type:longtext;serializer:json" json:"info"`
}

三、枚举类型

       有些情况下,在数据库里面需要存储一些标识状态的内容,比如描述日志的等级,通常有固定的几个值,比如:info,waring,error等,如果直接存储字符串,很明显是浪费空间,所以可以使用自定义类型。枚举类型不需要进行编写两个函数接口,就可以迁移数据库。代码如下:

type Status int8const (Running Status = 1Warning Status = 2
)type User struct {ID     int64Name   string `gorm:"size:32"`Status Status `json:"status"`
}

       因为返回前端的时候,肯定是会走json序列化的,所以返回给前端的时候就是对应的中文,我们可以实现一个函数,代码如下:

func (s Status) MarshalJSON() (data []byte, err error) {var str stringswitch s {case Running:str = "运行中"case Warning:str = "警告"}return json.Marshal(str)
}

       不过这个函数可以再优化一下,只返回中文的数据是比较少的,还需要把他本身的数字也返回出来,我们可以使用map来进行操作,代码如下:

func (s Status) MarshalJSON() (data []byte, err error) {var str stringswitch s {case Running:str = "运行中"case Warning:str = "警告"}return json.Marshal(map[string]any{"status":      int8(s),"statusTitle": str,})
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com