gin+gorm实现goweb项目的示例代码

 更新时间:2025年03月31日 10:05:08   作者:JawCat  
Gorm是Go语言的ORM框架,提供一套对数据库进行增删改查的接口,本文主要介绍了gin+gorm实现goweb项目的示例代码,具有一定的参考价值,感兴趣的可以了解一下

Gin

  • Gin 是一个用 Go 编写的轻量级、高性能的 Web 框架。它的主要功能是处理 HTTP 请求和响应,帮助开发者快速构建 Web 应用程序和 API 服务。

  • 通俗解释
    Gin 框架就像一个服务员,负责接收客户的订单(HTTP 请求),根据菜单(路由规则)将订单转交给合适的厨师(处理函数),厨师准备好食物(生成响应数据)后,服务员再将食物递给客户(返回 HTTP 响应)。

1. 主要功能

  • 路由:Gin 允许你定义不同的 URL 路径和 HTTP 方法(如 GET、POST),并将它们映射到相应的处理函数。
  • 中间件:可以在请求处理过程中插入多个中间件函数,用于认证、日志记录等操作。
  • 参数绑定:支持从 URL、表单、JSON 等位置获取参数并绑定到结构体中。
  • 错误处理:提供方便的错误处理机制,统一管理错误响应。

2. 工作流程

  • 定义路由:开发者定义各种路由和它们对应的处理函数。
  • 启动服务器:Gin 框架启动一个 HTTP 服务器,监听特定端口。
  • 接收请求:当有 HTTP 请求到达时,Gin 根据请求的路径和方法查找对应的处理函数。
  • 执行中间件:在处理函数执行之前,依次执行注册的中间件。
  • 处理请求:调用对应的处理函数,生成响应数据。
  • 返回响应:将响应数据返回给客户端。

3. 示例

package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

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

    r.GET("/ping", func(c *gin.Context) {
        c.JSON(http.StatusOK, gin.H{
            "message": "pong",
        })
    })

    r.Run(":8080")
}


Gorm

  • Gorm 是一个用 Go 编写的 ORM(对象关系映射)库,它的主要功能是简化数据库操作。Gorm 通过将数据库表映射为 Go 结构体,使得开发者可以使用 Go 代码来执行数据库的增删改查等操作,而不需要直接编写 SQL 语句。

  • 通俗解释:Gorm 就像一个翻译器,它把开发者写的 Go 代码翻译成数据库能够理解的 SQL 语句,并且负责执行这些 SQL 语句,将结果再翻译回 Go 语言的数据结构。

1. 主要功能

  • 模型定义:将数据库表映射为 Go 结构体,定义字段及其属性。
  • 查询:提供简洁的查询方法,如创建记录、读取记录、更新记录、删除记录等。
  • 关系:支持数据库表之间的关系,如一对一、一对多、多对多关系。
  • 迁移:自动迁移数据库表结构,使其与 Go 结构体保持同步。

2. 工作流程

  • 定义模型:开发者定义与数据库表对应的 Go 结构体。
  • 初始化数据库连接:配置数据库连接信息,并建立连接。
  • 执行操作:使用 Gorm 提供的方法来进行数据库操作,如创建、查询、更新、删除等。
  • 处理结果:将数据库操作的结果映射回 Go 结构体中,供业务逻辑使用。

3. 示例

package main

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

type User struct {
    ID    uint   `gorm:"primaryKey"`
    Name  string `gorm:"size:255"`
    Email string `gorm:"uniqueIndex"`
    Age   int
}

func main() {
    dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
    if err != nil {
        log.Fatal(err)
    }

    // 自动迁移
    db.AutoMigrate(&User{})

    // 创建记录
    db.Create(&User{Name: "John", Email: "john@example.com", Age: 25})

    // 读取记录
    var user User
    db.First(&user, 1) // 查询主键为1的用户
    log.Println(user)

    // 更新记录
    db.Model(&user).Update("Age", 26)

    // 删除记录
    db.Delete(&user)
}

Gin+Gorm项目实操

1. 项目目录结构

my-gin-gorm-project/
│
├── cmd/
│   └── main.go        // 主程序入口
│
├── config/
│   └── config.go      // 配置文件解析
│
├── controllers/
│   └── user.go        // 用户相关的控制器
│
├── models/
│   └── user.go        // 用户模型定义
│
├── routes/
│   └── routes.go      // 路由定义
│
├── middlewares/
│   └── auth.go        // 认证中间件
│
├── services/
│   └── user.go        // 用户相关的业务逻辑
│
├── repositories/
│   └── user.go        // 用户数据访问层
│
├── utils/
│   └── utils.go       // 工具函数
│
├── .env               // 环境变量文件
├── go.mod             // Go模块文件
└── go.sum             // 依赖文件

2. 主程序入口(cmd/main.go)

package main

import (
    "my-gin-gorm-project/config"
    "my-gin-gorm-project/routes"
    "github.com/gin-gonic/gin"
    "gorm.io/gorm"
)

var db *gorm.DB

