一个高度可扩展的 Golang ORM 库【GORM】
GORM 是一个功能强大的 Golang 对象关系映射(ORM)库,它提供了简洁的接口和全面的功能,帮助开发者更方便地操作数据库。
1. 完整的 ORM 功能
• 支持常见的关系模型:
• Has One(一对一)
• Has Many(一对多)
• Belongs To(从属)
• Many To Many(多对多)
• 多态关联(Polymorphism)
• 单表继承(Single Table Inheritance)
2. 钩子函数(Hooks)
• 支持模型的生命周期钩子,例如:
• BeforeCreate / AfterCreate
• BeforeSave / AfterSave
• BeforeUpdate / AfterUpdate
• BeforeDelete / AfterDelete
• BeforeFind / AfterFind
3. 数据查询与加载
• 预加载(Preload):一次性加载关联数据。
• 联表查询(Joins):通过 SQL JOIN 查询关联表。
4. 事务支持
• 支持事务管理,包括:
• 开启事务
• 嵌套事务
• 保存点(Save Point)
• 回滚到特定保存点
5. 复杂功能支持
• SQL 构建器:支持动态生成复杂的 SQL 查询。
• 乐观锁与悲观锁:通过 Select For Update 等机制实现。
• 复合主键:支持定义多个字段作为主键。
• 索引与约束:可为模型字段添加索引和约束规则。
6. 自动迁移
• 根据模型结构自动创建或更新数据库表。
demo例子
模型定义
type User struct {
ID uint `gorm:"primaryKey"`
Name string
Email string `gorm:"unique"`
Age int
CreatedAt time.Time
}
基本操作
// 创建记录
db.Create(&User{Name: "Alice", Email: "alice@example.com", Age: 25})
// 查询记录
var user User
db.First(&user, 1) // 查询主键为 1 的记录
db.Where("name = ?", "Alice").First(&user)
// 更新记录
db.Model(&user).Update("Age", 26)
// 删除记录
db.Delete(&user)
完整代码:
package main
import (
"fmt"
"log"
"net/http"
"time"
"github.com/gin-gonic/gin"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
// User 模型
type User struct {
ID uint `gorm:"primaryKey"`
Name string `json:"name"`
Email string `json:"email" gorm:"unique"`
Age int `json:"age"`
CreatedAt time.Time `json:"created_at"`
}
// 初始化数据库
func initDB() *gorm.DB {
// 使用 SQLite 数据库(也可以替换为 MySQL、PostgreSQL 等)
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
if err != nil {
log.Fatal("Failed to connect to database:", err)
}
// 自动迁移表结构
if err := db.AutoMigrate(&User{}); err != nil {
log.Fatal("Failed to migrate database:", err)
}
return db
}
func main() {
// 初始化数据库
db := initDB()
// 初始化 Gin 路由
r := gin.Default()
// 创建用户
r.POST("/users", func(c *gin.Context) {
var user User
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if result := db.Create(&user); result.Error != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()})
return
}
c.JSON(http.StatusCreated, user)
})
// 获取所有用户
r.GET("/users", func(c *gin.Context) {
var users []User
if result := db.Find(&users); result.Error != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()})
return
}
c.JSON(http.StatusOK, users)
})
// 根据 ID 获取用户
r.GET("/users/:id", func(c *gin.Context) {
id := c.Param("id")
var user User
if result := db.First(&user, id); result.Error != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
return
}
c.JSON(http.StatusOK, user)
})
// 更新用户
r.PUT("/users/:id", func(c *gin.Context) {
id := c.Param("id")
var user User
if result := db.First(&user, id); result.Error != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
return
}
var input User
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// 更新字段
user.Name = input.Name
user.Email = input.Email
user.Age = input.Age
db.Save(&user)
c.JSON(http.StatusOK, user)
})
// 删除用户
r.DELETE("/users/:id", func(c *gin.Context) {
id := c.Param("id")
if result := db.Delete(&User{}, id); result.Error != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "User deleted successfully"})
})
// 启动服务
if err := r.Run(":8080"); err != nil {
log.Fatal("Failed to start server:", err)
}
}