GORM集成 #
一、GORM安装 #
1.1 安装GORM #
bash
go get gorm.io/gorm
go get gorm.io/driver/mysql
1.2 其他数据库驱动 #
bash
go get gorm.io/driver/postgres
go get gorm.io/driver/sqlite
go get gorm.io/driver/sqlserver
二、数据库连接 #
2.1 MySQL连接 #
go
package main
import (
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
var db *gorm.DB
func initDB() error {
dsn := "root:password@tcp(localhost:3306)/myapp?charset=utf8mb4&parseTime=True&loc=Local"
var err error
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
return err
}
sqlDB, err := db.DB()
if err != nil {
return err
}
sqlDB.SetMaxOpenConns(25)
sqlDB.SetMaxIdleConns(5)
sqlDB.SetConnMaxLifetime(5 * time.Minute)
return nil
}
2.2 SQLite连接 #
go
db, err := gorm.Open(sqlite.Open("myapp.db"), &gorm.Config{})
2.3 PostgreSQL连接 #
go
dsn := "host=localhost user=postgres password=password dbname=myapp port=5432 sslmode=disable"
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
三、模型定义 #
3.1 基本模型 #
go
type User struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"size:100;not null" json:"name"`
Email string `gorm:"size:100;uniqueIndex;not null" json:"email"`
Password string `gorm:"size:255;not null" json:"-"`
Age int `gorm:"default:0" json:"age"`
Status string `gorm:"size:20;default:'active'" json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}
3.2 模型标签 #
| 标签 | 说明 |
|---|---|
| primaryKey | 主键 |
| uniqueIndex | 唯一索引 |
| index | 普通索引 |
| size | 字段长度 |
| not null | 非空 |
| default | 默认值 |
| unique | 唯一 |
| comment | 注释 |
| autoIncrement | 自增 |
3.3 关联模型 #
go
type User struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `json:"name"`
Posts []Post `gorm:"foreignKey:UserID" json:"posts"`
Profile Profile `gorm:"foreignKey:UserID" json:"profile"`
}
type Post struct {
ID uint `gorm:"primaryKey" json:"id"`
Title string `json:"title"`
Body string `json:"body"`
UserID uint `json:"user_id"`
User User `json:"user"`
}
type Profile struct {
ID uint `gorm:"primaryKey" json:"id"`
Bio string `json:"bio"`
UserID uint `json:"user_id"`
}
四、自动迁移 #
4.1 迁移模型 #
go
func main() {
initDB()
db.AutoMigrate(
&User{},
&Post{},
&Profile{},
)
}
4.2 检查表是否存在 #
go
if db.Migrator().HasTable(&User{}) {
fmt.Println("Users table exists")
}
4.3 创建表 #
go
db.Migrator().CreateTable(&User{})
4.4 删除表 #
go
db.Migrator().DropTable(&User{})
五、CRUD操作 #
5.1 创建 #
go
user := User{
Name: "张三",
Email: "zhangsan@example.com",
Password: "hashed_password",
Age: 25,
}
result := db.Create(&user)
if result.Error != nil {
return result.Error
}
fmt.Println(user.ID)
5.2 批量创建 #
go
users := []User{
{Name: "张三", Email: "zhangsan@example.com"},
{Name: "李四", Email: "lisi@example.com"},
}
db.Create(&users)
5.3 查询单条 #
go
var user User
db.First(&user, 1)
db.First(&user, "email = ?", "zhangsan@example.com")
db.Where("name = ?", "张三").First(&user)
5.4 查询多条 #
go
var users []User
db.Find(&users)
db.Where("age > ?", 20).Find(&users)
db.Where("name LIKE ?", "%张%").Find(&users)
db.Order("created_at desc").Find(&users)
db.Limit(10).Offset(0).Find(&users)
5.5 分页查询 #
go
func getUsers(page, size int) ([]User, int64) {
var users []User
var total int64
db.Model(&User{}).Count(&total)
offset := (page - 1) * size
db.Offset(offset).Limit(size).Find(&users)
return users, total
}
5.6 更新 #
go
db.Model(&user).Update("name", "李四")
db.Model(&user).Updates(User{Name: "李四", Age: 30})
db.Model(&user).Updates(map[string]interface{}{
"name": "王五",
"age": 28,
})
db.Model(&User{}).Where("status = ?", "inactive").Update("status", "active")
5.7 删除 #
go
db.Delete(&user)
db.Delete(&User{}, 1)
db.Where("name = ?", "张三").Delete(&User{})
5.8 软删除 #
go
type User struct {
ID uint `gorm:"primaryKey"`
Name string
DeletedAt gorm.DeletedAt `gorm:"index"`
}
db.Delete(&user)
db.Unscoped().Find(&users)
六、查询条件 #
6.1 Where条件 #
go
db.Where("name = ?", "张三").First(&user)
db.Where("name <> ?", "张三").Find(&users)
db.Where("age > ?", 20).Find(&users)
db.Where("age BETWEEN ? AND ?", 20, 30).Find(&users)
db.Where("name IN ?", []string{"张三", "李四"}).Find(&users)
db.Where("name LIKE ?", "%张%").Find(&users)
db.Where("name = ? AND age > ?", "张三", 20).Find(&users)
6.2 Or条件 #
go
db.Where("name = ?", "张三").Or("name = ?", "李四").Find(&users)
6.3 Not条件 #
go
db.Not("name = ?", "张三").Find(&users)
6.4 In条件 #
go
db.Where("id IN ?", []int{1, 2, 3}).Find(&users)
6.5 排序 #
go
db.Order("age desc").Find(&users)
db.Order("age desc, name asc").Find(&users)
6.6 分组 #
go
type Result struct {
Status string
Count int
}
var results []Result
db.Model(&User{}).Select("status, count(*) as count").Group("status").Find(&results)
七、关联查询 #
7.1 预加载 #
go
db.Preload("Posts").Find(&users)
db.Preload("Posts").Preload("Profile").Find(&users)
db.Preload("Posts", "status = ?", "published").Find(&users)
7.2 关联创建 #
go
user := User{
Name: "张三",
Posts: []Post{
{Title: "文章1", Body: "内容1"},
{Title: "文章2", Body: "内容2"},
},
}
db.Create(&user)
7.3 关联查询 #
go
var user User
db.First(&user, 1)
var posts []Post
db.Model(&user).Association("Posts").Find(&posts)
八、事务 #
8.1 自动事务 #
go
err := db.Transaction(func(tx *gorm.DB) error {
if err := tx.Create(&User{Name: "张三"}).Error; err != nil {
return err
}
if err := tx.Create(&Post{Title: "文章"}).Error; err != nil {
return err
}
return nil
})
8.2 手动事务 #
go
tx := db.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
if err := tx.Create(&User{Name: "张三"}).Error; err != nil {
tx.Rollback()
return err
}
if err := tx.Create(&Post{Title: "文章"}).Error; err != nil {
tx.Rollback()
return err
}
tx.Commit()
九、完整示例 #
go
package main
import (
"fmt"
"net/http"
"time"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"github.com/labstack/echo/v4"
)
type User struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"size:100;not null" json:"name"`
Email string `gorm:"size:100;uniqueIndex;not null" json:"email"`
Age int `gorm:"default:0" json:"age"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}
type Post struct {
ID uint `gorm:"primaryKey" json:"id"`
Title string `gorm:"size:200;not null" json:"title"`
Body string `json:"body"`
UserID uint `json:"user_id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}
var db *gorm.DB
func initDB() error {
dsn := "root:password@tcp(localhost:3306)/myapp?charset=utf8mb4&parseTime=True&loc=Local"
var err error
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
return err
}
db.AutoMigrate(&User{}, &Post{})
return nil
}
func main() {
if err := initDB(); err != nil {
panic(err)
}
e := echo.New()
e.GET("/users", listUsers)
e.GET("/users/:id", getUser)
e.POST("/users", createUser)
e.PUT("/users/:id", updateUser)
e.DELETE("/users/:id", deleteUser)
e.Logger.Fatal(e.Start(":8080"))
}
func listUsers(c echo.Context) error {
page := 1
size := 10
var users []User
var total int64
db.Model(&User{}).Count(&total)
offset := (page - 1) * size
db.Offset(offset).Limit(size).Find(&users)
return c.JSON(http.StatusOK, map[string]interface{}{
"data": users,
"total": total,
"page": page,
"size": size,
})
}
func getUser(c echo.Context) error {
id := c.Param("id")
var user User
if err := db.First(&user, id).Error; err != nil {
return echo.NewHTTPError(http.StatusNotFound, "用户不存在")
}
return c.JSON(http.StatusOK, user)
}
func createUser(c echo.Context) error {
user := new(User)
if err := c.Bind(user); err != nil {
return err
}
if err := db.Create(user).Error; err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
}
return c.JSON(http.StatusCreated, user)
}
func updateUser(c echo.Context) error {
id := c.Param("id")
var user User
if err := db.First(&user, id).Error; err != nil {
return echo.NewHTTPError(http.StatusNotFound, "用户不存在")
}
if err := c.Bind(&user); err != nil {
return err
}
db.Save(&user)
return c.JSON(http.StatusOK, user)
}
func deleteUser(c echo.Context) error {
id := c.Param("id")
if err := db.Delete(&User{}, id).Error; err != nil {
return echo.NewHTTPError(http.StatusNotFound, "用户不存在")
}
return c.NoContent(http.StatusNoContent)
}
十、总结 #
GORM集成要点:
| 要点 | 说明 |
|---|---|
| 连接 | gorm.Open() |
| 模型 | struct定义 |
| 迁移 | AutoMigrate() |
| 创建 | Create() |
| 查询 | First()、Find() |
| 更新 | Update()、Updates() |
| 删除 | Delete() |
| 事务 | Transaction() |
准备好学习Redis集成了吗?让我们进入下一章!
最后更新:2026-03-28