func main() {
    // 解析配置文件
    config.LoadConfig()

    // 初始化数据库连接
    db = config.InitDB()

    // 设置Gin引擎
    r := gin.Default()

    // 注册路由
    routes.RegisterRoutes(r)

    // 启动服务器
    r.Run(config.Config.ServerPort)
}

3. 配置文件解析(config/config.go)

package config

import (
    "log"
    "os"
    "github.com/joho/godotenv"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)

var Config struct {
    ServerPort string
    DBUser     string
    DBPassword string
    DBName     string
    DBHost     string
    DBPort     string
}

// LoadConfig 解析配置文件
func LoadConfig() {
    if err := godotenv.Load(); err != nil {
        log.Fatal("Error loading .env file")
    }

    Config.ServerPort = os.Getenv("SERVER_PORT")
    Config.DBUser = os.Getenv("DB_USER")
    Config.DBPassword = os.Getenv("DB_PASSWORD")
    Config.DBName = os.Getenv("DB_NAME")
    Config.DBHost = os.Getenv("DB_HOST")
    Config.DBPort = os.Getenv("DB_PORT")
}

// InitDB 初始化数据库连接
func InitDB() *gorm.DB {
    dsn := Config.DBUser + ":" + Config.DBPassword + "@tcp(" + Config.DBHost + ":" + Config.DBPort + ")/" + Config.DBName + "?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
    if err != nil {
        log.Fatal("Failed to connect to database:", err)
    }
    return db
}

4. 用户模型定义(models/user.go)

package models

import "gorm.io/gorm"

// User 用户模型定义
type User struct {
    gorm.Model
    Name  string `gorm:"size:255"`
    Email string `gorm:"uniqueIndex"`
    Age   int
}

5. 用户相关的控制器(controllers/user.go)

package controllers

import (
    "my-gin-gorm-project/models"
    "my-gin-gorm-project/services"
    "net/http"
    "github.com/gin-gonic/gin"
)

// GetUsers 获取所有用户
func GetUsers(c *gin.Context) {
    users := services.GetAllUsers()
    c.JSON(http.StatusOK, users)
}

// CreateUser 创建新用户
func CreateUser(c *gin.Context) {
    var user models.User
    if err := c.ShouldBindJSON(&user); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
    if err := services.CreateUser(&user); err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
        return
    }
    c.JSON(http.StatusOK, user)
}

6. 用户数据访问层(repositories/user.go)

package repositories

import (
    "my-gin-gorm-project/models"
    "gorm.io/gorm"
)

var DB *gorm.DB

// SetDB 设置数据库实例
func SetDB(db *gorm.DB) {
    DB = db
}

// GetAllUsers 获取所有用户
func GetAllUsers() ([]models.User, error) {
    var users []models.User
    if err := DB.Find(&users).Error; err != nil {
        return nil, err
    }
    return users, nil
}

// CreateUser 创建新用户
func CreateUser(user *models.User) error {
    if err := DB.Create(user).Error; err != nil {
        return err
    }
    return nil
}

7. 用户相关的业务逻辑(services/user.go)

package services

import (
    "my-gin-gorm-project/models"
    "my-gin-gorm-project/repositories"
)

// GetAllUsers 获取所有用户
func GetAllUsers() []models.User {
    users, _ := repositories.GetAllUsers()
    return users
}

// CreateUser 创建新用户
func CreateUser(user *models.User) error {
    return repositories.CreateUser(user)
}

8. 路由定义(routes/routes.go)

package routes

import (
    "my-gin-gorm-project/controllers"
    "github.com/gin-gonic/gin"
)

// RegisterRoutes 注册所有路由
func RegisterRoutes(r *gin.Engine) {
    // 用户相关路由
    userRoutes := r.Group("/users")
    {
        userRoutes.GET("/", controllers.GetUsers)
        userRoutes.POST("/", controllers.CreateUser)
    }
}

9. 环境变量文件(.env)

SERVER_PORT=:8080
DB_USER=root
DB_PASSWORD=password
DB_NAME=mydb
DB_HOST=localhost
DB_PORT=3306

10. 补充:关于utils和Middlewares的区别以及使用

Utils(工具类)

  • 功能:工具类目录用于存放项目中常用的工具函数和通用模块。这些函数和模块通常独立于业务逻辑,可以在项目的各个部分复用。

  • 存放内容:

    通用工具函数:例如字符串处理函数、日期时间处理函数、加密解密函数等。

    配置解析函数:用于解析配置文件或环境变量的函数。

    日志记录函数:处理日志记录的工具。

    Token处理:如Token的生成、解析、验证等。

    其他通用模块:如错误处理函数、文件操作函数等。

示例

package utils

import (
    "time"
    "github.com/dgrijalva/jwt-go"
    "os"
    "errors"
)

var jwtSecret = []byte(os.Getenv("JWT_SECRET"))

// Claims 自定义的声明
type Claims struct {
    UserID uint
    jwt.StandardClaims
}

