golang gorm 的多对多关系 CRUD 操作

更新日期: 2022-03-10 阅读次数: 1221 字数: 342 分类: golang

例如,一个财务预算管理系统,需要能设置各部门的负责人,以方便控制查看权限。 而且可以一个部门设置多个负责人。

golang gorm 的数据结构

因为我独立建了个关系表,兼容出现多对多的关系,所以用到了 gorm many2many:

type Department struct {
	Id         int    `json:"id"`
	Name       string `json:"name"`
	Managers   []User `gorm:"many2many:department_manager;"`
	ManagerIds []int  `gorm:"-"`	// 有点多余,但是前端接口能简化很多
}

返回列表

然后再返回数据的时候加个预加载即可:

db := models.DB.Preload("Managers")

新建/更新

就在原有 Department 的基础上,增加了管理员 id 列表字段 ManagerIds。

以更新为例:

func UpdateDepartment(c *gin.Context) {
	var item models.Department
	if err := c.ShouldBindJSON(&item); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	models.DB.
		Select("name").
		Updates(item)

	// 更新关联表
	var managers []models.User
	for _, v := range item.ManagerIds {
		managers = append(managers, models.User{Id: v})
	}
	models.DB.Model(&item).Association("Managers").Replace(managers)

	c.JSON(http.StatusOK, gin.H{
		"success": true,
	})
}

gorm 更新关联表对应的 sql

Association("Managers").Replace 对应的 SQL 语句:

2022/03/09 17:05:20 /home/xxx/controllers/department.go:43
[1.076ms] [rows:0] UPDATE `department` SET `name`='市场部' WHERE `id` = 9

2022/03/09 17:05:20 /home/xxx/controllers/department.go:51
[0.524ms] [rows:0] INSERT INTO `user` (`real_name`,`id`) VALUES ('',4),('',3) ON DUPLICATE KEY UPDATE `id`=`id`

2022/03/09 17:05:20 /home/xxx/controllers/department.go:51
[0.482ms] [rows:2] INSERT INTO `department_manager` (`department_id`,`user_id`) VALUES (9,4),(9,3) ON DUPLICATE KEY UPDATE `department_id`=`department_id`

2022/03/09 17:05:20 /home/xxx/controllers/department.go:51
[8.100ms] [rows:0]

2022/03/09 17:05:20 /home/xxx/controllers/department.go:51
[0.698ms] [rows:0] DELETE FROM `department_manager` WHERE `department_manager`.`department_id` = 9 AND `department_manager`.`user_id` NOT IN (4,3)
[GIN] 2022/03/09 - 17:05:20 | 200 |     10.1287ms |       127.0.0.1 | POST     "/api/admin/updateDepartment"

tags: gorm

爱评论不评论