【gin学习笔记】08gorm结构体的创建和结合gin的使用

本文学习视频 https://www.bilibili.com/video/BV1kC4y1t7Qi/?spm_id_from=333.788

tag设置

  • 设置主键: gorm:“primary_key”
  • 自定义字段名称: column:user_id
  • 忽略: “-”
  • 指定数据类型t:ype:varchar(100)
  • 非空:not null
  • 创建索引: index
  • 设置外键:ForeignKey
  • 关联外键:AssociationForeignKey
  • 多对多:many2many:表面

自定义表名

一般如果不指定的话,表名就是结构体的名字,如果想自定义表表名要用到TableName()这个方法

tag设置和自定义表名的代码如下:

package main

import (
	_ "github.com/go-sql-driver/mysql"
	"github.com/jinzhu/gorm"
)

type User struct {
	gorm.Model
	//设置主键,字段名称设置为user_name,字段类型设置为varchar长度为100
	Name string `gorm:"primary_key;column:user_name;type:varchar(100)"`
	Age  int
}

//将表名设置为my_users
func (u User) TableName() string {
	return "my_users"
}

func main() {
	db, _ := gorm.Open("mysql",
		"root:root@/ginclass?charset=utf8mb4&parseTime=True&loc=Local")
	defer db.Close()
	db.AutoMigrate(&User{})
}

运行后创建出来的表结构如下:
在这里插入图片描述

重点:结构体声明 1对1 1对多 多对多

  • 多对多使用many2many关键字
  • 分页查询使用count记录总数,使用limit和offset指定记录位置
  • 预加载 preload

举例:
一对一 一个学生有一个身份证
一对多 一个学生有一个班级,一个班级有多个学生
多对多 一个学生有多个老师 一个老师有多个学生

下面举例来创建一些表并生成一些数据

package main

import (
	_ "github.com/go-sql-driver/mysql"
	"github.com/jinzhu/gorm"
)

//一对一:学生每个人有一张IDCard,IDCard通过ID来知道是哪个学生的,这是一对一关系
//一对多:班级有多个学生,学生通过ClassID知道自己在哪个班
//多对多:老师有多个学生,并且知道学生的ID;学生有多个老师,并且知道老师的ID

type Class struct {
	gorm.Model
	ClassName string
	Students  []Student //一个班级有多个学生
}

type Student struct {
	gorm.Model
	StudentName string
	ClassID     uint      //每个学生都有一个班级
	IDCard      IDCard    //每个学生都有一张IDCard
	Teachers    []Teacher `gorm:"many2many:student_teachers;"` //一个学生有多个老师 student_teachers是关联表
}

type Teacher struct {
	gorm.Model
	TeacherName string
	StudentID   uint
	Students    []Student `gorm:"many2many:student_teachers;"` //一个老师有多个学生
}

type IDCard struct {
	gorm.Model
	StudentID uint //每个学生有一个IDcard 与学生的ID进行关联
	Num       int
}

func main() {
	db, _ := gorm.Open("mysql",
		"root:root@/ginclass?charset=utf8mb4&parseTime=True&loc=Local")
	defer db.Close()
	
	//创建Teacher表,Class表,Student表,IDCard表,还有之前的关联表student_teachers
	db.AutoMigrate(&Teacher{}, &Class{}, &Student{}, &IDCard{})
	
	i := IDCard{
		Num: 123456,
	}
	//创建一个学生
	s := Student{
		StudentName: "kaka",
		IDCard:      i,
	}
	//创建一个老师
	t := Teacher{
		TeacherName: "张老师",
	}
	//创建一个班级
	c := Class{
		ClassName: "文科班",
		Students:  []Student{s},
	}
	_ = db.Create(&c).Error //把班级信息写到数据库
	_ = db.Create(&t).Error //把老师信息写到数据库
}

