使用GIN实现操作数据库简单的web项目

1、gin框架的介绍

Gin是一个用Go(Golang)编写的HTTP Web框架,它是一个轻量级、高性能的框架,广泛用于构建RESTful API、Web服务和单页应用程序。以下是Gin的一些主要特点和优势:

特点:

  1. 性能 :Gin是一个非常快速的框架,它是基于HTTP路由器(httprouter)构建的,这个路由器以其高性能而闻名。

  2. 中间件支持:Gin允许使用中间件来处理HTTP请求,例如身份验证、日志记录、CORS处理等。

  3. 路由:Gin提供了强大的路由能力,支持HTTP的GET、POST、PUT、DELETE、PATCH等方法,并允许参数和路径的绑定。

  4. 错误管理:Gin有内置的错误处理机制,可以很容易地管理HTTP错误。

  5. 模型绑定和验证:Gin支持将请求体绑定到结构体,并可以进行数据验证。

  6. 渲染:Gin支持多种类型的渲染,如JSON、XML、HTML等。

  7. 扩展性:Gin易于扩展,你可以根据需要添加自己的中间件。

安装:

安装Gin非常简单,使用Go的包管理工具go get即可:

复制代码
go get -u github.com/gin-gonic/gin

2、使用goland编译器开发

配置这三个配置即可,如果安装好go环境之后,前面两个默认就会配置好。第三个配置如图配置,下载go的一些依赖的代理地址。

3、代码

3.1、目录结构介绍

说明:

migrate:存放数据库的链接方法

model:数据库的对象

service:操作数据库的方法

static:里面存放的是css、js、图片等

templates:静态界面html

go.mod:项目的依赖

main.go:项目的启动文件

3.2、代码实现

mysql_db.go

复制代码
package migrate

import (
	"first/model"
	"gorm.io/gorm"
)
import "gorm.io/driver/mysql"

var DB *gorm.DB

// 在 Go 语言中,如果函数、变量或类型以小写字母开头,则它们在包外是不可见的,
// 这被称为 "unexported" 或 "private"。这意味着您不能从其他包中直接调用这些未导出的标识符。
func InitDB() *gorm.DB {
	// DSN (Data Source Name) 格式: "用户名:密码@tcp(地址:端口)/数据库?charset=utf8mb4&parseTime=True&loc=Local"
	dsn := "root:123456@tcp(127.0.0.1:3307)/go?charset=utf8mb4&parseTime=True&loc=Local"
	var err error
	DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		var x any = "failed to connect database"
		panic(x)
	}

	// 自动迁移模式
	DB.AutoMigrate(&model.User{})
	return DB
}

在 Go 语言中,如果函数、变量或类型以小写字母开头,则它们在包外是不可见的, 这被称为 "unexported" 或 "private"。这意味着您不能从其他包中直接调用这些未导出的标识符。

外部需要调用该方法名需要大写开头

user.go

定义表字段,数据库会默认带id和创建时间、更新时间、删除时间四个字段

复制代码
package model

import "gorm.io/gorm"

type User struct {
	gorm.Model
	Username string `gorm:"size:100"`
	Password string
	Email string `gorm:"size:100;uniqueIndex"`
}

func Migrate(db *gorm.DB) error {
	return db.AutoMigrate(&User{})

}

user_service.go

复制代码
package service

