5. gin集成Gorm

文章目录

代码地址:https://gitee.com/lymgoforIT/golang-trick/tree/master/24-gin-learning

本节主要介绍如何使用gin集成gorm,并完成用户的创建、修改、删除、查询等功能

本节主要是做最基本的连接和增删改查演示,具体使用细节可以查看官方文档:https://gorm.io/zh_CN/docs/

一:连接DB

引入gormmysql驱动

go 复制代码
go get gorm.io/gorm
go get gorm.io/driver/mysql

定义modelrequst

go 复制代码
type User struct {
	gorm.Model
	Name  string `json:"name" binding:"required"`
	Email string `json:"email" binding:"required"`
}

type UpdateUserInput struct {
	Name  string `json:"name"`
	Email string `json:"email"`
}

注:

  • binding taggin中绑定参数时的校验,将入参绑定到user对象时,对应字段为必传项
  • 上面UserUpdateUserInput看上去拥有的字段差不多,为什么还定义了两个结构体呢?原因是User为与DB交互的modelUpdateUserInput为接口的request,实际工作中modelrequest会有很多相似的字段,但一般不会完全一样,如request中可能会带有size,page等用于分页查询的字段。

连接DB

go 复制代码
package main

import (
	"github.com/gin-gonic/gin"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"net/http"
)

type User struct {
	gorm.Model
	Name  string `json:"name" binding:"required"`
	Email string `json:"email" binding:"required"`
}

type UpdateUserInput struct {
	Name  string `json:"name"`
	Email string `json:"email"`
}

func main() {

	dsn := "root:root@(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=true&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		panic(any("failed to connect to db"))
	}

	// 建表
	err = db.AutoMigrate(&User{})
	if err != nil {
		panic(any("create table err"))
	}
}

运行上述代码后,可看到DB中创建了users表,当model没有实现Table方法时,表名默认为在model结构体名字后面加s,因此此处model名为User,所以表名是users

二:增删改查

代码如:

go 复制代码
package main

import (
	"github.com/gin-gonic/gin"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"log"
	"net/http"
)

type User struct {
	gorm.Model
	Name  string `json:"name" binding:"required"`
	Email string `json:"email" binding:"required"`
}

type UpdateUserInput struct {
	Name  string `json:"name"`
	Email string `json:"email"`
}

func main() {

	dsn := "root:root@(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=true&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		panic(any("failed to connect to db"))
	}

	// 建表
	err = db.AutoMigrate(&User{})
	if err != nil {
		panic(any("create table err"))
	}

	r := gin.Default()

	r.GET("/ping", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"message": "pong",
		})
	})

	// Get /users
	r.GET("/users", func(c *gin.Context) {
		var users []User
		err := db.Find(&users).Error
		if err != nil {
			c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
				"error": "Failed to find users",
			})
			log.Println("Failed to find users")
			return
		}
		c.JSON(http.StatusOK, gin.H{"data": users})
	})

	// Post /users
	r.POST("/users", func(c *gin.Context) {
		var input User
		if err := c.ShouldBindJSON(&input); err != nil {
			c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
				"error": err.Error(),
			})
			return
		}

		if err := db.Create(&input).Error; err != nil {
			c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
				"error": "Failed to create users",
			})
			log.Println("Failed to create users")
			return
		}
		c.JSON(http.StatusOK, gin.H{"data": input})
	})

	// Put /users
	r.PUT("/users/:id", func(c *gin.Context) {
		var input UpdateUserInput
		if err := c.ShouldBindJSON(&input); err != nil {
			c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
				"error": "invalid params",
			})
			log.Println("invalid params")
			return
		}

		id := c.Param("id")
		var user User
		if err := db.Where("id = ?", id).Find(&user).Error; err != nil {
			c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
				"error": "Failed to Find user",
			})
			log.Println("Failed to Find user")
			return
		}
		if input.Name != "" {
			user.Name = input.Name
		}
		if input.Email != "" {
			user.Email = input.Email
		}

		if err := db.Save(&user).Error; err != nil {
			c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
				"error": "Failed to save user",
			})
			log.Println("Failed to save user")
			return
		}
		c.JSON(http.StatusOK, gin.H{"data": user})
	})

	// Delete /users
	r.DELETE("/users/:id", func(c *gin.Context) {
		id := c.Param("id")
		var user User
		if err := db.First(&user, id).Error; err != nil {
			c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
				"error": "Failed to Find user",
			})
			log.Println("Failed to Find user")
			return
		}
		if err := db.Delete(&user, id).Error; err != nil {
			c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
				"error": "Failed to delete user",
			})
			log.Println("Failed to delete user")
			return
		}

		c.JSON(http.StatusOK, gin.H{"data": "Delete user " + id})
	})

	r.Run(":8080")
}

三:使用PostMan测试

Get

因为表中还没有数据,所以查询结果是空的

Post
post请求,因为我们想用raw请求体,所以需要先设置ContentType请求头

构造请求体,发送请求

可以多创建几个用户,然后查看DB以及使用get请求查询所有用户

查看DB

使用Get请求查

Put

同样要注意设置ContentType请求头

id1的用户的邮箱改掉

Delete

同样要注意设置ContentType请求头

id1的用户删除

下图是点了两次发送后的结果,第一次就删除了,所以第二次删除显示找不到用户了

查询看下

继续删除id2的用户,然后查看DB,可以看到删除是软删除

相关推荐
不会写DN7 小时前
Gin 日志体系详解
前端·javascript·gin
Java面试题总结7 小时前
Gin 日志体系详解
gin
不会写DN7 小时前
Gin 实战入门:从环境搭建到企业级常用特性全解析
go·gin
Wzx19801216 小时前
gin_gorm
gin
必胜刻1 天前
Gin框架---框架CORS
http·https·gin
不会写DN1 天前
GORM 实战入门:从环境搭建到企业级常用特性全解析
sql·mysql·go·gin
onlywhz4 天前
【Golang】——Gin 框架中间件详解:从基础到实战
中间件·golang·gin
不会写DN4 天前
Gin 接收前端传参方式有几种?
开发语言·前端·gin
贺小涛8 天前
Golang Gin框架核心原理与架构解析
架构·golang·gin
yashuk15 天前
Go-Gin Web 框架完整教程
前端·golang·gin