运行后会在数据库中看到如下信息:
在这里插入图片描述
class表中创建了一条名字为文科班的数据,id为1
在这里插入图片描述
学生表中创建了一条学生名字为kaka的数据,班级id为1,学生id为1
在这里插入图片描述
IDCard表中创建了一条卡号为123456的数据
在这里插入图片描述
teacher表中也相应创建了一条数据
但是many2many关联表student_teachers里面没有数据,这里面的数据怎么创建呢?
代码如下,只需要在teacher中加入Students: []Student{s} 即可

//创建一个老师
	t := Teacher{
		TeacherName: "张老师",
		Students:    []Student{s},
	}

运行后结果如下
在这里插入图片描述
创建了id为2的老师数据

在这里插入图片描述
创建了id为3的student数据
在这里插入图片描述
teacher 2 和student 3对应上了

使用gin接受参数并经过处理入库或返回

我们创建一个/student路由

package main

import (
	"github.com/gin-gonic/gin"
	_ "github.com/go-sql-driver/mysql"
	"github.com/jinzhu/gorm"
)

//一对一:学生每个人有一张IDCard,IDCard通过ID来知道是哪个学生的,这是一对一关系
//一对多:班级有多个学生,学生通过ClassID知道自己在哪个班
//多对多:老师有多个学生,并且知道学生的ID;学生有多个老师,并且知道老师的ID

type Class struct {
	gorm.Model
	ClassName string
	Students  []Student //一个班级有多个学生
}

type Student struct {
	gorm.Model
	StudentName string
	ClassID     uint      //每个学生都有一个班级
	IDCard      IDCard    //每个学生都有一张IDCard
	Teachers    []Teacher `gorm:"many2many:student_teachers;"` //一个学生有多个老师 student_teachers是关联表
}

type Teacher struct {
	gorm.Model
	TeacherName string
	StudentID   uint
	Students    []Student `gorm:"many2many:student_teachers;"` //一个老师有多个学生
}

type IDCard struct {
	gorm.Model
	StudentID uint //每个学生有一个IDcard 与学生的ID进行关联
	Num       int
}

func main() {
	db, _ := gorm.Open("mysql",
		"ginclass:Fjj@sh123@/ginclass?charset=utf8mb4&parseTime=True&loc=Local")
	defer db.Close()

	r := gin.Default()
	r.POST("/student", func(c *gin.Context) {
		var student Student
		_ = c.BindJSON(&student)
		db.Create(&student)
	})
	r.Run(":8888")
}

在这里插入图片描述
post请求的header中加上 Content-Type applicaiton/json,用来告诉服务端消息主体是序列化后的 JSON 字符串。
在这里插入图片描述
Body中传入以上信息,运行后数据正常入库。在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

用gin路由查询数据库里的数据

创建一个get路由

package main

import (
	"github.com/gin-gonic/gin"
	_ "github.com/go-sql-driver/mysql"
	"github.com/jinzhu/gorm"
)

//一对一:学生每个人有一张IDCard,IDCard通过ID来知道是哪个学生的,这是一对一关系
//一对多:班级有多个学生,学生通过ClassID知道自己在哪个班
//多对多:老师有多个学生,并且知道学生的ID;学生有多个老师,并且知道老师的ID

type Class struct {
	gorm.Model
	ClassName string
	Students  []Student //一个班级有多个学生
}

type Student struct {
	gorm.Model
	StudentName string
	ClassID     uint      //每个学生都有一个班级
	IDCard      IDCard    //每个学生都有一张IDCard
	Teachers    []Teacher `gorm:"many2many:student_teachers;"` //一个学生有多个老师 student_teachers是关联表
}

type Teacher struct {
	gorm.Model
	TeacherName string
	StudentID   uint
	Students    []Student `gorm:"many2many:student_teachers;"` //一个老师有多个学生
}

type IDCard struct {
	gorm.Model
	StudentID uint //每个学生有一个IDcard 与学生的ID进行关联
	Num       int
}

