文章目录
- 一:连接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
,可以看到删除是软删除