golang實(shí)現(xiàn)動(dòng)態(tài)路由的項(xiàng)目實(shí)踐
一、動(dòng)態(tài)路由
1.結(jié)構(gòu)體(數(shù)據(jù)庫(kù)的定義)
包含了角色數(shù)據(jù)庫(kù)、菜單數(shù)據(jù)庫(kù)、角色和菜單關(guān)系表。
type Role struct { gorm.Model Rolename string `json:"rolename"` Authority string `json:"authority"` Order int `json:"order" gorm:"column:order"` Status bool `json:"status"` Menus []Menu `json:"menus" gorm:"many2many:role_menu_table"` Remark string `json:"remark"` }
type Menu struct { gorm.Model ParentID uint `json:"parentid" gorm:"column:parentid"` Path string `json:"path"` Name string `json:"name"` Component string `json:"component"` Sort int `json:"sort"` Meta `json:"meta"` Children []Menu `json:"children" gorm:"-"` Roles []Role `json:"rolse" gorm:"many2many:role_menu_table"` } type Meta struct { ActiveName string `json:"activeName" gorm:"comment:高亮菜單"` KeepAlive bool `json:"keepalive" gorm:"comment:是否緩存"` // 是否緩存 DefaultMenu bool `json:"defaultmenu" gorm:"comment:是否是基礎(chǔ)路由(開發(fā)中)"` // 是否是基礎(chǔ)路由(開發(fā)中) Title string `json:"title" gorm:"comment:菜單名"` // 菜單名 Icon string `json:"icon" gorm:"comment:菜單圖標(biāo)"` // 菜單圖標(biāo) CloseTab bool `json:"closeTab" gorm:"comment:自動(dòng)關(guān)閉tab"` // 自動(dòng)關(guān)閉tab }
type RoleMenu struct { MenuId string `json:"menuid" gorm:"colume:menuid"` RoleId string `json:"roleid" gorm:"colume:roleid"` }
2.預(yù)加載preload
var role Role err = db.Preload("Menus").Find(&role,roleid).Error if err != nil { fmt.Println("Error:", err) return }else{ fmt.Printf("Role's Menus: %+v\n", role.Menus) }
Preload("Menus")
:在查詢 Role
時(shí),預(yù)加載 Menus
字段,即查詢出 Role
對(duì)應(yīng)的所有 Menu
數(shù)據(jù)。通過這種方式,可以避免在訪問 role.Menus
時(shí),再次觸發(fā)數(shù)據(jù)庫(kù)查詢,出現(xiàn) N+1 查詢問題。
3.添加關(guān)聯(lián)的方法
var role models.Role role.ID = reqRole.ID role.Rolename = reqRole.Rolename role.Authority = reqRole.Authority role.Order = reqRole.Order role.Status = reqRole.Status role.Menus = menus role.Remark = reqRole.Remark if err := config.DB.Create(&role).Error; err != nil { return err }
創(chuàng)建新用戶時(shí),用戶Menus字段為要添加的路由(從數(shù)據(jù)庫(kù)中查詢出來的),然后直接create即可。創(chuàng)建之后,數(shù)據(jù)庫(kù)中不會(huì)顯示Menus字段,但是role_menu_table會(huì)自動(dòng)添加關(guān)聯(lián)。
默認(rèn)情況下,Updates
方法只更新主表的數(shù)據(jù),不會(huì)自動(dòng)更新關(guān)聯(lián)關(guān)系,因?yàn)?nbsp;Menus
是通過 many2many
關(guān)系維護(hù)的,因此需要顯式操作來同步 Menus
和 role_menu_table
的關(guān)聯(lián)數(shù)據(jù):
if err := config.DB.Model(&role).Association("Menus").Replace(menus); err != nil { return err }
刪除時(shí),要先刪除關(guān)聯(lián)。First時(shí)也要Preload,否則會(huì)clear失敗導(dǎo)致最終刪除失敗
//找到實(shí)例并刪除 if err := tx.Preload("Menus").First(&role, id).Error; err != nil { return err } //刪除關(guān)聯(lián)Menus if len(role.Menus) > 0 { if err := tx.Model(&role).Association("Menus").Clear(); err != nil { return err } } //刪除實(shí)例 if err := tx.Unscoped().Delete(&role).Error; err != nil { return err }
到此這篇關(guān)于golang實(shí)現(xiàn)動(dòng)態(tài)路由的項(xiàng)目實(shí)踐的文章就介紹到這了,更多相關(guān)golang 動(dòng)態(tài)路由內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go并發(fā)讀寫文件、分片寫、分片下載文件的實(shí)現(xiàn)示例
讀寫文件在很多項(xiàng)目中都可以用到,本文主要介紹了Go并發(fā)讀寫文件、分片寫、分片下載文件的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01Golang干貨分享之利用AST實(shí)現(xiàn)AOP功能
本文主要是一個(gè)純干貨分享,主要介紹了Golang如何利用AST實(shí)現(xiàn)AOP功能,文中的示例代碼簡(jiǎn)潔易懂,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-04-04Golang協(xié)程池的實(shí)現(xiàn)與應(yīng)用
這篇文章主要介紹了Golang協(xié)程池的實(shí)現(xiàn)與應(yīng)用,使用協(xié)程池的好處是減少在創(chuàng)建和銷毀協(xié)程上所花的時(shí)間以及資源的開銷,解決資源不足的問題,需要詳細(xì)了解可以參考下文2023-05-05Golang發(fā)送Get和Post請(qǐng)求的實(shí)現(xiàn)
做第三方接口有時(shí)需要用Get或者Post請(qǐng)求訪問,本文主要介紹了Golang發(fā)送Get和Post請(qǐng)求的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-05-05go 對(duì)象池化組件 bytebufferpool使用詳解
這篇文章主要為大家介紹了go 對(duì)象池化組件 bytebufferpool使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10Go語言使用defer+recover解決panic導(dǎo)致程序崩潰的問題
如果協(xié)程出現(xiàn)了panic,就會(huì)造成程序的崩潰,這時(shí)可以在goroutine中使用recover來捕獲panic,進(jìn)行處理,本文就詳細(xì)的介紹一下,感興趣的可以了解一下2021-09-09