gorm 結(jié)構(gòu)體中 binding 和 msg 結(jié)構(gòu)體標(biāo)簽示例詳解
binding 和 msg 是結(jié)構(gòu)體標(biāo)簽(struct tags),主要用于數(shù)據(jù)驗(yàn)證和錯(cuò)誤信息提示。它們通常與 Gin 框架的 ShouldBindJSON 配合使用,以及用于處理表單驗(yàn)證。
下面詳細(xì)解釋?zhuān)?/p>
基本用法示例:
type LoginForm struct {
Username string `json:"username" binding:"required" msg:"用戶(hù)名不能為空"`
Password string `json:"password" binding:"required,min=6" msg:"密碼不能為空且長(zhǎng)度至少6位"`
Age int `json:"age" binding:"required,gte=18" msg:"年齡必須大于或等于18歲"`
Email string `json:"email" binding:"required,email" msg:"請(qǐng)輸入有效的郵箱地址"`
}在 Gin 中使用:
func Login(c *gin.Context) {
var form LoginForm
if err := c.ShouldBindJSON(&form); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
// 處理登錄邏輯...
}常用的 binding 驗(yàn)證規(guī)則:
type User struct {
// required: 必填
Name string `binding:"required"`
// min,max: 字符串長(zhǎng)度或數(shù)字范圍
Password string `binding:"min=6,max=20"`
// email: 郵箱格式
Email string `binding:"email"`
// oneof: 枚舉值
Role string `binding:"oneof=admin user guest"`
// gte,lte: 大于等于,小于等于
Age int `binding:"gte=18,lte=100"`
// url: URL格式
Website string `binding:"url"`
// 正則表達(dá)式
Phone string `binding:"required,regexp=^1[3-9]\\d{9}$"`
}自定義驗(yàn)證器:
type RegisterForm struct {
Password string `binding:"required,CustomPassword"`
Phone string `binding:"required,CustomPhone"`
}
func customValidator() {
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
// 注冊(cè)自定義驗(yàn)證器
v.RegisterValidation("CustomPassword", ValidatePassword)
v.RegisterValidation("CustomPhone", ValidatePhone)
}
}
func ValidatePassword(fl validator.FieldLevel) bool {
password := fl.Field().String()
// 自定義密碼驗(yàn)證邏輯
return len(password) >= 8
}使用 msg 標(biāo)簽自定義錯(cuò)誤信息:
type CreateUserForm struct {
Username string `json:"username" binding:"required" msg:"用戶(hù)名不能為空"`
Password string `json:"password" binding:"required,min=6" msg:"密碼長(zhǎng)度最少6位"`
}
// 處理錯(cuò)誤信息的輔助函數(shù)
func getValidMsg(err error, obj interface{}) string {
// 通過(guò)反射獲取 struct 類(lèi)型
getObj := reflect.TypeOf(obj)
// 如果是指針,則獲取其基礎(chǔ)類(lèi)型
if getObj.Kind() == reflect.Ptr {
getObj = getObj.Elem()
}
// 將錯(cuò)誤信息轉(zhuǎn)換為驗(yàn)證器錯(cuò)誤
if errs, ok := err.(validator.ValidationErrors); ok {
// 遍歷每一個(gè)錯(cuò)誤
for _, e := range errs {
// 獲取對(duì)應(yīng)字段
if f, exist := getObj.FieldByName(e.Field()); exist {
// 獲取 msg 標(biāo)簽內(nèi)容
msg := f.Tag.Get("msg")
if msg != "" {
return msg
}
}
}
}
return err.Error()
}在控制器中使用:
func CreateUser(c *gin.Context) {
var form CreateUserForm
if err := c.ShouldBindJSON(&form); err != nil {
// 獲取自定義錯(cuò)誤信息
errMsg := getValidMsg(err, form)
c.JSON(400, gin.H{"error": errMsg})
return
}
// 處理業(yè)務(wù)邏輯...
}組合驗(yàn)證規(guī)則:
type Product struct {
// 多個(gè)驗(yàn)證規(guī)則用逗號(hào)分隔
Name string `binding:"required,min=2,max=50" msg:"產(chǎn)品名稱(chēng)長(zhǎng)度必須在2-50之間"`
Price float64 `binding:"required,gte=0" msg:"價(jià)格必須大于或等于0"`
// 條件驗(yàn)證:當(dāng) Status 為 "active" 時(shí),Description 必填
Status string `binding:"required,oneof=active inactive" msg:"狀態(tài)必須是 active 或 inactive"`
Description string `binding:"required_if=Status active" msg:"當(dāng)狀態(tài)為active時(shí),描述必填"`
}跨字段驗(yàn)證:
type ChangePassword struct {
Password string `binding:"required" msg:"密碼不能為空"`
ConfirmPassword string `binding:"required,eqfield=Password" msg:"兩次輸入的密碼不一致"`
}初始化驗(yàn)證器:
func InitValidator() {
// 注冊(cè)驗(yàn)證器
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
// 注冊(cè)自定義驗(yàn)證器
v.RegisterValidation("custom_validation", CustomValidationFunc)
// 注冊(cè)自定義錯(cuò)誤信息翻譯器
zhTranslations.RegisterDefaultTranslations(v, trans)
}
}這些標(biāo)簽主要用于:
- 數(shù)據(jù)驗(yàn)證(binding)
- 自定義錯(cuò)誤信息(msg)
- 參數(shù)綁定
- 表單驗(yàn)證
- API 接口參數(shù)驗(yàn)證
通過(guò)合理使用這些標(biāo)簽,可以:
- 減少手動(dòng)編寫(xiě)驗(yàn)證代碼
- 提供更友好的錯(cuò)誤提示
- 確保數(shù)據(jù)的完整性和有效性
- 提高代碼的可維護(hù)性
到此這篇關(guān)于gorm 結(jié)構(gòu)體中 binding 和 msg 結(jié)構(gòu)體標(biāo)簽的文章就介紹到這了,更多相關(guān)gorm binding 和 msg 結(jié)構(gòu)體標(biāo)簽內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go語(yǔ)言中處理JSON數(shù)據(jù)的編碼和解碼的方法
在Go語(yǔ)言中,處理JSON數(shù)據(jù)的編碼和解碼主要依賴(lài)于標(biāo)準(zhǔn)庫(kù)中的encoding/json包,這個(gè)包提供了兩個(gè)核心的函數(shù):Marshal和Unmarshal,本文給大家介紹了Go語(yǔ)言中處理JSON數(shù)據(jù)的編碼和解碼的方法,需要的朋友可以參考下2024-04-04
golang將切片或數(shù)組根據(jù)某個(gè)字段進(jìn)行分組操作
這篇文章主要介紹了golang將切片或數(shù)組根據(jù)某個(gè)字段進(jìn)行分組操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12
Go?語(yǔ)言進(jìn)階freecache源碼學(xué)習(xí)教程
這篇文章主要為大家介紹了Go?語(yǔ)言進(jìn)階freecache源碼學(xué)習(xí)教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
VSCode1.4 搭建Golang的開(kāi)發(fā)調(diào)試環(huán)境(遇到很多問(wèn)題)
這篇文章主要介紹了VSCode1.4 搭建Golang的開(kāi)發(fā)調(diào)試環(huán)境(遇到很多問(wèn)題),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
golang實(shí)現(xiàn)數(shù)組分割的示例代碼
本文主要介紹了golang實(shí)現(xiàn)數(shù)組分割的示例代碼,要求把數(shù)組分割成多個(gè)正整數(shù)大小的數(shù)組,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12
Go語(yǔ)言開(kāi)發(fā)redis封裝及簡(jiǎn)單使用詳解
這篇文章主要為大家介紹了Go語(yǔ)言開(kāi)發(fā)redis的封裝及簡(jiǎn)單使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2021-11-11
解決golang sync.Wait()不執(zhí)行的問(wèn)題
這篇文章主要介紹了解決golang sync.Wait()不執(zhí)行的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12

