3-gorm解决传统msyql的痛点问题

我们引入 GORM,本质就是为了更便捷地操作数据库。 写原生 SQL 最大痛点就是要自己手动把查询结果映射到结构体,字段多了写起来又啰嗦又容易出错。

其实数据表和 Go 结构体本身就是一套一一对应的关系:一张表对应一个结构体,一条记录对应一个结构体对象,一列对应结构体的一个字段。 这也是所有 ORM 框架的核心逻辑 ------ 专门负责自动完成表和结构体之间的数据映射,不用我们手动处理字段赋值。

搞懂这套映射逻辑,再去学习 GORM 的使用,上手会快很多。

1.基础环境要求的安装

复制代码
go get -u gorm.io/gorm
go get gorm.io/driver/mysql

2.综合代码

复制代码
package main

import (
	"fmt"
	"log"
	"time"

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

// User 对应 testdb.user 表
type User struct {
	ID       uint      `gorm:"primaryKey;autoIncrement"`
	Username string    `gorm:"column:username"`
	Age      int       `gorm:"column:age"`
	CreateAt time.Time `gorm:"column:create_at"`
}

// 固定表名为 user,禁止自动复数users
func (User) TableName() string {
	return "user"
}

func main() {
	dsn := "root:123456@tcp(127.0.0.1:3306)/godb?charset=utf8mb4&parseTime=True&loc=Local"

	gormConfig := &gorm.Config{
		SkipDefaultTransaction: true,
	}
	db, err := gorm.Open(mysql.Open(dsn), gormConfig)
	if err != nil {
		log.Fatal("连接数据库失败:", err)
	}

	// 先获取底层sqlDB,处理error
	sqlDB, err := db.DB()
	if err != nil {
		log.Fatal("获取底层连接池失败:", err)
	}
	// 程序退出关闭连接池
	defer func() {
		if err := sqlDB.Close(); err != nil {
			log.Println("关闭连接池失败:", err)
		}
	}()

	// 连接池配置
	sqlDB.SetMaxOpenConns(10)
	sqlDB.SetMaxIdleConns(5)
	sqlDB.SetConnMaxLifetime(time.Hour)
	sqlDB.SetConnMaxIdleTime(30 * time.Minute)

	// 增删改查流程
	uid := createDemo(db)
	fmt.Println("-----------------------")

	getOne(db, uid)
	fmt.Println("-----------------------")

	updateDemo(db, uid)
	fmt.Println("修改完成,重新查询:")
	getOne(db, uid)
	fmt.Println("-----------------------")

	var userList []User
	if err := db.Find(&userList).Error; err != nil {
		log.Fatal("查询全部失败:", err)
	}
	fmt.Printf("所有用户:%+v\n", userList)
	fmt.Println("-----------------------")

	deleteDemo(db, uid)
	fmt.Println("删除后列表:")
	if err := db.Find(&userList).Error; err != nil {
		log.Fatal("查询全部失败:", err)
	}
	fmt.Printf("%+v\n", userList)
}

// 新增
func createDemo(db *gorm.DB) uint {
	user := User{
		Username: "小明1",
		Age:      18,
	}
	if err := db.Create(&user).Error; err != nil {
		log.Fatal("新增用户失败:", err)
	}
	fmt.Println("新增自增ID:", user.ID)
	return user.ID
}

// 查单条
func getOne(db *gorm.DB, uid uint) {
	var u User
	if err := db.First(&u, uid).Error; err != nil {
		log.Fatal("查询单条失败:", err)
	}
	fmt.Printf("单条数据:%+v\n", u)
}

// 修改
func updateDemo(db *gorm.DB, uid uint) {
	err := db.Model(&User{}).Where("id = ?", uid).Updates(User{
		Username: "小明改名",
		Age:      20,
	}).Error
	if err != nil {
		log.Fatal("更新数据失败:", err)
	}
	fmt.Println("更新成功")
}

// 物理删除 Unscoped 关闭软删除
func deleteDemo(db *gorm.DB, uid uint) {
	err := db.Unscoped().Delete(&User{}, uid).Error
	if err != nil {
		log.Fatal("删除数据失败:", err)
	}
	fmt.Println("删除成功")
}