HOW - Go 开发入门(四)- ORM 对象关系映射

文章目录

HOW - Go 开发入门(一) 我们进行了开发入门的开篇介绍。今天我们主要介绍第 3 步:接数据库(ORM)。

ORM 是什么?

ORM = Object-Relational Mapping(对象关系映射)

  • 核心目标:把数据库表和 Go 的 struct 对象 一一对应
  • 不用写大量 SQL,直接用熟悉的 struct + 方法操作数据库
  • 优势:
    • 简化开发
    • 避免手写重复 SQL
    • 提高可维护性

GORM 简介

GORM 是 Go 生态最流行的 ORM:

  • 支持 MySQL、Postgres、SQLite、SQLServer 等
  • 提供:
    • 自动迁移(自动生成表结构)
    • CRUD 方法
    • 关联关系(One2Many, Many2Many)
    • Hooks(回调:BeforeCreate, AfterUpdate 等)
  • 易用又贴近 Go 风格

初始化数据库连接

go 复制代码
package main

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

func main() {
    dsn := "root:123456@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
    if err != nil {
        panic("failed to connect database")
    }
    _ = db
}

说明:

  • dsn:数据库连接字符串
  • gorm.Open:返回 *gorm.DB 对象,用于操作数据库

定义 Model(结构体)

go 复制代码
type User struct {
    ID   uint   `gorm:"primaryKey"`
    Name string `gorm:"size:100"`
    Age  int
}
  • ID 主键
  • Name 限制长度 100
  • Age 默认 int
  • GORM 会自动根据 struct 创建对应表

自动迁移(创建表)

go 复制代码
db.AutoMigrate(&User{})
  • 自动创建表或修改表结构
  • 推荐在项目启动时调用

CRUD 基本操作

Create

go 复制代码
db.Create(&User{Name: "Tom", Age: 18})
  • 插入一条数据
  • 自动填充 ID

Read

go 复制代码
var user User
db.First(&user, 1)           // 根据主键查
db.Where("name = ?", "Tom").Find(&user) // 条件查询

Update

go 复制代码
db.Model(&user).Update("Age", 20)
db.Model(&user).Updates(User{Name: "Tommy", Age: 21})

Delete

go 复制代码
db.Delete(&user) // 根据主键删除

关联关系(常用)

One2Many

go 复制代码
type Order struct {
    ID     uint
    UserID uint
    Total  float64
}

type User struct {
    ID     uint
    Name   string
    Orders []Order
}
  • GORM 会自动识别 UserID 外键
  • 查用户 + 订单:
go 复制代码
var user User
db.Preload("Orders").First(&user, 1)

Many2Many

go 复制代码
type Role struct {
    ID   uint
    Name string
    Users []User `gorm:"many2many:user_roles;"`
}
  • 自动生成中间表 user_roles

Hooks(回调)

  • BeforeCreate / AfterCreate / BeforeUpdate / AfterDelete
  • 用于做统一日志、验证、缓存等
go 复制代码
func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
    if u.Age < 0 {
        return errors.New("invalid age")
    }
    return nil
}

高级功能

  • 事务
go 复制代码
tx := db.Begin()
if err := tx.Create(&User{Name: "Alice"}).Error; err != nil {
    tx.Rollback()
} else {
    tx.Commit()
}
  • 原生 SQL
go 复制代码
db.Raw("SELECT * FROM users WHERE age > ?", 18).Scan(&users)

Go + GORM 的工程化思路

  1. 每张表定义一个 struct(model)
  2. 提供 CRUD 方法(Repository/Service 层)
  3. 启动时自动迁移表
  4. 对于复杂查询,使用原生 SQL 或 chain 方法
  5. 用 interface 封装数据库操作 → 可替换 MySQL / Postgres / 测试 mock
相关推荐
IvanCodes11 小时前
Python 数据处理(十三):JSON、CSV 与数据序列化
开发语言·python
步行cgn12 小时前
Spring c 命名空间注入详解
java·后端·spring
明月_清风12 小时前
Maven 到底是什么?一篇文章搞懂 Java 项目构建与依赖管理
java·后端·maven
明月_清风12 小时前
AI 越来越强,程序员真正的价值到底是什么?
人工智能·后端
aramae12 小时前
MySQL复合查询(8)
java·c语言·开发语言·后端·算法
Rain的Java大神之路13 小时前
如何快速上传10G文件
java·spring boot·redis·后端·mysql·spring cloud·面试
码事漫谈14 小时前
别再跟AI说“请”了,它根本不 care——但有个东西它超在意
后端
qq_25183645715 小时前
springboot vue3 开发实现 拼豆管理系统
java·开发语言·ai编程
郑州光合科技余经理16 小时前
同城外卖小程序开发:下单成功后,后台导出能不能对上用户端状态
开发语言·前端·git·后端·uni-app·php·ai编程
知识分享小能手16 小时前
C++ 学习教程,从入门到精通,C++ 入门知识 — 完整知识点(1)
开发语言·c++·学习