// GenerateToken 生成Token
func GenerateToken(userID uint) (string, error) {
    expirationTime := time.Now().Add(24 * time.Hour)
    claims := &Claims{
        UserID: userID,
        StandardClaims: jwt.StandardClaims{
            ExpiresAt: expirationTime.Unix(),
        },
    }
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    tokenString, err := token.SignedString(jwtSecret)
    if err != nil {
        return "", err
    }
    return tokenString, nil
}

// ParseToken 解析Token
func ParseToken(tokenString string) (*Claims, error) {
    claims := &Claims{}
    token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
        return jwtSecret, nil
    })
    if err != nil {
        return nil, err
    }
    if !token.Valid {
        return nil, errors.New("invalid token")
    }
    return claims, nil
}

Middlewares(中间件)

  • 功能:中间件目录用于存放在HTTP请求处理过程中需要执行的额外操作。这些操作通常在请求到达具体的业务逻辑处理之前或之后进行,主要用于请求的预处理和后处理。

  • 存放内容:

    认证中间件:如Token验证中间件,确保请求携带有效的Token。

    日志中间件:记录请求日志,包括请求的路径、方法、响应时间等。

    错误处理中间件:统一处理错误并返回标准的错误响应。

    CORS中间件:处理跨域请求。

    其他预处理或后处理操作:如请求限流、压缩响应等。

示例

package middlewares

import (
    "my-gin-gorm-project/utils"
    "net/http"
    "strings"

    "github.com/gin-gonic/gin"
)

// AuthMiddleware 认证中间件
func AuthMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        tokenString := c.GetHeader("Authorization")
        if tokenString == "" {
            c.JSON(http.StatusUnauthorized, gin.H{"error": "请求头中缺少Token"})
            c.Abort()
            return
        }

        tokenString = strings.TrimPrefix(tokenString, "Bearer ")

        claims, err := utils.ParseToken(tokenString)
        if err != nil {
            c.JSON(http.StatusUnauthorized, gin.H{"error": "无效的Token"})
            c.Abort()
            return
        }

        c.Set("userID", claims.UserID)
        c.Next()
    }
}

11. 项目运行流程

  • 配置解析和数据库连接:在主程序入口中,首先加载配置文件并初始化数据库连接。
  • 路由注册:接着,注册所有的路由。
  • 控制器和服务层的调用:当路由被访问时,控制器会调用相应的服务层方法。
  • 数据访问:服务层通过数据访问层(Repository)来进行数据库操作。

到此这篇关于gin+gorm实现goweb项目的示例代码的文章就介绍到这了,更多相关gin+gorm实现goweb内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Golang工作池的使用实例讲解

    Golang工作池的使用实例讲解

    我们使用Go语言开发项目,常常会使用到goroutine;goroutine太多会造成系统占用过高或其他系统异常,我们可以将goroutine控制指定数量,且减少goroutine的创建,这就运用到Go工作池,下面就介绍和使用一下
    2023-02-02
  • Go实现socks5服务器的方法

    Go实现socks5服务器的方法

    SOCKS5 是一个代理协议,它在使用TCP/IP协议通讯的前端机器和服务器机器之间扮演一个中介角色,使得内部网中的前端机器变得能够访问Internet网中的服务器,或者使通讯更加安全,这篇文章主要介绍了Go实现socks5服务器的方法,需要的朋友可以参考下
    2023-07-07
  • go module化 import 调用本地模块 tidy的方法

    go module化 import 调用本地模块 tidy的方法

    这篇文章主要介绍了go module化 import 调用本地模块 tidy的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-09-09
  • 一文掌握Golang的panic和recover实战

    一文掌握Golang的panic和recover实战

    Go语言中,异常处理通常依赖error返回值,本文将通过示例展示如何在Go语言中正确使用recover来处理panic异常,防止程序直接崩溃,感兴趣的朋友跟随小编一起看看吧
    2024-09-09
  • Golang 处理浮点数遇到的精度问题(使用decimal)

    Golang 处理浮点数遇到的精度问题(使用decimal)

    本文主要介绍了Golang 处理浮点数遇到的精度问题,不使用decimal会出大问题,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • go开源Hugo站点构建三步曲之集结渲染

    go开源Hugo站点构建三步曲之集结渲染

    这篇文章主要为大家介绍了go开源Hugo站点构建三步曲之集结渲染详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • 浅谈Go Slice 高级实践

    浅谈Go Slice 高级实践

    这篇文章主要介绍了浅谈Go Slice 高级实践,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • golang中按照结构体的某个字段排序实例代码

    golang中按照结构体的某个字段排序实例代码

    在任何编程语言中,关乎到数据的排序都会有对应的策略,下面这篇文章主要给大家介绍了关于golang中按照结构体的某个字段排序的相关资料,需要的朋友可以参考下
    2022-05-05
  • Go操作etcd的实现示例

    Go操作etcd的实现示例

    etcd是近几年比较火热的一个开源的、分布式的键值对数据存储系统,提供共享配置、服务的注册和发现,本文主要介绍etcd的安装和使用,感兴趣的可以了解一下
    2021-09-09
  • Go语言基础之网络编程全面教程示例

    Go语言基础之网络编程全面教程示例

    这篇文章主要为大家介绍了Go语言基础之网络编程全面教程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12

最新评论