import (
	"first/migrate"
	"first/model"
	"fmt"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

func GetUsers(c *gin.Context) {
	var users []model.User
	migrate.DB.Find(&users)
	c.JSON(200, users)
}

func CreateUser(c *gin.Context) {
	var user model.User
	if err := c.ShouldBindJSON(&user); err != nil {
		c.JSON(400, gin.H{"error": err.Error()})
		return
	}

	migrate.DB.Create(&user)
	c.JSON(200, user)
}

// 根据用户名查询用户
func GetUserByUsername(username string) (*model.User, error) {
	var user model.User
	result := migrate.DB.Where("username = ?", username).First(&user)
	if result.Error != nil {
		if result.Error == gorm.ErrRecordNotFound {
			fmt.Println("User not found")
		} else {
			fmt.Println(result.Error)
		}
	}
	// 输出查询结果
	fmt.Printf("User: %+v\n", user)
	return &user, nil
}

main.go

复制代码
package main

import (
	"encoding/json"
	"first/migrate"
	"first/service"
	"github.com/gin-gonic/gin"
	"github.com/thinkerou/favicon"
	"gorm.io/gorm"
	"log"
	"net/http"
)

// 自定义中间件 拦截器
func myHandler() (gin.HandlerFunc) {
	return func(context *gin.Context) {
		context.Set("user_session", "userid-66666666666666")
		// 放行
		context.Next()
		// 阻断
		// context.Abort()
	}
}

var db *gorm.DB

func main() {
	ginServer := gin.Default()
	// 注册中间件
	ginServer.Use(myHandler())

	ginServer.LoadHTMLGlob("./templates/*")
	ginServer.Static("/static", "./static")

	ginServer.Use(favicon.New("./static/img/favicon.png"))

	// http://localhost:8082/hello
	ginServer.GET("/hello", func(context *gin.Context) {
		user_session := context.MustGet("user_session").(string)
		log.Println("获取的session:", user_session)
		context.JSON(200, gin.H{
			"code": 200,
			"msg": "hello world!",
		})
	})

	// http://localhost:8082/index
	ginServer.GET("/index", func(context *gin.Context) {
		context.HTML(200, "index.html", gin.H{
			"msg": "后端的数据,你好,go!",
		})
	})

	// http://localhost:8082/user/info?userid=1001&username=frank
	ginServer.GET("/user/info", func(context *gin.Context) {
		user_session := context.MustGet("user_session").(string)
		log.Println("获取的session:", user_session)
		userid := context.Query("userid")
		username := context.Query("username")
		context.JSON(200, gin.H{
			"userid": userid,
			"username": username,
			"user_session": user_session,
		})
	})

	// http://localhost:8082/user/1001/frank
	ginServer.GET("/user/:userid/:username", func(context *gin.Context) {
		userid := context.Param("userid")
		username := context.Param("username")
		context.JSON(200, gin.H{
			"userid": userid,
			"username": username,
		})
	})

	ginServer.POST("/json", func(context *gin.Context) {
		data, _ := context.GetRawData()
		var m map[string]interface{}
		_ = json.Unmarshal(data, &m)
		context.JSON(http.StatusOK, m)
	})

	// 表单保存
	ginServer.POST("/user", func(context *gin.Context) {
		username := context.PostForm("username")
		password := context.PostForm("password")
		context.JSON(200, gin.H{
			"password": password,
			"username": username,
		})
	})

	ginServer.PUT("/user", func(context *gin.Context) {
		context.JSON(200, gin.H{
			"msg": "修改的界面",
		})
	})

	ginServer.DELETE("/user", func(context *gin.Context) {
		context.JSON(200, gin.H{
			"msg": "删除的界面",
		})
	})

	// 重定向
	ginServer.GET("/test", func(context *gin.Context) {
		context.Redirect(http.StatusMovedPermanently, "https://www.baidu.com")
	})

	// 404
	ginServer.NoRoute(func(context *gin.Context) {
		context.HTML(http.StatusNotFound, "404.html", nil)
	})

	// 路由组
	userGroup := ginServer.Group("/user")
	{
		userGroup.GET("/add")
		userGroup.GET("/login")
		userGroup.GET("/logout")
	}

	orderGroup := ginServer.Group("/order")
	{
		orderGroup.GET("/add")
		orderGroup.GET("/delete")
		orderGroup.GET("/update")
	}

	// 操作数据库
	db = migrate.InitDB()

	// 获取所有用户
	ginServer.GET("/users", service.GetUsers)
	// 保存用户
	ginServer.POST("/user/create", service.CreateUser)
	// http://127.0.0.1:8082/users/frank2 根据名称查询用户信息
	ginServer.GET("/users/:username", func(context *gin.Context) {
		username := context.Param("username")
		user, _ := service.GetUserByUsername(username)
		context.JSON(200, gin.H{
			"data": user,
		})
	})

	ginServer.Run(":8082")
}

完整的代码地址:

gin-study: 学习gin框架实现的第一个web项目

相关推荐
木西4 分钟前
Nest.js实战:构建聊天室的群聊与私聊模块
前端·后端·nestjs
数字人直播5 分钟前
跨境电商如何选择高转化率的AI数字人直播平台?
前端·后端
天生我材必有用_吴用6 分钟前
深入理解JavaScript设计模式之代理模式
前端
掘金安东尼1 小时前
7个【宝藏工具】从智能画图到 SSL 自动化,一应俱全
前端·面试·github
zhangxingchao1 小时前
Flutter屏幕适配指南
前端
石小石Orz1 小时前
被对象嘲讽,写个网页护眼宝你都不会么
前端
江城开朗的豌豆1 小时前
🔥 Vue组件传值:小杨教你玩转父子组件通信
前端·javascript·面试
江城开朗的豌豆1 小时前
Vue组件花式聊天指南:6种传值妙招,总有一款适合你
前端·javascript·vue.js
黑土豆1 小时前
在Vue3项目中实现PDF文件解析与预览的完整实践
前端·javascript·vue.js
han_1 小时前
前端如何动态执行JavaScript代码?
前端·javascript