Gin之GORM的表关联查询操作详解

前期工作:

先查看下要操作的两张表:

carton

carton_cate

//关系如下:

// 一个章节对应一个动漫(一对一;两种方法:belong to;has one)

// 一个动漫可以对应多个章节(一对多)

1、创建路由(cartonRoutes)

Go 复制代码
package routers

import (
	"gindemo04/controllers/admin"

	"github.com/gin-gonic/gin"
)

func CartonController(r *gin.Engine) {

	cartonRouters := r.Group("/carton")
	{
		cartonRouters.GET("/test", admin.CartonController{}.Test)
		
	}
}

2、控制文件创建(cartonController.go)

Go 复制代码
package admin

import (
	"gindemo04/models"
	"net/http"
	"github.com/gin-gonic/gin"
)

type CartonController struct {
	BaseController
}

func (con CartonController) Test(c *gin.Context) {



}

3、入口文件绑定(main.go)

4、固定要操作的表

/models/carton:

Go 复制代码
package models
//carton可以查询卡通章节,获取章节对应的分类要在cartoncate
type Carton struct { //这样默认操作的是cartons表
	Id int
	Title string
	CartonCateId int  //1、cartonCateId默认为外键(在建立关系后,默认以主表+id作为外键)
	Status int


}

//固定要操作的表名
func (Carton) TableName() string {
	return "carton"
}

Belongs To | GORM - The fantastic ORM library for Golang, aims to be developer friendly.https://gorm.io/zh_CN/docs/belongs_to.html

/models/carton_cate:

//foreignKey外键 如果是表名称加上Id默认也可以不配置,如果不是需要使用`gorm:"foreignKey:+你的外键名称配置

//references表示的是主键 默认就是Id 如果是Id的话可以不配置

Go 复制代码
package models

//CartonCate查询分类,获取卡通分类下的章节


type CartonCate struct { //这样默认操作的是articles表
	Id int  //默认为主键
	Title string
	Status int
	
}

//固定要操作的表名
func (CartonCate) TableName() string {
	return "carton_cate"
}

开始操作:

1、获取所有的动漫章节

cartonController.go:

Go 复制代码
package admin

import (
	"gindemo04/models"
	"net/http"
	"github.com/gin-gonic/gin"
)

type CartonController struct {
	BaseController
}
//关系如下:
// 一个章节对应一个动漫(一对一;两种方法:belong to;has one)
// 一个动漫可以对应多个章节(一对多)
func (con CartonController) Test(c *gin.Context) {
//1、获取所有章节
	cartonList := []models.Carton{}
	models.DB.Find(&cartonList)
	c.JSON(http.StatusOK, gin.H{
		"List": cartonList,
	})


}

2、获取角色对应的动漫分类

/models/carton:

Go 复制代码
package models
//carton可以查询卡通章节,获取章节对应的分类要在cartoncate
type Carton struct { //这样默认操作的是cartons表
	Id int
	Title string
	CartonCateId int  //1、cartonCateId默认为外键(在建立关系后,默认以主表+id作为外键)
	Status int
	CartonCate CartonCate 


}

//固定要操作的表名
func (Carton) TableName() string {
	return "carton"
}

cartonController.go:

Go 复制代码
package admin

import (
	"gindemo04/models"
	"net/http"
	"github.com/gin-gonic/gin"
)

type CartonController struct {
	BaseController
}
//关系如下:
// 一个章节对应一个动漫(一对一;两种方法:belong to;has one)
// 一个动漫可以对应多个章节(一对多)
func (con CartonController) Test(c *gin.Context) {
//1、获取所有章节
	// cartonList := []models.Carton{}
	// models.DB.Find(&cartonList)
	// c.JSON(http.StatusOK, gin.H{
	// 	"List": cartonList,
	// })


	//2、获取角色对应的动漫分类
	cartonList1 := []models.Carton{}
	//preload是用来加载另外一张表的,这里的cartoncate是在carton.go内配置的
	models.DB.Preload("CartonCate").Find(&cartonList1)
	c.JSON(http.StatusOK, gin.H{
		"List": cartonList1,
	})
}

