文章目录
- 包含了角色数据库、菜单数据库、角色和菜单关系表。 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:是否是基础路由(开发中)”` // 是否是基础路由(开发中) Title string `json:”title” gorm:”comment:菜单名”` // 菜单名 Icon string `json:”icon” gorm:”comment:菜单图标”` // 菜单图标 CloseTab bool `json:”closeTab” gorm:”comment:自动关闭tab”` // 自动关闭tab } type RoleMenu struct { MenuId string `json:”menuid” gorm:”colume:menuid”` RoleId string `json:”roleid” gorm:”colume:roleid”` }
- 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: %+vn”, role.Menus) } Preload("Menus"):在查询 Role 时,预加载 Menus 字段,即查询出 Role 对应的所有 Menu 数据。通过这种方式,可以避免在访问 role.Menus 时,再次触发数据库查询,出现 N+1 查询问题。
- 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 } 创建新用户时,用户Menus字段为要添加的路由(从数据库中查询出来的),然后直接create即可。创建之后,数据库中不会显示Menus字段,但是role_menu_table会自动添加关联。 默认情况下,Updates 方法只更新主表的数据,不会自动更新关联关系,因为 Menus 是通过 many2many 关系维护的,因此需要显式操作来同步 Menus 和 role_menu_table 的关联数据: if err := config.DB.Model(&role).Association(“Menus”).Replace(menus); err != nil { return err } 删除时,要先删除关联。First时也要Preload,否则会clear失败导致最终删除失败 //找到实例并删除 if err := tx.Preload(“Menus”).First(&role, id).Error; err != nil { return err } //删除关联Menus if len(role.Menus) > 0 { if err := tx.Model(&role).Association(“Menus”).Clear(); err != nil { return err } } //删除实例 if err := tx.Unscoped().Delete(&role).Error; err != nil { return err } 到此这篇关于golang实现动态路由的项目实践的文章就介绍到这了,更多相关golang 动态路由内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客! 您可能感兴趣的文章: Golang之casbin权限管理的实现 Go语言web快速开发框架Gin的HttpRouter路由的使用 Go路由注册方法详解 Go 1.22对net/http包的路由增强功能详解 Go Gin框架中的路由组及其优先级探索分析 Go Gin框架路由相关bug分析
目录
- 一、动态路由
- 1.结构体(数据库的定义)
- 2.预加载preload
- 3.添加关联的方法
包含了角色数据库、菜单数据库、角色和菜单关系表。
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:是否是基础路由(开发中)"` // 是否是基础路由(开发中)
Title string `json:"title" gorm:"comment:菜单名"` // 菜单名
Icon string `json:"icon" gorm:"comment:菜单图标"` // 菜单图标
CloseTab bool `json:"closeTab" gorm:"comment:自动关闭tab"` // 自动关闭tab
}
type RoleMenu struct {
MenuId string `json:"menuid" gorm:"colume:menuid"`
RoleId string `json:"roleid" gorm:"colume:roleid"`
}
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: %+vn", role.Menus)
}
Preload("Menus"):在查询 Role 时,预加载 Menus 字段,即查询出 Role 对应的所有 Menu 数据。通过这种方式,可以避免在访问 role.Menus 时,再次触发数据库查询,出现 N+1 查询问题。
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
}
创建新用户时,用户Menus字段为要添加的路由(从数据库中查询出来的),然后直接create即可。创建之后,数据库中不会显示Menus字段,但是role_menu_table会自动添加关联。
默认情况下,Updates 方法只更新主表的数据,不会自动更新关联关系,因为 Menus 是通过 many2many 关系维护的,因此需要显式操作来同步 Menus 和 role_menu_table 的关联数据:
if err := config.DB.Model(&role).Association("Menus").Replace(menus); err != nil {
return err
}
删除时,要先删除关联。First时也要Preload,否则会clear失败导致最终删除失败
//找到实例并删除
if err := tx.Preload("Menus").First(&role, id).Error; err != nil {
return err
}
//删除关联Menus
if len(role.Menus) > 0 {
if err := tx.Model(&role).Association("Menus").Clear(); err != nil {
return err
}
}
//删除实例
if err := tx.Unscoped().Delete(&role).Error; err != nil {
return err
}
到此这篇关于golang实现动态路由的项目实践的文章就介绍到这了,更多相关golang 动态路由内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!
您可能感兴趣的文章:
- Golang之casbin权限管理的实现
- Go语言web快速开发框架Gin的HttpRouter路由的使用
- Go路由注册方法详解
- Go 1.22对net/http包的路由增强功能详解
- Go Gin框架中的路由组及其优先级探索分析
- Go Gin框架路由相关bug分析