【Gorm】自定义数据类型

server/2024/12/29 16:51:23/

       很多情况下,我们有存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,})
}


http://www.ppmy.cn/server/137275.html

相关文章

K8s-DashBoard部署与管理

DashBoard 之前在kubernetes中完成的所有操作都是通过命令行工具kubectl完成的。其实,为了提供更丰富的用户体验,kubernetes还开发了一个基于web的用户界面(Dashboard)。用户可以使用Dashboard部署容器化的应用,还可以…

基于SSM+微信小程序的社区垃圾回收管理系统(垃圾1)

👉文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 基于ssm微信小程序的社区垃圾回收管理系统,有管理员,回收员,用户三个角色。 1、管理员功能有个人中心,用户管理,回收员管理&am…

python实现excel数据导入数据库

要实现excel数据导入数据库,可以使用Python中的openpyxl库来读取excel文件的数据,然后再使用Python中的pymysql库来连接数据库,并将数据插入数据库中。 以下是一个简单的示例代码: import openpyxl import pymysql# 连接数据库 …

ctfshow web系列

声明: 本文章只适用于网络安全交流与学习,请读者遵循网络安全法,若读者从事一些与网络安全不相关的事情,结果均与本人无关!!! 是ctfshow的web题:https://www.ctf.show/ web3: 开局提示使用php include get url include()函数是…

网站被浏览器提示不安全怎么办?——附解决方案

当你的网站被浏览器标记为不安全时,这通常意味着有一些问题需要解决。以下是一些解决这个问题的步骤: 检查SSL证书:首先,确保你的网站使用了有效的SSL证书。SSL证书可以加密浏览器和服务器之间的数据传输,保护用户数据…

配置服务器的.ssh目录

在配置服务器的 .ssh 目录以支持 SSH 免密码登录时,可以按照以下步骤进行: 1. 确保 .ssh 目录和 authorized_keys 文件存在 在服务器的用户目录下(例如 /home/username),执行以下命令来创建 .ssh 目录和 authorized_…

【Python基础】

一、编程语言介绍 1、分类 机器语言 (直接用 0 1代码编写)汇编语言 (英文单词替代二进制指令)高级语言 2、总结 1、执行效率:机器语言>汇编语言>高级语言(编译型>解释型) 2、开发效率&…

MFC工控项目实例二十七添加产品参数

承接专栏《MFC工控项目实例二十六创建数据库》 在型号参数界面添加三个参数试验时间、最小值、最大值。变量为double m_edit_time; double m_edit_min; double m_edit_max; 1、在SEAL_PRESSURE.h中添加代码 class CProductPara { public:union{struct{...double m_edit_min;…