golang实现动态路由的项目实践

Written by

in

文章目录
  • 目录
    • 一、动态路由
      • 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分析

    站内搜索