如何用Golang实现用户资料管理

来源:站长平台作者:半夏头衔:草根站长
导读:本期聚焦于小伙伴创作的《如何用Golang实现用户资料管理》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何用Golang实现用户资料管理》有用,将其分享出去将是对创作者最好的鼓励。

用户资料管理是多数业务系统的基础功能,核心需求包括用户资料的创建、查询、更新、删除,以及对应的数据合法性校验和存储逻辑。下面我们将基于Golang生态的常用组件,完整实现一套可用的用户资料管理功能。

如何用Golang实现用户资料管理

环境准备与依赖安装

实现功能前需要先准备基础环境,首先确保本地已经安装Golang 1.18及以上版本,同时安装MySQL数据库用于数据存储。接下来初始化项目并安装所需依赖:

# 初始化Go模块
go mod init user_profile_demo
# 安装gin框架
go get -u github.com/gin-gonic/gin
# 安装MySQL驱动
go get -u gorm.io/driver/mysql
# 安装GORM ORM库
go get -u gorm.io/gorm
# 安装参数校验库
go get -u github.com/go-playground/validator/v10

数据库表设计

用户资料表需要存储用户的基础信息,设计如下字段,使用GORM的模型定义方式:

package model

import (
    "gorm.io/gorm"
    "time"
)

// UserProfile 用户资料模型
type UserProfile struct {
    ID        uint           `gorm:"primarykey" json:"id"`
    Username  string         `gorm:"type:varchar(50);not null;uniqueIndex" json:"username"` // 用户名 唯一
    Nickname  string         `gorm:"type:varchar(50)" json:"nickname"`                       // 昵称
    Email     string         `gorm:"type:varchar(100);uniqueIndex" json:"email"`             // 邮箱 唯一
    Phone     string         `gorm:"type:varchar(20)" json:"phone"`                          // 手机号
    Avatar    string         `gorm:"type:varchar(255)" json:"avatar"`                        // 头像地址
    CreatedAt time.Time      `json:"created_at"`
    UpdatedAt time.Time      `json:"updated_at"`
    DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}

数据库连接初始化

封装数据库连接的初始化逻辑,方便后续在业务中使用:

package global

import (
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
    "log"
)

var DB *gorm.DB

// InitDB 初始化MySQL连接
func InitDB() {
    dsn := "root:password@tcp(127.0.0.1:3306)/user_db?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
    if err != nil {
        log.Fatalf("数据库连接失败: %v", err)
    }
    // 自动迁移表结构
    err = db.AutoMigrate(&model.UserProfile{})
    if err != nil {
        log.Fatalf("表结构迁移失败: %v", err)
    }
    DB = db
    log.Println("数据库连接成功")
}

请求参数校验定义

使用validator库定义创建和更新用户资料的请求参数结构体,实现自动校验:

package request

import "github.com/go-playground/validator/v10"

// CreateProfileReq 创建用户资料请求参数
type CreateProfileReq struct {
    Username string `json:"username" validate:"required,min=3,max=50"` // 用户名必填 长度3-50
    Nickname string `json:"nickname" validate:"max=50"`                // 昵称最长50
    Email    string `json:"email" validate:"required,email"`           // 邮箱必填 格式校验
    Phone    string `json:"phone" validate:"omitempty,e164"`           // 手机号可选 符合E164格式
    Avatar   string `json:"avatar" validate:"omitempty,url"`           // 头像可选 符合URL格式
}

// UpdateProfileReq 更新用户资料请求参数
type UpdateProfileReq struct {
    Nickname string `json:"nickname" validate:"max=50"`
    Email    string `json:"email" validate:"omitempty,email"`
    Phone    string `json:"phone" validate:"omitempty,e164"`
    Avatar   string `json:"avatar" validate:"omitempty,url"`
}

// Validate 参数校验方法
func (r *CreateProfileReq) Validate() error {
    validate := validator.New()
    return validate.Struct(r)
}

func (r *UpdateProfileReq) Validate() error {
    validate := validator.New()
    return validate.Struct(r)
}

业务接口实现

创建用户资料接口

实现用户资料的创建逻辑,包含参数校验、重复校验和数据库写入:

package handler

import (
    "net/http"
    "user_profile_demo/global"
    "user_profile_demo/model"
    "user_profile_demo/request"
    "github.com/gin-gonic/gin"
    "log"
)

// CreateProfile 创建用户资料
func CreateProfile(c *gin.Context) {
    var req request.CreateProfileReq
    // 绑定请求参数
    if err := c.ShouldBindJSON(&req); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"code": 400, "msg": "参数格式错误"})
        return
    }
    // 参数校验
    if err := req.Validate(); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"code": 400, "msg": err.Error()})
        return
    }
    // 检查用户名是否已存在
    var existUser model.UserProfile
    global.DB.Where("username = ?", req.Username).First(&existUser)
    if existUser.ID != 0 {
        c.JSON(http.StatusConflict, gin.H{"code": 409, "msg": "用户名已存在"})
        return
    }
    // 检查邮箱是否已存在
    global.DB.Where("email = ?", req.Email).First(&existUser)
    if existUser.ID != 0 {
        c.JSON(http.StatusConflict, gin.H{"code": 409, "msg": "邮箱已存在"})
        return
    }
    // 构建用户资料对象
    user := model.UserProfile{
        Username: req.Username,
        Nickname: req.Nickname,
        Email:    req.Email,
        Phone:    req.Phone,
        Avatar:   req.Avatar,
    }
    // 写入数据库
    if err := global.DB.Create(&user).Error; err != nil {
        log.Printf("创建用户失败: %v", err)
        c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "msg": "创建用户失败"})
        return
    }
    c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "创建成功", "data": user})
}

