在Golang项目开发中,使用gorm框架可以大幅简化数据库操作的复杂度,避免手动编写繁琐的SQL语句,同时支持多种主流数据库,适配性很强。下面将从基础准备到实际操作逐步讲解完整的使用流程。

环境准备与依赖安装
首先需要在项目中安装gorm核心库和对应数据库的驱动,以MySQL为例,执行以下命令安装依赖:
# 安装gorm核心库 go get -u gorm.io/gorm # 安装MySQL驱动 go get -u gorm.io/driver/mysql
如果使用其他数据库,只需要替换对应的驱动即可,比如PostgreSQL可以安装gorm.io/driver/postgres,SQLite可以安装gorm.io/driver/sqlite。
连接数据库
gorm连接数据库需要传入对应的DSN字符串,不同数据库的DSN格式略有差异,下面是MySQL的连接示例:
package main
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
"log"
)
func main() {
// MySQL的DSN格式:用户名:密码@tcp(数据库地址:端口)/数据库名?参数
dsn := "root:123456@tcp(127.0.0.1:3306)/test_db?charset=utf8mb4&parseTime=True&loc=Local"
// 打开数据库连接
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatalf("连接数据库失败: %v", err)
}
// 获取底层sql.DB对象,可设置连接池参数
sqlDB, err := db.DB()
if err != nil {
log.Fatalf("获取底层DB对象失败: %v", err)
}
// 设置最大打开连接数
sqlDB.SetMaxOpenConns(100)
// 设置最大空闲连接数
sqlDB.SetMaxIdleConns(10)
log.Println("数据库连接成功")
}
定义模型与自动建表
gorm通过结构体来映射数据库表,结构体的字段对应表的列,下面是用户表的模型定义示例:
// User 用户模型,对应数据库中的users表
type User struct {
// gorm.Model内置了ID、CreatedAt、UpdatedAt、DeletedAt字段
gorm.Model
Name string `gorm:"type:varchar(100);not null"` // 用户名,非空,长度100
Age int `gorm:"type:int;default:0"` // 年龄,默认0
Email string `gorm:"type:varchar(100);unique"` // 邮箱,唯一
}
定义好模型后,可以使用AutoMigrate方法自动创建表或者更新表结构:
// 自动迁移表结构,会创建users表,如果表已存在会更新字段
err = db.AutoMigrate(&User{})
if err != nil {
log.Fatalf("自动建表失败: %v", err)
}
数据插入操作
插入单条数据和批量插入的示例如下:
// 插入单条数据
user1 := User{Name: "张三", Age: 20, Email: "zhangsan@ipipp.com"}
result := db.Create(&user1)
if result.Error != nil {
log.Printf("插入单条数据失败: %v", result.Error)
} else {
log.Printf("插入成功,用户ID: %d", user1.ID)
}
// 批量插入数据
users := []User{
{Name: "李四", Age: 22, Email: "lisi@ipipp.com"},
{Name: "王五", Age: 25, Email: "wangwu@ipipp.com"},
}
result = db.Create(&users)
if result.Error != nil {
log.Printf("批量插入失败: %v", result.Error)
} else {
log.Printf("批量插入成功,插入条数: %d", result.RowsAffected)
}
数据查询操作
gorm提供了丰富的查询方法,下面是常见的查询场景示例:
// 查询单条数据,根据主键查询
var user User
db.First(&user, 1) // 查询ID为1的用户
log.Printf("查询到的用户: %+v", user)
// 根据条件查询单条数据
db.Where("name = ?", "张三").First(&user)
log.Printf("姓名为张三的用户: %+v", user)
// 查询多条数据
var userList []User
db.Where("age > ?", 20).Find(&userList) // 查询年龄大于20的所有用户
log.Printf("年龄大于20的用户列表: %+v", userList)
// 查询所有数据
db.Find(&userList)
log.Printf("所有用户: %+v", userList)
// 统计数量
var count int64
db.Model(&User{}).Where("age > ?", 20).Count(&count)
log.Printf("年龄大于20的用户数量: %d", count)
数据更新操作
更新操作可以分为更新单个字段和批量更新多个字段:
// 更新单个字段,更新ID为1的用户年龄
db.Model(&User{}).Where("id = ?", 1).Update("age", 21)
// 更新多个字段
db.Model(&User{}).Where("id = ?", 1).Updates(User{Name: "张三三", Age: 22})
// 使用map更新多个字段
db.Model(&User{}).Where("id = ?", 1).Updates(map[string]interface{}{"name": "张三", "age": 23})
数据删除操作
gorm默认使用软删除,也就是不会真正删除数据库记录,而是更新deleted_at字段,如果需要硬删除可以调用Unscoped方法:
// 软删除,ID为1的用户会被标记删除
db.Delete(&User{}, 1)
// 硬删除,真正从数据库中删除记录
db.Unscoped().Delete(&User{}, 1)
// 根据条件批量软删除
db.Where("age < ?", 18).Delete(&User{})
注意事项
- DSN中的参数需要根据实际情况调整,比如时区、字符集等,避免出现时间解析错误或者乱码问题
- 模型结构体的字段标签可以自定义列名、类型、约束等,不需要和结构体字段名完全一致
- 软删除的记录默认不会被普通查询语句查到,如果需要查询包含软删除的记录,可以使用
Unscoped方法 - 连接池的参数需要根据项目的实际并发量调整,避免连接数不足或者资源浪费