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"
}

再次查看:

相关推荐
星恒随风6 小时前
MySQL 从零入门(五):MySQL 内置函数详解——日期、字符串、数学函数与实战案例
linux·数据库·笔记·sql·mysql
吴名氏.8 小时前
Java转AI Agent教程(第十三周)混合检索与重排
java·数据库·人工智能·ai·ai agent
爱码少年8 小时前
Springboot下如何将CSV文件数据导入H2、Mysql数据库表
数据库·mysql·csv
可乐ea9 小时前
智能体记忆该拆成几层:笔记、记忆表示与注入上下文
服务器·数据库·笔记·ai智能体·提示词工程·上下文工程·记忆系统
阿义有问题10 小时前
MySQL 迁移达梦全流程实战:DTS 七步图解 + 对象名全大写适配(附踩坑清单)
数据库
猫猫不是喵喵.13 小时前
从0到1创建一个微服务项目
java·数据库·微服务·1024程序员节
lsc_blog14 小时前
听到优化风声,先准备能由自己掌控的事
数据库·分布式·中间件·职场和发展·重构
墨痕诉清风14 小时前
SSRF漏洞实战记录+OSS桶命令执行+MCP漏洞
linux·服务器·数据库
Ashe81317 小时前
MySQL 慢日志先别急着加索引:三个指标能拦掉大半误判
数据库
ClouGence17 小时前
最基础的异构数据库 DDL 同步,我们踩过哪些坑?
数据库·mysql·postgresql