一、说明
-
1、
JSON
数据类型是MySQL 5.7.8
开始支持的。在此之前,只能通过字符类型(CHAR
,VARCHAR
或TEXT
)来保存JSON
文档。现实中也很多人不会采用json
的存储方式,直接定义一个字符类型,让前端转换传递进来,返回给前端也是一个字符串,前端自己处理 -
2、
json
数据类型参考文档 -
3、创建一个数据表
CREATE TABLE `report` ( `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id', `query_param` json NOT NULL, `name` varchar(50) DEFAULT NULL, `created_at` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间', `updated_at` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '更新时间', `deleted_at` timestamp(6) NULL DEFAULT NULL COMMENT '软删除时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
二、gorm
中使用json
方式一
-
1、自定义数据类型
// JSON 自定义JSON数据类型 type JSON []byte func (j JSON) Value() (driver.Value, error) { if j.IsNull() { return nil, nil } return string(j), nil } func (j *JSON) Scan(value interface{}) error { if value == nil { *j = nil return nil } s, ok := value.([]byte) if !ok { errors.New("invalid Scan Source") } *j = append((*j)[0:0], s...) return nil } func (m JSON) MarshalJSON() ([]byte, error) { if m == nil { return []byte("null"), nil } return m, nil } func (m *JSON) UnmarshalJSON(data []byte) error { if m == nil { return errors.New("null point exception") } *m = append((*m)[0:0], data...) return nil } func (j JSON) IsNull() bool { return len(j) == 0 || string(j) == "null" } func (j JSON) Equals(j1 JSON) bool { return bytes.Equal([]byte(j), []byte(j1)) }
-
2、在配置生成实体类的工具中遇到
json
的话直接转换为JSON
数据类型dataMap := map[string]func(detailType gorm.ColumnType) (dataType string){ "json": func(detailType gorm.ColumnType) (dataType string) { return "JSON" }, // 自定义 }
-
3、逆向生成的实体类
type ReportEntity struct { ID int64 `gorm:"column:id;type:int;primaryKey;autoIncrement:true;comment:主键id" json:"id"` // 主键id QueryParam JSON `gorm:"column:query_param;type:json;not null" json:"queryParam"` Name string `gorm:"column:name;type:varchar(50)" json:"name"` CreatedAt LocalTime `gorm:"column:created_at;comment:创建时间" json:"createdAt"` // 创建时间 UpdatedAt LocalTime `gorm:"column:updated_at;comment:更新时间" json:"updatedAt"` // 更新时间 DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;type:timestamp(6);comment:软删除时间" json:"-"` // 软删除时间 }
-
4、定义
DTO
的时候直接定义JSON
数据类型type Test1Dto struct { QueryParam JSON `json:"queryParam"` Name string `json:"name"` }
-
5、随便插入数据
三、定义JSON
的方式二
- 1、直接使用
gorm
自带的json
数据类型datatypes.JSON
- 2、可以自己再次封装下
四、查询语句
-
1、官方案例地址
-
2、查询对象中的数据
first, _ := dao.ReportEntity.WithContext(ctx). Where(gen.Cond(datatypes.JSONQuery("query_param").Extract("gender").Equals("男"))...).First()
SELECT * FROM `report` WHERE JSON_EXTRACT(`query_param`,'$.gender') AND `report`.`deleted_at` IS NULL ORDER BY `report`.`id` LIMIT 1
-
3、查询数组中是否包括元素
first, _ := dao.ReportEntity.WithContext(ctx).Where(gen.Cond(datatypes.JSONArrayQuery("query_param").Contains("1"))...).First()
SELECT * FROM `report` WHERE JSON_CONTAINS (`query_param`, JSON_ARRAY('1')) AND `report`.`deleted_at` IS NULL ORDER BY `report`.`id` LIMIT 1
-
4、查询对象数组中是否包括一个值(官网上没找到合适的方式,只能写原生
sql
)SELECT * from report WHERE query_param->"$[1].age" = 20;
first := model.ReportEntity{} w.db.Raw(`SELECT * from report WHERE query_param->"$[1].age" = 20;`).Scan(&first)