vault backup: 2026-06-07 11:08:10

This commit is contained in:
2026-06-07 11:08:10 +08:00
parent 4fecd02af0
commit 527a4eb1ca
59 changed files with 19905 additions and 0 deletions
+362
View File
@@ -0,0 +1,362 @@
---
tags:
- Go
- golang
- gin
- web框架
- http
---
# Gin
Gin是一个用Go语言编写的高性能Web框架,以其高效的路由系统和优秀的性能著称。本文将详细介绍如何使用Gin框架开发Web应用。
## 安装Gin
首先,我们需要安装Gin框架。可以使用以下命令:
```bash
go get -u github.com/gin-gonic/gin
```
## 基本使用
### 创建HTTP服务器
使用Gin创建一个基本的HTTP服务器非常简单:
```go
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
// 创建默认的路由引擎
r := gin.Default()
// 注册一个GET路由
r.GET("/ping", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
})
// 启动HTTP服务,默认在0.0.0.0:8080启动服务
r.Run()
}
```
### 路由参数
Gin支持多种路由参数形式:
```go
// 获取get请求的路径参数,参数名为name
r.GET("/user/:name", func(c *gin.Context) {
name := c.Param("name")
c.String(http.StatusOK, "Hello %s", name)
})
// 获取get请求的路径参数,参数名为name,age,age的默认值为20
r.GET("/users", func(c *gin.Context) {
name := c.Query("name") // 获取name参数
age := c.DefaultQuery("age", "20") // 获取age参数,默认值为20
c.JSON(http.StatusOK, gin.H{
"name": name,
"age": age,
})
})
```
### 处理表单数据
Gin可以轻松处理POST请求中的表单数据:
```go
r.POST("/form", func(c *gin.Context) {
// 获取表单参数
username := c.PostForm("username")
password := c.DefaultPostForm("password", "")
c.JSON(http.StatusOK, gin.H{
"username": username,
"password": password,
})
})
```
### 处理JSON数据
Gin可以轻松处理POST请求中的JSON数据:
```go
// 定义请求体结构
type LoginRequest struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
}
r.POST("/login", func(c *gin.Context) {
var login LoginRequest
// 将请求体绑定到结构体
if err := c.BindJSON(&login); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
return
}
// 处理登录逻辑
c.JSON(http.StatusOK, gin.H{
"message": "登录成功",
"username": login.Username,
})
})
// 也可以直接使用map接收JSON数据
r.POST("/raw", func(c *gin.Context) {
var data map[string]interface{}
if err := c.BindJSON(&data); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
return
}
c.JSON(http.StatusOK, data)
})
```
在上面的示例中:
1. 使用结构体接收JSON数据时,可以通过tag来指定字段的验证规则
2. `binding:"required"`表示该字段是必需的
3. 也可以使用map来接收不固定结构的JSON数据
4. `c.BindJSON()`会自动检查Content-Type是否为application/json
### 上传文件
Gin支持单文件和多文件上传:
```go
// 单文件上传
r.POST("/upload", func(c *gin.Context) {
file, _ := c.FormFile("file")
// 保存文件
c.SaveUploadedFile(file, "./"+file.Filename)
c.String(http.StatusOK, "File %s uploaded successfully", file.Filename)
})
// 多文件上传
r.POST("/uploads", func(c *gin.Context) {
form, _ := c.MultipartForm()
files := form.File["files"]
for _, file := range files {
c.SaveUploadedFile(file, "./"+file.Filename)
}
c.String(http.StatusOK, "%d files uploaded successfully", len(files))
})
```
### 中间件
Gin的中间件可以在请求处理过程中执行一些公共的操作:
```go
// 定义一个中间件
func Logger() gin.HandlerFunc {
return func(c *gin.Context) {
t := time.Now()
// 在请求之前
c.Next()
// 在请求之后
latency := time.Since(t)
log.Printf("请求处理时间: %v", latency)
}
}
// 使用中间件
r.Use(Logger())
```
### 分组路由
Gin支持路由分组,可以更好地组织API:
```go
// 创建v1版本的路由组
v1 := r.Group("/v1")
{
v1.POST("/login", loginEndpoint)
v1.POST("/submit", submitEndpoint)
v1.POST("/read", readEndpoint)
}
// 创建v2版本的路由组
v2 := r.Group("/v2")
{
v2.POST("/login", loginEndpointV2)
v2.POST("/submit", submitEndpointV2)
v2.POST("/read", readEndpointV2)
}
```
## 完整示例
以下是一个完整的示例,展示了如何使用Gin框架创建一个简单的RESTful API服务:
```go
package main
import (
"github.com/gin-gonic/gin"
"log"
"net/http"
)
// User 用户模型
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
}
// 模拟数据库
var users = []User{
{ID: 1, Name: "张三", Age: 25},
{ID: 2, Name: "李四", Age: 30},
}
func main() {
// 创建默认的路由引擎
r := gin.Default()
// 注册路由
r.GET("/users", getUsers)
r.GET("/users/:id", getUserByID) // 这里的冒号表示路径参数,可以通过c.Param("id")获取
r.POST("/users", createUser)
r.PUT("/users/:id", updateUser)
r.DELETE("/users/:id", deleteUser)
// 启动http服务器,监听8080端口
if err := r.Run(":8080"); err != nil {
log.Fatalf("Server error: %v", err)
}
}
// 获取所有用户
func getUsers(c *gin.Context) {
c.JSON(http.StatusOK, users)
}
// 根据ID获取用户
func getUserByID(c *gin.Context) {
id := c.Param("id")
for _, user := range users {
if string(user.ID) == id {
c.JSON(http.StatusOK, user)
return
}
}
c.JSON(http.StatusNotFound, gin.H{"message": "User not found"})
}
// 创建用户
func createUser(c *gin.Context) {
var newUser User
if err := c.BindJSON(&newUser); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
users = append(users, newUser)
c.JSON(http.StatusCreated, newUser)
}
// 更新用户
func updateUser(c *gin.Context) {
// 获取路径参数中的ID
id := c.Param("id")
var updatedUser User
// 绑定请求体中的JSON数据到updatedUser
if err := c.BindJSON(&updatedUser); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
for i, user := range users {
if string(user.ID) == id {
users[i] = updatedUser
c.JSON(http.StatusOK, updatedUser)
return
}
}
c.JSON(http.StatusNotFound, gin.H{"message": "User not found"})
}
// 删除用户
func deleteUser(c *gin.Context) {
id := c.Param("id")
for i, user := range users {
if string(user.ID) == id {
users = append(users[:i], users[i+1:]...)
c.JSON(http.StatusOK, gin.H{"message": "User deleted"})
return
}
}
c.JSON(http.StatusNotFound, gin.H{"message": "User not found"})
}
```
### 程序测试
使用curl命令测试API:
```bash
# 获取所有用户
curl http://localhost:8080/users
# 获取指定用户
curl http://localhost:8080/users/1
# 创建用户
curl -X POST -H "Content-Type: application/json" -d '{"id":3,"name":"王五","age":35}' http://localhost:8080/users
# 更新用户
curl -X PUT -H "Content-Type: application/json" -d '{"id":1,"name":"张三丰","age":26}' http://localhost:8080/users/1
# 删除用户
curl -X DELETE http://localhost:8080/users/2
```
### 代码说明
1. **路由设置**:使用`gin.Default()`创建路由引擎,并注册了基本的RESTful API路由。
2. **数据模型**:定义了`User`结构体作为数据模型,并使用切片模拟数据库存储。
3. **请求处理**:实现了增删改查(CRUD)的基本操作,包括:
- GET /users:获取所有用户
- GET /users/:id:获取指定用户
- POST /users:创建新用户
- PUT /users/:id:更新用户
- DELETE /users/:id:删除用户
4. **错误处理**:对各种可能的错误情况进行了处理,并返回适当的HTTP状态码。
## 小结
这篇文章简单介绍了Gin框架的基本使用方法,包括路由配置、参数获取、中间件使用等内容。如需了解Gin框架更详细的用法,可以参考:[Gin框架官方文档](https://gin-gonic.com/zh-cn/docs/)
+274
View File
@@ -0,0 +1,274 @@
---
tags:
- Go
- golang
- gorm
- mysql
- 数据库
---
# GORM
GORM是一个功能强大的Go语言ORM库,提供了简洁的API来操作数据库。本文将详细介绍如何使用GORM与MySQL数据库进行交互。
## 安装GORM和MySQL驱动
首先,我们需要安装GORM和MySQL驱动。可以使用以下命令:
```bash
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
```
## 连接数据库
在使用GORM连接MySQL数据库时,我们需要提供数据源名称(DSN),其中包含用户名、密码、主机地址、端口号和数据库名称等信息。
```go
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
"log"
)
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.Fatalf("failed to connect database: %v", err)
}
}
```
## 初始化连接
GORM会自动管理数据库连接池,因此我们不需要手动设置最大连接数和最大空闲连接数。不过,如果有特殊需求,可以通过`sql.DB`对象进行设置。
```go
sqlDB, err := db.DB()
if err != nil {
log.Fatalf("failed to get database object: %v", err)
}
// 设置最大打开连接数
sqlDB.SetMaxOpenConns(100)
// 设置最大空闲连接数
sqlDB.SetMaxIdleConns(10)
```
## 定义模型
在GORM中,我们通过定义结构体来映射数据库表。每个字段对应表中的一列。
```go
// User 结构体映射到数据库中的users表
type User struct {
ID uint `gorm:"primaryKey;column:id"` // ID为主键
Name string `gorm:"size:255;column:name"` // Name字段最大长度为255
Age int `gorm:"column:age"` // Age字段
}
```
## 自动迁移
GORM提供了自动迁移功能,可以根据模型结构自动创建或更新数据库表。
```go
// 自动迁移User结构体
db.AutoMigrate(&User{})
```
## CRUD操作
### 创建记录
使用`Create`方法可以向数据库中插入一条新记录。
```go
// 创建一个新的User记录
user := User{Name: "张三", Age: 25}
result := db.Create(&user)
if result.Error != nil {
log.Fatalf("failed to create user: %v", result.Error)
}
```
### 查询记录
#### 单行查询
使用`First`方法可以查询符合条件的第一条记录。
```go
// 查询ID为1的User记录
var user User
result := db.First(&user, 1) // 根据主键查询
if result.Error != nil {
log.Printf("failed to find user: %v", result.Error)
}
```
#### 多行查询
使用`Find`方法可以查询符合条件的多条记录。
```go
// 查询年龄大于20的所有User记录
var users []User
result := db.Where("age > ?", 20).Find(&users)
if result.Error != nil {
log.Printf("failed to find users: %v", result.Error)
}
```
### 更新记录
使用`Save`方法可以更新记录。
```go
// 更新User记录的Age字段
user.Age = 26
result := db.Save(&user)
if result.Error != nil {
log.Fatalf("failed to update user: %v", result.Error)
}
```
### 删除记录
使用`Delete`方法可以删除记录。
```go
// 删除User记录
result := db.Delete(&user)
if result.Error != nil {
log.Fatalf("failed to delete user: %v", result.Error)
}
```
## 事务支持
GORM支持事务操作,可以通过`Transaction`方法来执行事务。
```go
// 使用事务创建两个User记录
err := db.Transaction(func(tx *gorm.DB) error {
if err := tx.Create(&User{Name: "李四", Age: 30}).Error; err != nil {
return err
}
if err := tx.Create(&User{Name: "王五", Age: 35}).Error; err != nil {
return err
}
return nil
})
if err != nil {
log.Fatalf("transaction failed: %v", err)
}
```
## 预处理和SQL注入
GORM会自动处理SQL注入问题,因此我们不需要手动拼接SQL语句。所有的查询条件都可以通过链式调用来实现。
```go
// 查询Name为"张三"的User记录
db.Where("name = ?", "张三").First(&user)
```
## 完整示例
以下是一个完整的示例代码,展示了如何使用GORM连接MySQL数据库并进行CRUD操作。
```go
package main
import (
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"log"
)
// User 结构体映射到数据库中的users表
type User struct {
ID uint `gorm:"primaryKey;column:id"` // ID为主键
Name string `gorm:"size:255;column:name"` // Name字段最大长度为255
Age int `gorm:"column:age"` // Age字段
}
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.Fatalf("failed to connect database: %v", err)
}
// 自动迁移User结构体
db.AutoMigrate(&User{})
// 创建一个新的User记录
user := User{Name: "张三", Age: 25}
result := db.Create(&user)
if result.Error != nil {
log.Fatalf("failed to create user: %v", result.Error)
}
// 查询ID为1的User记录
var queriedUser User
result = db.First(&queriedUser, user.ID) // 根据主键查询
if result.Error != nil {
log.Printf("failed to find user: %v", result.Error)
} else {
fmt.Printf("Queried User: %+v\n", queriedUser)
}
// 更新User记录的Age字段
queriedUser.Age = 26
result = db.Save(&queriedUser)
if result.Error != nil {
log.Fatalf("failed to update user: %v", result.Error)
}
// 删除User记录
result = db.Delete(&queriedUser)
if result.Error != nil {
log.Fatalf("failed to delete user: %v", result.Error)
}
}
```
### 程序输出
假设数据库连接成功,程序将输出如下信息:
```
Queried User: {ID:1 Name:张三 Age:25}
```
这表示程序成功创建、查询、更新并删除了一条用户记录。
### 代码说明
1. **连接数据库**:使用`gorm.Open`方法连接MySQL数据库,数据源名称(DSN)中包含了数据库连接的必要信息。
2. **自动迁移**:使用`AutoMigrate`方法根据`User`结构体自动创建或更新数据库表。
3. **创建记录**:使用`Create`方法向数据库中插入一条新记录。
4. **查询记录**:使用`First`方法查询符合条件的第一条记录。
5. **更新记录**:使用`Save`方法更新记录。
6. **删除记录**:使用`Delete`方法删除记录。
---
## 小结
这篇文章简单介绍了GORM的基本使用方法,包括连接数据库、定义模型、CRUD操作、事务支持等内容。希望对您有所帮助!,如需了解GORM详细的用法,可以参考:[GORM中文官网](https://gorm.io/zh_CN/docs/)