这里需要注意:你preload内的是需要和你在外部caton结构体是一致的,大小写,不然找不到

3、重写外键的操作

Belongs To | GORM - The fantastic ORM library for Golang, aims to be developer friendly.https://gorm.io/zh_CN/docs/belongs_to.html

caton有默认的主键为ID,但是catoncate没有了对应的caton_cate_id做外键了(这里成为了cate_id),需要操作修改一下

/models/caton.go:

Go 复制代码
package models
//carton可以查询卡通章节,获取章节对应的分类要在cartoncate
type Carton struct { //这样默认操作的是cartons表
	Id int
	Title string
	CateId int  //1、cartonCateId默认为外键(在建立关系后,默认以主表+id作为外键)
	Status int
	CartonCate CartonCate `gorm:"foreignKey:CateId;references:Id"` 
	// 2、没有1的情况下如何处理(重写外键)

}

//固定要操作的表名
func (Carton) TableName() string {
	return "carton"
}

cartonController.go:

Go 复制代码
package admin

import (
	"gindemo04/models"
	"net/http"
	"github.com/gin-gonic/gin"
)

type CartonController struct {
	BaseController
}
//关系如下:
// 一个章节对应一个动漫(一对一;两种方法:belong to;has one)
// 一个动漫可以对应多个章节(一对多)
func (con CartonController) Test(c *gin.Context) {
//1、获取所有章节
	// cartonList := []models.Carton{}
	// models.DB.Find(&cartonList)
	// c.JSON(http.StatusOK, gin.H{
	// 	"List": cartonList,
	// })


	//2、获取角色对应的动漫分类
	cartonList1 := []models.Carton{}
	//preload是用来加载另外一张表的,这里的cartoncate是在carton.go内配置的
	models.DB.Preload("CartonCate").Find(&cartonList1)
	c.JSON(http.StatusOK, gin.H{
		"List": cartonList1,
	})
}

4、依据动漫分类看其所属章节

4.1、先获取章节对应动漫的分类

cartonController.go:

Go 复制代码
package admin

import (
	"gindemo04/models"
	"net/http"
	"github.com/gin-gonic/gin"
)

type CartonController struct {
	BaseController
}
//关系如下:
// 一个章节对应一个动漫(一对一;两种方法:belong to;has one)
// 一个动漫可以对应多个章节(一对多)
func (con CartonController) Test(c *gin.Context) {
//1、获取所有章节
	// cartonList := []models.Carton{}
	// models.DB.Find(&cartonList)
	// c.JSON(http.StatusOK, gin.H{
	// 	"List": cartonList,
	// })


	//2、获取角色对应的动漫分类
	// cartonList1 := []models.Carton{}
	// //preload是用来加载另外一张表的,这里的articlecate是在article.go内配置的
	// models.DB.Preload("CartonCate").Find(&cartonList1)
	// c.JSON(http.StatusOK, gin.H{
	// 	"List": cartonList1,
	// })

	//4、依据分类看分类下文章
	//4.1、先获取caton的分类
	cartonList2 := []models.Carton{}
	models.DB.Preload("CartonCate").Find(&cartonList2)
	c.JSON(http.StatusOK, gin.H{
		"List": 	cartonList2,
	})
}

根据这里的cateid可以获取对应动漫

4.2、依据分类看分类下章节

caton.go

Go 复制代码
package models
//carton可以查询卡通章节,获取章节对应的分类要在cartoncate
type Carton struct { //这样默认操作的是cartons表
	Id int
	Title string
	CateId int  //1、cartonCateId默认为外键(在建立关系后,默认以主表+id作为外键)
	Status int
	CartonCate CartonCate `gorm:"foreignKey:CateId;references:Id"` 
	// 2、没有1的情况下如何处理(重写外键)

}

