如何在Golang中实现枚举与Bson&Json映射并存入MongoDB
Go中实现MongoDB与请求兼容的字符串枚举字段
1. 定义自定义枚举类型
在enums包下声明基于string的枚举类型和常量,既满足MongoDB字符串存储要求,又能通过类型约束限定取值:
package enums type StudentType string const ( StudentTypePaid StudentType = "PAID" StudentTypeUnpaid StudentType = "UNPAID" StudentTypeInactive StudentType = "INACTIVE" )
2. 实现有效值校验逻辑
维护合法值集合,用于快速校验输入或数据库读取的字段是否合规:
var validStudentTypes = map[StudentType]bool{ StudentTypePaid: true, StudentTypeUnpaid: true, StudentTypeInactive: true, } // IsValidStudentType 校验StudentType是否为合法枚举值 func IsValidStudentType(t StudentType) bool { return validStudentTypes[t] }
3. 处理JSON序列化/反序列化(请求校验)
实现json.Unmarshaler接口,确保接收HTTP请求时自动校验枚举值,非法值直接返回错误:
import "encoding/json" import "fmt" func (t *StudentType) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { return err } validType := StudentType(s) if !IsValidStudentType(validType) { return fmt.Errorf("invalid studentType: %s, allowed values are PAID, UNPAID, INACTIVE", s) } *t = validType return nil } // 可选:实现MarshalJSON确保输出为标准字符串 func (t StudentType) MarshalJSON() ([]byte, error) { return json.Marshal(string(t)) }
4. 处理BSON序列化/反序列化(MongoDB兼容)
实现bson.Unmarshaler和bson.Marshaler接口,确保MongoDB读写时自动校验字段值,避免脏数据:
import "go.mongodb.org/mongo-driver/bson" func (t *StudentType) UnmarshalBSON(data []byte) error { var s string if err := bson.Unmarshal(data, &s); err != nil { return err } validType := StudentType(s) if !IsValidStudentType(validType) { return fmt.Errorf("invalid studentType stored in DB: %s", s) } *t = validType return nil } func (t StudentType) MarshalBSON() ([]byte, error) { return bson.Marshal(string(t)) }
5. 结构体使用与枚举操作
现在你的studentModel可以直接使用该枚举类型,并且在任何场景下都能像原生枚举一样操作:
type studentModel struct { StudentType enums.StudentType `bson:"studentType,omitempty" json:"studentType,omitempty"` StudentId int64 `bson:"studentId,omitempty" json:"studentId,omitempty"` } // 示例:赋值、比较、打印 func demo() { // 用枚举常量直接赋值 stu := studentModel{ StudentType: enums.StudentTypePaid, StudentId: 12345, } // 枚举值比较 if stu.StudentType == enums.StudentTypeUnpaid { // 执行对应逻辑 } // 打印枚举值(默认转为字符串,也可自定义String方法) println(stu.StudentType) // 输出 "PAID" }
可选:实现String方法
为了让枚举值的字符串转换更直观,可以补充String()方法:
func (t StudentType) String() string { return string(t) }
这套方案完全满足需求:
- MongoDB存储的是字符串类型;
- 请求接收和数据库读写都会自动校验枚举值合法性;
- 结构体字段可直接用枚举常量赋值、比较,完全当作枚举使用。
内容的提问来源于stack exchange,提问作者Prayansh Dhariwal
相关产品推荐
相关产品推荐