func main() {
	db, _ := gorm.Open("mysql",
		"ginclass:Fjj@sh123@/ginclass?charset=utf8mb4&parseTime=True&loc=Local")
	defer db.Close()

	r := gin.Default()
	r.POST("/student", func(c *gin.Context) {
		var student Student
		_ = c.BindJSON(&student)
		db.Create(&student)
	})

	r.GET("/student/:ID", func(c *gin.Context) {
		id := c.Param("ID") //从前端拿到ID,并赋给id
		var student Student
		db.First(&student, "id=?", id) //通过id去数据库里查询一条数据并把结果返回给student
		//将student返回前端
		c.JSON(200, gin.H{
			"学生信息": student,
		})
	})

	r.Run(":8888")
}

在这里插入图片描述
查询id为2的学生信息,可以看到返回的只有基础信息,其他的信息都没返回。为了将其他信息也查出来就需要preload

db.Preload("Teachers").Preload("IDCard").First(&student, "id=?", id) //通过id去数据库里查询一条数据并把结果返回给student
		//将student返回前端

db.First前面加Preload
重新get下会发现返回的信息变多了,结果如下:

{
    "学生信息": {
        "ID": 2,
        "CreatedAt": "2022-05-12T23:35:38+08:00",
        "UpdatedAt": "2022-05-12T23:35:38+08:00",
        "DeletedAt": null,
        "StudentName": "Jack",
        "ClassID": 1,
        "IDCard": {
            "ID": 4,
            "CreatedAt": "2022-05-12T23:35:38+08:00",
            "UpdatedAt": "2022-05-12T23:35:38+08:00",
            "DeletedAt": null,
            "StudentID": 2,
            "Num": 666666
        },
        "Teachers": [
            {
                "ID": 3,
                "CreatedAt": "2022-05-12T23:35:38+08:00",
                "UpdatedAt": "2022-05-12T23:35:38+08:00",
                "DeletedAt": null,
                "TeacherName": "语文老师",
                "StudentID": 0,
                "Students": null
            },
            {
                "ID": 4,
                "CreatedAt": "2022-05-12T23:35:38+08:00",
                "UpdatedAt": "2022-05-12T23:35:38+08:00",
                "DeletedAt": null,
                "TeacherName": "英语老师",
                "StudentID": 0,
                "Students": null
            }
        ]
    }
}

接下来通过class把students都查出来

r.GET("/class/:ID", func(c *gin.Context) {
		id := c.Param("ID") //从前端拿到ID,并赋给id
		var class Class
		db.First(&class, "id=?", id) //通过id去数据库里查询一条数据并把结果返回给class
		//将class返回前端
		c.JSON(200, gin.H{
			"班级信息": class,
		})
	})

查询后返回结果如下
在这里插入图片描述
可以看到没有Students信息,接下来我们通过preload将students信息查询出来。

r.GET("/class/:ID", func(c *gin.Context) {
		id := c.Param("ID") //从前端拿到ID,并赋给id
		var class Class
		db.Preload("Students").First(&class, "id=?", id) //通过id去数据库里查询一条数据并把结果返回给class
		//将class返回前端
		c.JSON(200, gin.H{
			"班级信息": class,
		})
	})

结果如下

{
    "班级信息": {
        "ID": 1,
        "CreatedAt": "2022-05-12T22:06:51+08:00",
        "UpdatedAt": "2022-05-12T22:06:51+08:00",
        "DeletedAt": null,
        "ClassName": "文科班",
        "Students": [
            {
                "ID": 2,
                "CreatedAt": "2022-05-12T23:35:38+08:00",
                "UpdatedAt": "2022-05-12T23:35:38+08:00",
                "DeletedAt": null,
                "StudentName": "Jack",
                "ClassID": 1,
                "IDCard": {
                    "ID": 0,
                    "CreatedAt": "0001-01-01T00:00:00Z",
                    "UpdatedAt": "0001-01-01T00:00:00Z",
                    "DeletedAt": null,
                    "StudentID": 0,
                    "Num": 0
                },
                "Teachers": null
            }
        ]
    }
}

