当前位置:网站首页>【GORM】存取数组/自定义类型数据
【GORM】存取数组/自定义类型数据
2022-07-31 09:52:00 【Viva Python】
GORM
存取数组类型数据
在
GORM
不支持数组类型变量数据的存取,可以通过GROM
的自定义数据类型实现。
一、GORM
的自定义类型
1. Scanner
/Valuer
接口
GORM
的自定义的数据类型必须实现Scanner
/Valuer
接口。
(1) Scanner
接口的Scan
方法,是从数据库读取数据到Go变量时需要进行的解析处理,与解码的过程类型。
(2) Valuer
接口的Value
方法,是将Go变量存到数据库时进行编码处理。
2. 数组变量
虽然GORM
不支持数组变量,但是可以通过实现Scanner
/Valuer
接口,在数据库取/存时进行类似解码/编码的处理,使数组变量成为数据库可支持的变量类型。
(1) 实现Sacnner
接口
Scan
函数,从数据库读取数据后,对其进行处理,然后获得Go类型的变量。
type Strs []string
func (m *Strs) Scan(val interface{
}) error {
s := val.([]uint8)
ss := strings.Split(string(s), "|")
*m = ss
return nil
}
- 如上自定义
Strs
类型,底层类型未字符串数组。Scan
函数将读取的val
值,按照字符串处理,以"|"为分隔符进行切割,获得字符串数组类型,然后使用指针赋值。
(2) 实现Valuer
接口
Value
函数,将数据存到数据库时,对数据进行处理,获得数据库支持的类型。
func (m Strs) Value() (driver.Value, error) {
str := strings.Join(m, "|")
return str, nil
}
- 如上将
Strs
存入数据库前,将数组内的字符串用"|"拼接,获得数据库支持的string
类型后再存入数据库。
3. 测试
定义如下函数进行测试
(1) 模型变量
type User struct {
ID uint `gorm:"primary_key"`
Name string
Pics Strs `gorm:"type:longtext"` // 自定义的数组类型,在数据库中存为长文本类型
}
(2) Service
函数
func SaveUser(user User) error {
var err error
err = db.Save(&user).Error
return err
}
func GetUser(name string) (User, error) {
var user User
err := db.First(&user, "name = ?", name).Error
return user, err
}
(3) testService
函数
func TestSaveUser() {
user := User{
Name: "Jason",
Pics: Strs{
"123124",
"gtsrbxrzsfcv",
},
}
err := SaveUser(user)
if err != nil {
log.Panicln("保存失败!", err)
} else {
log.Println("保存成功!")
}
}
func TestGetUser() {
user, err := GetUser("Jason")
if err != nil {
log.Panicln("获取失败!", err)
} else {
log.Println("获取成功!", user)
}
}
(4) 运行结果
2022/07/30 18:18:41 保存成功!
2022/07/30 18:18:41 获取成功! {3 Jason [123124 gtsrbxrzsfcv]}
- 在数据库存储中体现为:
mysql> select *from users;
+----+-------+---------------------+
| id | name | pics |
+----+-------+---------------------+
| 3 | Jason | 123124|gtsrbxrzsfcv |
+----+-------+---------------------+
1 row in set (0.00 sec)
二、实际生产
上面的例子中展示了
Scanner
/Valuer
接口的简单使用,实际生产中将数组类型转换为json
字符串进行保存,下面展示一个完整的例子,以一个User
拥有一张包含信息的银行卡为例(当然可以通过一对一关联4444实现)。(1) 实现自定义类型
type User struct { ID uint `gorm:"primary_key"` Name string Cards Card `gorm:"json"` } type Card struct { // 指定json的Tag。 Type int `json:"type"` Account string `json:"account"` Password string `json:"password"` } // Scan 解码json字符串 func (card *Card) Scan(val interface{ }) error { b, _ := val.([]byte) return json.Unmarshal(b, card) } // Value 编码json func (card Card) Value() (value driver.Value, err error) { return json.Marshal(card) }
(2) 数据表模型
type User struct {
ID uint `gorm:"primary_key"`
Name string
Cards Card `gorm:"json"` // 指定为json类型
}
边栏推荐
猜你喜欢
js implements the 2020 New Year's Day countdown bulletin board
Gradle series - Groovy overview, basic use (based on Groovy document 4.0.4) day2-1
富文本编辑器Tinymce
[NLP] Interpretation of Transformer Theory
Redis Cluster - Sentinel Mode Principle (Sentinel)
Kotlin—基本语法(三)
Build finished with errors/Executable Not Found
一些计时软件,生产力工具
浏览器使用占比js雷达图
浓眉大眼的谷歌 Chrome 也叛变了,教你一招快速清除其自带广告
随机推荐
canvas粒子变幻各种形状js特效
The fifth chapter
学习笔记——七周成为数据分析师《第二周:业务》:业务分析框架
odoo14 | 附件上传功能及实际使用
【NLP】Transformer理论解读
GVINS论文阅读笔记
优信年营收16亿:亏损3亿 已与蔚来资本及58集团签署股权协议
迪拜的超市---线段树双重懒标记+二分
Solve rpc error: code = Unimplemented desc = method CheckLicense not implemented
Flink1.15源码阅读flink-clients——flink命令行帮助命令
cocoaPods管理之后工程结构变化
NowCoderTOP17-22 二分查找/排序——持续更新ing
ReentrantLock
模块八
第二十二课,实例化(instancing)
【节选】吴恩达给出的AI职业生涯规划
湖仓一体电商项目(二):项目使用技术及版本和基础环境准备
各位大佬,sqlserver 支持表名正则匹配吗
(C language) program environment and preprocessing
js department budget and expenditure radar chart