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
相关推荐
2401_879503412 小时前
C++中的状态模式实战
开发语言·c++·算法
Aawy1202 小时前
自定义字面量实战
开发语言·c++·算法
Red丶哞2 小时前
RustFS 使用 S3 Python SDK(Boto3)文档
开发语言·python
计算机学姐2 小时前
基于SpringBoot的汽车美容保养系统
java·spring boot·后端·spring·tomcat·汽车·mybatis
爱吃山竹的大肚肚2 小时前
依赖冲突快速解决
java·spring boot·后端·spring cloud·maven
得物技术2 小时前
大禹平台:流批一体离线Dump平台的设计与应用|得物技术
java·后端·算法
Java编程爱好者2 小时前
Java工程师复健Spring IoC:所有Java开发的第一个面试题
后端
轩情吖2 小时前
MySQL之表的增删查改
android·开发语言·c++·后端·mysql·adb·
卤蛋七号2 小时前
springboot整合validation详细教程
后端