文章目录
- 一:连接DB
- 二:增删改查
- 三:使用PostMan测试
代码地址:https://gitee.com/lymgoforIT/golang-trick/tree/master/24-gin-learning
本节主要介绍如何使用gin集成gorm,并完成用户的创建、修改、删除、查询等功能
本节主要是做最基本的连接和增删改查演示,具体使用细节可以查看官方文档:https://gorm.io/zh_CN/docs/
一:连接DB
引入gorm与mysql驱动
go get gorm.io/gorm
go get gorm.io/driver/mysql
定义model和requst
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 tag为gin中绑定参数时的校验,将入参绑定到user对象时,对应字段为必传项- 上面
User和UpdateUserInput看上去拥有的字段差不多,为什么还定义了两个结构体呢?原因是User为与DB交互的model,UpdateUserInput为接口的request,实际工作中model和request会有很多相似的字段,但一般不会完全一样,如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请求头
将id为1的用户的邮箱改掉

Delete
同样要注意设置ContentType请求头
将id为1的用户删除
下图是点了两次发送后的结果,第一次就删除了,所以第二次删除显示找不到用户了

查询看下

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





















