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

再次查看:

相关推荐
Rookie也要加油26 分钟前
01_SQLite
数据库·sqlite
liuxin3344556630 分钟前
教育技术革新:SpringBoot在线教育系统开发
数据库·spring boot·后端
看山还是山,看水还是。1 小时前
MySQL 管理
数据库·笔记·mysql·adb
fishmemory7sec1 小时前
Koa2项目实战2(路由管理、项目结构优化)
数据库·mongodb·koa
momo小菜pa1 小时前
【MySQL 09】表的内外连接
数据库·mysql
Jasonakeke2 小时前
【重学 MySQL】四十九、阿里 MySQL 命名规范及 MySQL8 DDL 的原子化
数据库·mysql
程序猿小D2 小时前
第二百六十九节 JPA教程 - JPA查询OrderBy两个属性示例
java·开发语言·数据库·windows·jpa
小宇成长录2 小时前
Mysql:数据库和表增删查改基本语句
数据库·mysql·数据库备份
团儿.3 小时前
解锁MySQL高可用新境界:深入探索MHA架构的无限魅力与实战部署
数据库·mysql·架构·mysql之mha架构
程序猿小D3 小时前
第二百六十七节 JPA教程 - JPA查询AND条件示例
java·开发语言·前端·数据库·windows·python·jpa