//固定要操作的表名
func (Carton) TableName() string {
	return "carton"
}

catonCate.go

Go 复制代码
package models

//CartonCate查询分类,获取卡通分类下的章节
//foreignKey外键 如果是表名称加上Id默认也可以不配置,如果不是需要使用`gorm:"foreignKey:+你的外键名称配置
//references表示的是主键 默认就是Id 如果是Id的话可以不配置

type CartonCate struct { //这样默认操作的是articles表
	Id int  //默认为主键 ()
	Title string
	Status int
	Carton []Carton  `gorm:"foreignKey:CateId;references:Id"`
}

//固定要操作的表名
func (CartonCate) TableName() string {
	return "carton_cate"
}

cartonController.go:

Go 复制代码
package admin

import (
	"gindemo04/models"
	"net/http"
	"github.com/gin-gonic/gin"
)

type CartonController struct {
	BaseController
}
//关系如下:
// 一个章节对应一个动漫(一对一;两种方法:belong to;has one)
// 一个动漫可以对应多个章节(一对多)
func (con CartonController) Test(c *gin.Context) {
//1、获取所有章节
	// cartonList := []models.Carton{}
	// models.DB.Find(&cartonList)
	// c.JSON(http.StatusOK, gin.H{
	// 	"List": cartonList,
	// })


	//2、获取角色对应的动漫分类
	// cartonList1 := []models.Carton{}
	// //preload是用来加载另外一张表的,这里的articlecate是在article.go内配置的
	// models.DB.Preload("CartonCate").Find(&cartonList1)
	// c.JSON(http.StatusOK, gin.H{
	// 	"List": cartonList1,
	// })

	//4、依据分类看分类下文章
	//4.1、先获取caton的分类
	// cartonList2 := []models.Carton{}
	// models.DB.Preload("CartonCate").Find(&cartonList2)
	// c.JSON(http.StatusOK, gin.H{
	// 	"List": 	cartonList2,
	// })
	//4.2、has many 一对多
	cartonList3 := []models.CartonCate{}
	models.DB.Preload("Carton").Find(&cartonList3)
	c.JSON(http.StatusOK, gin.H{
		"List": 	cartonList3,
	})
	

}

//操作完成后看到一个空的cartoncate,去到carton.go将其注释掉

注释后的 carton.go

Go 复制代码
package models
//carton可以查询卡通章节,获取章节对应的分类要在cartoncate
type Carton struct { //这样默认操作的是cartons表
	Id int
	Title string
	CateId int  //1、cartonCateId默认为外键(在建立关系后,默认以主表+id作为外键)
	Status int
	// CartonCate CartonCate `gorm:"foreignKey:CateId;references:Id"` 
	// 2、没有1的情况下如何处理(重写外键)

}

//固定要操作的表名
func (Carton) TableName() string {
	return "carton"
}

再次查看:

相关推荐
倔强的石头_7 小时前
kingbase备份与恢复实战(二)—— sys_dump库级逻辑备份与恢复(Windows详细步骤)
数据库
stark张宇12 小时前
微服务架构必备:Gin + gRPC + Consul + Nacos + GORM 打造用户服务
微服务·gin·grpc
jiayou642 天前
KingbaseES 实战:深度解析数据库对象访问权限管理
数据库
李广坤2 天前
MySQL 大表字段变更实践(改名 + 改类型 + 改长度)
数据库
刀法如飞3 天前
一款Go语言Gin框架MVC脚手架,满足大部分场景
go·mvc·gin
爱可生开源社区3 天前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba
随逸1774 天前
《从零搭建NestJS项目》
数据库·typescript
花酒锄作田4 天前
Gin 框架中的规范响应格式设计与实现
golang·gin
加号34 天前
windows系统下mysql多源数据库同步部署
数据库·windows·mysql
シ風箏4 天前
MySQL【部署 04】Docker部署 MySQL8.0.32 版本(网盘镜像及启动命令分享)
数据库·mysql·docker