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 get gorm.io/gorm
go get gorm.io/driver/mysql

定义modelrequst

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

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

在这里插入图片描述

二:增删改查

代码如:

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,可以看到删除是软删除
在这里插入图片描述

在这里插入图片描述

### 集成 GORMGin 框架 为了使开发人员能够更高效地构建 Web 应用程序,GinGORM 的组合提供了一个强大的解决方案。下面是一个简单的例子展示如何在 Gin集成 GORM 来连接 SQLite 数据库[^3]。 #### 初始化项目结构 首先创建一个新的 Go 文件夹作为项目的根目录,并初始化模块: ```bash mkdir gin-gorm-example && cd $_ go mod init example.com/gin-gorm-example ``` 安装所需的依赖项: ```bash go get -u github.com/gin-gonic/gin go get -u gorm.io/gorm go get -u gorm.io/driver/sqlite ``` #### 创建模型文件 `models/user.go` 定义一个 User 表对应的结构体用于表示数据记录。 ```go package models type User struct { ID uint `json:"id"` Name string `json:"name" gorm:"not null"` Email string `json:"email" gorm:"unique;not null"` } ``` #### 设置数据库配置 `config/database.go` 建立与 SQLite 数据库之间的链接。 ```go package config import ( "gorm.io/driver/sqlite" "gorm.io/gorm" ) var DB *gorm.DB func InitDB() error { var err error DB, err = gorm.Open(sqlite.Open("test.db"), &gorm.Config{}) if err != nil { return err } // 自动迁移模式 err = DB.AutoMigrate(&User{}) // 假设有一个名为 User 的模型 if err != nil { return err } return nil } ``` #### 构建 API 路由器 `main.go` 编写主函数启动 HTTP 服务器并注册 RESTful 接口。 ```go package main import ( "log" "github.com/gin-gonic/gin" "example.com/gin-gorm-example/config" "example.com/gin-gorm-example/models" ) func setupRouter() *gin.Engine { r := gin.Default() api := r.Group("/api/v1") { api.GET("/users", func(c *gin.Context) { var users []models.User config.DB.Find(&users) c.JSON(200, users) }) api.POST("/users", func(c *gin.Context) { var user models.User if err := c.ShouldBindJSON(&user); err == nil { config.DB.Create(&user) c.JSON(201, user) } else { c.JSON(400, gin.H{"error": err.Error()}) } }) } return r } func main() { if err := config.InitDB(); err != nil { log.Fatal(err) } router := setupRouter() log.Println("Server is running on port :8080...") router.Run(":8080") } ``` 上述代码展示了基本的 CRUD 功能,在实际应用中可能还需要考虑更多的细节比如错误处理、事务管理等。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值