【go从零单排】gin+gorm理解及实现CRUD-????代码

package main

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

// 定义用户模型
// User 结构体表示用户模型,包含 ID、Name 和 Email 字段。
type User struct {
	ID    uint   `json:"id" gorm:"primaryKey"`
	Name  string `json:"name"`
	Email string `json:"email"`
}

// 初始化数据库
func setupDatabase() *gorm.DB {
	db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
	if err != nil {
		panic("failed to connect database")
	}
	db.AutoMigrate(&User{}) // 自动迁移
	return db
}

// 创建用户
func createUser(c *gin.Context) { //参数:c *gin.Context 是 Gin 框架提供的上下文对象,包含请求和响应的相关信息。
	//数据库初始化:调用 setupDatabase() 函数,连接到 SQLite 数据库并返回数据库实例 db。
	db := setupDatabase()
	//定义变量:创建一个 User 类型的变量 user,用于存储从请求中绑定的数据。
	var user User
	//c.ShouldBindJSON(&user):尝试将请求体中的 JSON 数据绑定到 user 变量。
	//如果请求体不符合预期格式,ShouldBindJSON 将返回错误。
	if err := c.ShouldBindJSON(&user); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	//创建记录:使用 GORM 的 Create 方法将 user 变量中的数据插入到数据库中。
	db.Create(&user)
	//成功响应:如果用户创建成功,返回 HTTP 状态码 200 OK 和新创建的用户数据(包括自动生成的 ID 等信息)。
	c.JSON(http.StatusOK, user)
}

// 获取所有用户
// c *gin.Context 是 Gin 框架提供的上下文对象,包含请求和响应的相关信息。
func getUsers(c *gin.Context) {
	db := setupDatabase()
	//创建一个切片 users,类型为 User,用于存储从数据库中查询到的用户记录。
	var users []User
	//使用 GORM 的 Find 方法查询所有用户记录,并将结果存储到 users 切片中。Find 方法会自动填充切片中的数据。
	db.Find(&users)
	//如果查询成功,返回 HTTP 状态码 200 OK 和查询到的用户数据(users 切片)
	c.JSON(http.StatusOK, users)
}

// 根据 ID 查询用户
func getUserByID(c *gin.Context) {
	db := setupDatabase()
	//从 URL 路径中获取用户的 ID。假设你的路由是 /users/:id,c.Param("id") 将提取该 ID。
	id := c.Param("id") // 从 URL 路径中获取用户 ID

	var user User
	//使用 GORM 的 First 方法根据 ID 查询用户。如果用户存在,user 变量将被填充;如果找不到,err 将不为 nil。
	if err := db.First(&user, id).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "用户未找到"})
		return
	}

	c.JSON(http.StatusOK, user) // 返回用户信息
}

// 更新用户
// updateUser,用于处理更新用户信息的请求。
// updateUser,用于处理更新用户信息的请求。
func updateUser(c *gin.Context) {
	db := setupDatabase()
	var user User
	//c.ShouldBindJSON(&user):尝试将请求体中的 JSON 数据绑定到 user 变量。
	//如果请求体不符合预期格式,ShouldBindJSON 将返回错误。
	if err := c.ShouldBindJSON(&user); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	//使用 GORM 的 Where 方法找到 ID 为 user.ID 的记录,并使用 Updates 方法更新该用户的所有字段。
	if err := db.Where("id = ?", user.ID).Updates(user).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新失败: " + err.Error()})
		return
	}
	c.JSON(http.StatusOK, user)
}

// 更新用户的 email 字段为空
func updateEmail(c *gin.Context) {
	db := setupDatabase()
	id := c.Param("id") // 从 URL 中获取用户 ID
	DefaultEmail := "www.example.com"
	// 创建一个更新结构体,只包含需要更新的字段
	updateData := struct {
		Email *string `json:"email"` // 使用指针类型,可以设置为 nil
	}{
		Email: &DefaultEmail, // 设置 email 为 DefaultEmail
	}

	// 执行更新操作
	if err := db.Model(&User{}).Where("id = ?", id).Updates(updateData).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新失败: " + err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "用户 email 已设置为指定Email"})
}

// 删除用户
func deleteUser(c *gin.Context) {
	db := setupDatabase()
	id := c.Param("id")
	//&User{}:这里传入的是一个 User 结构体的指针。GORM 需要知道要删除哪个模型的记录。
	//id:这是要删除的记录的主键(通常是用户的 ID)。GORM 会根据这个 ID 找到对应的记录并进行删除。
	if err := db.Delete(&User{}, id).Error; err != nil {
		//如果 db.Delete(...) 返回了一个错误(即 err 不为 nil),则进入 if 语句块,通常会处理错误情况,比如返回一个 JSON 响应给客户端,表示删除失败。
		c.JSON(http.StatusInternalServerError, gin.H{"error": "删除失败: " + err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"message": "用户已删除"})
}

func main() {
	r := gin.Default()

	// 定义路由
	r.POST("/users", createUser)       // 创建用户
	r.GET("/users", getUsers)          // 获取所有用户
	r.PUT("/users", updateUser)        // 更新用户
	r.DELETE("/users/:id", deleteUser) // 删除用户
	r.GET("/users/:id", getUserByID)   //根据ID查询用户
	r.PUT("/users/:id", updateEmail)   //根据ID跟新用户指定字段
	// 启动服务器
	r.Run(":9080")
}
上一篇:速盾:cdn 支持 php 吗?


下一篇:Brave127编译指南 Windows篇:部署Node.js(五)