方法 / 步驟
一: Gin框架
1.1 : 環境 & 項目配置
1, GoLand創建項目
- 創建main.go
package mainimport ("github.com/gin-gonic/gin"
)func main() {r := gin.Default()r.GET("/", func(c *gin.Context) {c.JSON(200, gin.H{"message": "Hello, Gin!",})})r.Run(":8080") // 啟動服務,監聽 8080 端口
}
- 創建go.mod文件
2, 初始化Gin項目
go mod tidy
go get -u github.com/gin-gonic/gin
# 或者在go.mod 文件中添加下面依賴
require github.com/gin-gonic/gin v1.9.0
3, 編譯配置
# 更改輸出目錄為 xxxx/target# 工具實參 去除編譯相關
-ldflags="-s -w"
1.2 路由 & 出入參
// 基本路由
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {c.JSON(200, gin.H{"message": "pong"})
})// 路由分組 (getUsers)
api := r.Group("/api")
{api.GET("/users", getUsers)api.POST("/users", createUser)
}r.Run(":8080")// 綁定入參
type User struct {Name string `json:"name"`Age int `json:"age"`
}r.POST("/user", func(c *gin.Context){var u Userif err := c.ShouldBindJSON(&u); err != nil {c.JSON(400, gin.H{"error": err.Error()})return}c.JSON(200, gin.H{"status": "ok", "user": u})
})
// 獲取 URL 參數
r.GET("/user/:id", func(c *gin.Context){id := c.Param("id")c.JSON(200, gin.H{"id": id})
})
Gin Context
Gin 的 Context 特性(相比 Java 更輕量)
- Gin 的
Context
集成了請求、響應、JSON、參數、Header 等 - 無需額外注入 HttpServletRequest / Response
r.GET("/info", func(c *gin.Context){path := c.Request.URL.Pathheader := c.GetHeader("User-Agent")c.JSON(200, gin.H{"path": path, "ua": header})
})
1.3 Gin + Go 并發入門(相比 Java 線程更輕量)
- Go 原生 goroutine + Gin Context 可以輕松實現并發處理
- 對比 Java 線程,goroutine 占用資源極少
r.GET("/async", func(c *gin.Context){// 創建協程functiongo func(ctx *gin.Context){time.Sleep(2 * time.Second)fmt.Println("Async processing done")}(c.Copy()) // 必須使用 Copy() 避免 Context 并發問題c.JSON(200, gin.H{"status": "processing"})
})
通過上面可以看出我們的端口號都是在代碼里面寫死的8080, 實際在生產中這么寫死很不優雅的,所以下面就用另外一種優雅的方式來實現:
1.4 環境變量管理:godotenv
- go.mod文件中 添加相關依賴
require (github.com/gin-gonic/gin v1.10.1// godotenv環境變量依賴github.com/joho/godotenv v1.5.1
)
- .env 文件內容
KEY=value
DB_USER=root
DB_PASS=123456
PORT=9999
- 更改main.go中的 端口號使用配置里面進行加載
package mainimport ("fmt""github.com/gin-gonic/gin""github.com/joho/godotenv""log""os""time"
)type Users struct {Name string `json:"name"`Age int `json:"age"`
}func main() {// 1. 使用godotenv加載 .env 文件 (如果不配置gin的默認端口號是8080)err := godotenv.Load()if err != nil {log.Println("No .env file found, using system environment variables")}r := gin.Default()port := os.Getenv("PORT")r.Run(":" + port)r.GET("/", func(c *gin.Context) {c.JSON(200, gin.H{"message": "Hello, Gin!",})})api := r.Group("/api"){api.GET("/users", getUsers)api.POST("/users", createUser)}// Gin 并發處理入門r.GET("/async", func(c *gin.Context) {go func(ctx *gin.Context) {time.Sleep(2 * time.Second)fmt.Println("Async processing done")}(c.Copy()) // 必須使用 Copy() 避免 Context 并發問題c.JSON(200, gin.H{"status": "processing"})})// 啟動服務,監聽 8080 端口//r.Run(":8080")
}// 該function沒有返回值,gin框架返回的json使用context進行包裝返回
func createUser(context *gin.Context) {fmt.Println("this is createUser")newUser := Users{Name: "alice", Age: 12}//todo 進行創建用戶的業務處理context.JSON(200, gin.H{"success": true, "data": newUser})
}func getUsers(context *gin.Context) {newUser := Users{Name: "alice", Age: 12}context.JSON(200, gin.H{"success": true, "data": newUser})fmt.Println("this is getUsers")
}
二: GORM框架集成
GORM介紹
? GitHub: https://github.com/go-gorm/gorm
? 特點:
? 功能全:CRUD、事務、關聯、鉤子、分頁、軟刪除
? 鏈式 API,支持自定義 SQL
? 支持 MySQL、PostgreSQL、SQLite、SQL Server 等
? 適用場景: 企業級項目、快速開發、需要自動 CRUD
? 用戶量: GitHub Star ~33k+,社區活躍,文檔豐富
相對于其他ORM框架
1?? 前置條件 & 項目結構設計
? 已安裝 Go(推薦 Go 1.20+)
? 已安裝 MySQL 或 SQLite(方便本地測試)
? 已安裝 GoLand 或 VSCode(任選)
gin-gorm-demo/
├── main.go # 程序入口
├── config/ # 配置文件
│ └── config.go
├── model/ # 數據模型(類似 entity)
│ └── user.go
├── dao/ # 數據訪問層(類似 mapper/repository)
│ └── user_dao.go
├── service/ # 業務邏輯層
│ └── user_service.go
├── router/ # 路由配置
│ └── router.go
├── handler/ # 控制器層(類似 controller)
│ └── user_handler.go
├── .env # 環境配置
└── go.mod
- 初始化項目
# 新建目錄
mkdir gin-gorm-demo && cd gin-gorm-demo# 初始化 Go 模塊
go mod init gin-gorm-demo# 安裝依賴
go get -u github.com/gin-gonic/gin
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql# 可選:本地快速調試
go get -u gorm.io/driver/sqlite
- MySQL 初始化SQL
-- 初始化表
CREATE TABLE `users`
(`id` BIGINT UNSIGNED AUTO_INCREMENT,`name` VARCHAR(100),`email` VARCHAR(255),PRIMARY KEY (`id`),UNIQUE INDEX `idx_users_email` (`email`)
);
2?? .env 文件
(用于本地調試和生產環境切換,借助 godotenv 讀取)
APP_PORT=8080
DB_DRIVER=mysql
DB_DSN=root:password@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=True&loc=Local
3?? config/config.go
package configimport ("log""os""github.com/joho/godotenv"
)type Config struct {AppPort stringDBDriver stringDBDsn string
}var Cfg Configfunc InitConfig() {_ = godotenv.Load() // 讀取 .env 文件Cfg = Config{AppPort: getEnv("APP_PORT", "8080"),DBDriver: getEnv("DB_DRIVER", "sqlite"),DBDsn: getEnv("DB_DSN", "test.db"),}
}func getEnv(key, defaultVal string) string {if value, exists := os.LookupEnv(key); exists {return value}return defaultVal
}
4?? model/user.go
package modeltype User struct {ID uint `gorm:"primaryKey"`Name string `gorm:"size:100"`Email string `gorm:"uniqueIndex"`
}
5?? dao/user_dao.go
package daoimport ("gin-gorm-demo/model""gorm.io/gorm"
)type UserDao struct {DB *gorm.DB
}func NewUserDao(db *gorm.DB) *UserDao {return &UserDao{DB: db}
}func (d *UserDao) Create(user *model.User) error {return d.DB.Create(user).Error
}func (d *UserDao) FindAll() ([]model.User, error) {var users []model.Usererr := d.DB.Find(&users).Errorreturn users, err
}func (d *UserDao) FindByID(id string) (*model.User, error) {var user model.Usererr := d.DB.First(&user, id).Errorreturn &user, err
}
6?? service/user_service.go
package serviceimport ("gin-gorm-demo/dao""gin-gorm-demo/model"
)type UserService struct {UserDao *dao.UserDao
}func NewUserService(userDao *dao.UserDao) *UserService {return &UserService{UserDao: userDao}
}func (s *UserService) CreateUser(user *model.User) error {return s.UserDao.Create(user)
}func (s *UserService) GetUsers() ([]model.User, error) {return s.UserDao.FindAll()
}func (s *UserService) GetUserByID(id string) (*model.User, error) {return s.UserDao.FindByID(id)
}
7?? handler/user_handler.go
package handlerimport ("gin-gorm-demo/model""gin-gorm-demo/service""net/http""github.com/gin-gonic/gin"
)type UserHandler struct {UserService *service.UserService
}func NewUserHandler(userService *service.UserService) *UserHandler {return &UserHandler{UserService: userService}
}func (h *UserHandler) CreateUser(c *gin.Context) {var user model.Userif err := c.ShouldBindJSON(&user); err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}if err := h.UserService.CreateUser(&user); err != nil {c.JSON(http.StatusInternalServerError, gin.H{"error": "保存失敗"})return}c.JSON(http.StatusOK, user)
}func (h *UserHandler) GetUsers(c *gin.Context) {users, err := h.UserService.GetUsers()if err != nil {c.JSON(http.StatusInternalServerError, gin.H{"error": "查詢失敗"})return}c.JSON(http.StatusOK, users)
}func (h *UserHandler) GetUserByID(c *gin.Context) {id := c.Param("id")user, err := h.UserService.GetUserByID(id)if err != nil {c.JSON(http.StatusNotFound, gin.H{"error": "用戶不存在"})return}c.JSON(http.StatusOK, user)
}
8?? router/router.go
package routerimport ("gin-gorm-demo/handler""github.com/gin-gonic/gin"
)func SetupRouter(userHandler *handler.UserHandler) *gin.Engine {r := gin.Default()r.POST("/users", userHandler.CreateUser)r.GET("/users", userHandler.GetUsers)r.GET("/users/:id", userHandler.GetUserByID)return r
}
9?? main.go
package mainimport ("fmt""gin-gorm-demo/config""gin-gorm-demo/dao""gin-gorm-demo/handler""gin-gorm-demo/model""gin-gorm-demo/router""gin-gorm-demo/service""log""gorm.io/driver/mysql""gorm.io/driver/sqlite""gorm.io/gorm"
)func initDB() *gorm.DB {var db *gorm.DBvar err errorif config.Cfg.DBDriver == "mysql" {db, err = gorm.Open(mysql.Open(config.Cfg.DBDsn), &gorm.Config{})} else {db, err = gorm.Open(sqlite.Open(config.Cfg.DBDsn), &gorm.Config{})}if err != nil {log.Fatal("數據庫連接失敗:", err)}// 自動建表db.AutoMigrate(&model.User{})return db
}func main() {// 初始化配置config.InitConfig()// 初始化數據庫db := initDB()// 初始化分層對象userDao := dao.NewUserDao(db)userService := service.NewUserService(userDao)userHandler := handler.NewUserHandler(userService)// 路由r := router.SetupRouter(userHandler)// 啟動服務addr := fmt.Sprintf(":%s", config.Cfg.AppPort)r.Run(addr)
}
打包運行
相關源碼鏈接
- GoLang整合 gin + gorm 框架源碼
https://download.csdn.net/download/YangCheney/91873119