当前位置: 首页 > article >正文

一个高度可扩展的 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)
	}
}


http://www.kler.cn/a/409619.html

相关文章:

  • 二进制与网络安全的关系
  • 数据集-目标检测系列- 花卉 玫瑰 检测数据集 rose >> DataBall
  • STM32的中断(什么是外部中断和其他中断以及中断号是什么)
  • 非常简单实用的前后端分离项目-仓库管理系统(Springboot+Vue)part 2
  • web前端开发--动画效果
  • HarmonyOs鸿蒙开发实战(20)=>一文学会基础使用组件导航Navigation
  • git仓库:循环所有提交、查找有无指定文件名
  • Docker--通过Docker容器创建一个Web服务器
  • 使用 Volta 管理 Node.js 版本
  • Android 项目引入gradle Connect timed out
  • 9款电子合同平台性价比深度分析
  • 数据分析-机器学习-第三方库使用基础
  • 内存不足引发C++程序闪退崩溃问题的分析与总结
  • 设计模式:7、策略模式(政策)
  • SpringBoot源码解析(五):准备应用环境
  • Design a Multiplayer Hero Shooter Map in UE5
  • Cocos游戏优化
  • 大模型论文速递(11.23-11.25)
  • Linux操作系统学习---初识环境变量
  • 力扣-Hot100-栈【算法学习day.40】
  • 梧桐数据库的高效索引技术行业调研报告
  • 理解clickhouse 里的分区和分片键区别
  • 降本增效的新利器
  • 第49届ICPC亚洲区域赛,非凸科技再次支持上海赛站
  • TensorFlow手动更新模型特定变量
  • 重写radioselect类自定义个性化单选框