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内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论