可以看到students信息确实出来了,但是student关联的信息没有查出来。
这个就涉及到嵌套预加载的问题。

r.GET("/class/:ID", func(c *gin.Context) {
		id := c.Param("ID") //从前端拿到ID,并赋给id
		var class Class
		db.Preload("Students").Preload("Students.IDCard").Preload("Students.Teachers").First(&class, "id=?", id) //通过id去数据库里查询一条数据并把结果返回给class
		//将class返回前端
		c.JSON(200, gin.H{
			"班级信息": class,
		})
	})

嵌套了Students.IDCard, Students.Teachers
返回结果如下

{
    "班级信息": {
        "ID": 1,
        "CreatedAt": "2022-05-12T22:06:51+08:00",
        "UpdatedAt": "2022-05-12T22:06:51+08:00",
        "DeletedAt": null,
        "ClassName": "文科班",
        "Students": [
            {
                "ID": 2,
                "CreatedAt": "2022-05-12T23:35:38+08:00",
                "UpdatedAt": "2022-05-12T23:35:38+08:00",
                "DeletedAt": null,
                "StudentName": "Jack",
                "ClassID": 1,
                "IDCard": {
                    "ID": 4,
                    "CreatedAt": "2022-05-12T23:35:38+08:00",
                    "UpdatedAt": "2022-05-12T23:35:38+08:00",
                    "DeletedAt": null,
                    "StudentID": 2,
                    "Num": 666666
                },
                "Teachers": [
                    {
                        "ID": 3,
                        "CreatedAt": "2022-05-12T23:35:38+08:00",
                        "UpdatedAt": "2022-05-12T23:35:38+08:00",
                        "DeletedAt": null,
                        "TeacherName": "语文老师",
                        "StudentID": 0,
                        "Students": null
                    },
                    {
                        "ID": 4,
                        "CreatedAt": "2022-05-12T23:35:38+08:00",
                        "UpdatedAt": "2022-05-12T23:35:38+08:00",
                        "DeletedAt": null,
                        "TeacherName": "英语老师",
                        "StudentID": 0,
                        "Students": null
                    }
                ]
            }
        ]
    }
}

其他的gorm操作可以参考https://learnku.com/docs/gorm/v2

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用gingorm框架进行后台开发是指在构建后台应用程序时,采用了gingorm这两个开源框架来帮助实现快速、高效且可靠的开发。 首先,gin是一个轻量级的Web框架,它基于Go语言的net/http包进行封装,并提供了更简洁的API和更快的性能。使用gin框架可以轻松地处理HTTP请求和响应,定义路由和中间件,实现参数绑定和验证,并且具备灵活的扩展性和高并发处理能力。 其次,gorm是一个开源的Go语言ORM(对象关系映射)库,它提供了一种方便的方式来操作数据库,将数据库表和Go语言的结构体进行映射,实现了数据的增删改查操作。使用gorm可以简化数据库操作的代码,提高开发效率,还支持事务处理、查询构造器等高级功能。 使用gingorm框架进行后台开发有以下几个优势: 1. 快速开发:gin框架提供了简洁的API和高性能,可以大大加速开发过程。结合gorm框架的ORM功能,可以方便地进行数据库操作,减少了与数据库交互的代码量,提高了开发效率。 2. 灵活扩展:gin框架支持中间件,在请求的不同阶段插入自定义的处理逻辑,可以实现身份验证、日志记录、错误处理等功能。gorm框架也支持自定义回调函数,可以在数据库操作的前后执行特定的业务逻辑,提供了灵活扩展的能力。 3. 高性能:gin框架底层采用了轻量级的路由引擎和快速的HTTP处理器,以及简洁的API设计,使得性能表现出色。同时,gorm框架通过合理的SQL语句生成和查询优化,能够保证数据库操作的效率。 综上所述,使用gingorm框架进行后台开发可以提供快速、高效、可靠的开发体验,同时拥有灵活的扩展性和良好的性能表现,非常适合构建中小型的后台应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值