查询用户资料接口

支持根据用户名查询单个用户资料,以及分页查询所有用户资料:

// GetProfileByUsername 根据用户名查询用户资料
func GetProfileByUsername(c *gin.Context) {
    username := c.Query("username")
    if username == "" {
        c.JSON(http.StatusBadRequest, gin.H{"code": 400, "msg": "用户名不能为空"})
        return
    }
    var user model.UserProfile
    global.DB.Where("username = ?", username).First(&user)
    if user.ID == 0 {
        c.JSON(http.StatusNotFound, gin.H{"code": 404, "msg": "用户不存在"})
        return
    }
    c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "查询成功", "data": user})
}

// GetProfileList 分页查询用户资料列表
func GetProfileList(c *gin.Context) {
    page := c.DefaultQuery("page", "1")
    pageSize := c.DefaultQuery("page_size", "10")
    var users []model.UserProfile
    var total int64
    // 查询总数
    global.DB.Model(&model.UserProfile{}).Count(&total)
    // 分页查询
    global.DB.Offset((pageInt - 1) * pageSizeInt).Limit(pageSizeInt).Find(&users)
    c.JSON(http.StatusOK, gin.H{
        "code":  200,
        "msg":   "查询成功",
        "data":  users,
        "total": total,
    })
}

更新用户资料接口

实现用户资料的更新逻辑,仅允许更新昵称、邮箱、手机号、头像字段:

// UpdateProfile 更新用户资料
func UpdateProfile(c *gin.Context) {
    id := c.Param("id")
    var req request.UpdateProfileReq
    if err := c.ShouldBindJSON(&req); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"code": 400, "msg": "参数格式错误"})
        return
    }
    if err := req.Validate(); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"code": 400, "msg": err.Error()})
        return
    }
    var user model.UserProfile
    global.DB.First(&user, id)
    if user.ID == 0 {
        c.JSON(http.StatusNotFound, gin.H{"code": 404, "msg": "用户不存在"})
        return
    }
    // 如果更新邮箱 检查是否已被其他用户使用
    if req.Email != "" && req.Email != user.Email {
        var existUser model.UserProfile
        global.DB.Where("email = ?", req.Email).First(&existUser)
        if existUser.ID != 0 {
            c.JSON(http.StatusConflict, gin.H{"code": 409, "msg": "邮箱已被使用"})
            return
        }
    }
    // 更新字段
    updateData := map[string]interface{}{}
    if req.Nickname != "" {
        updateData["nickname"] = req.Nickname
    }
    if req.Email != "" {
        updateData["email"] = req.Email
    }
    if req.Phone != "" {
        updateData["phone"] = req.Phone
    }
    if req.Avatar != "" {
        updateData["avatar"] = req.Avatar
    }
    global.DB.Model(&user).Updates(updateData)
    c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "更新成功", "data": user})
}

删除用户资料接口

使用GORM的软删除功能,删除用户资料时不会真正删除数据库记录:

// DeleteProfile 删除用户资料
func DeleteProfile(c *gin.Context) {
    id := c.Param("id")
    var user model.UserProfile
    global.DB.First(&user, id)
    if user.ID == 0 {
        c.JSON(http.StatusNotFound, gin.H{"code": 404, "msg": "用户不存在"})
        return
    }
    // 软删除 数据库deleted_at字段会被赋值
    global.DB.Delete(&user)
    c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "删除成功"})
}

路由注册与服务启动

最后将接口注册到gin路由,启动HTTP服务:

package main

import (
    "user_profile_demo/global"
    "user_profile_demo/handler"
    "github.com/gin-gonic/gin"
    "log"
)

func main() {
    // 初始化数据库
    global.InitDB()
    r := gin.Default()
    // 用户资料管理路由组
    profileGroup := r.Group("/api/profile")
    {
        profileGroup.POST("/create", handler.CreateProfile)           // 创建用户
        profileGroup.GET("/get", handler.GetProfileByUsername)       // 查询单个用户
        profileGroup.GET("/list", handler.GetProfileList)            // 查询用户列表
        profileGroup.PUT("/update/:id", handler.UpdateProfile)       // 更新用户
        profileGroup.DELETE("/delete/:id", handler.DeleteProfile)    // 删除用户
    }
    log.Println("服务启动在 127.0.0.1:8080")
    r.Run("127.0.0.1:8080")
}

测试验证

启动服务后,可以使用curl或者postman测试接口:

  • 创建用户:发送POST请求到127.0.0.1:8080/api/profile/create,携带正确的JSON参数即可创建用户
  • 查询用户:发送GET请求到127.0.0.1:8080/api/profile/get?username=test可查询指定用户
  • 更新用户:发送PUT请求到127.0.0.1:8080/api/profile/update/1,携带更新参数即可修改用户资料
  • 删除用户:发送DELETE请求到127.0.0.1:8080/api/profile/delete/1可删除对应用户

以上实现覆盖了用户资料管理的核心场景,开发者可以根据实际业务需求扩展更多字段或者功能,比如增加用户资料的权限控制、添加操作日志等。

Golang用户资料管理gin框架MySQL数据校验修改时间:2026-07-18 06:33:58

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。