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

再次查看:

相关推荐
月巴月巴白勺合鸟月半3 分钟前
Delphi 开发避坑终极指南:数据库 Decimal (18,6) 类型选择,别再用错 Double 和 Currency!
数据库
techdashen22 分钟前
一个徽章坏了,顺带扯出了 2.3 万个 feature
数据库·mysql
2301_8148098624 分钟前
CSS Grid布局如何解决图片溢出网格单元_设置object-fit与网格尺寸.txt
jvm·数据库·python
魂梦翩跹如雨34 分钟前
数据库的“契约” —— 约束(Constrains)
java·数据库·mysql
m0_6784854536 分钟前
如何在Bootstrap中自定义Modal的弹出动画效果
jvm·数据库·python
与衫42 分钟前
[特殊字符] 解决 DataHub 无法解析复杂 SQL 血缘的问题(gsp-datahub-sidecar 实测)
数据库·sql
m0_4939345343 分钟前
CSS如何禁止子元素浮动影响父级_设置父容器BFC属性
jvm·数据库·python
weixin_586061461 小时前
Golang怎么安装和配置开发环境_Golang环境搭建完整教程【总结】
jvm·数据库·python
m0_493934531 小时前
html标签怎么避免标签嵌套错误_div不能放在p内原因【详解】
jvm·数据库·python
2301_782659181 小时前
Go语言goroutine调度原理_Go语言GMP调度模型教程【高效】
jvm·数据库·python