Skip to content
鼓励作者:欢迎打赏犒劳

gorm初体验

特殊设置

显示sql

go
//第一种 db后面加Debug()
var user User
db.Debug().Take(&user, 1)
fmt.Printf("user: %+v\n", user)

//第二种 全局设置
dsn := "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
// 连接数据库
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
    Logger: logger.Default.LogMode(logger.Info), // 设置日志级别为Info,显示所有SQL
})

指定表名

因为gorm默认是按照对象的驼峰转下划线后面加s当做表名的,比如 TestTime -> test_times , 如果我们想要显示的指定也是可以的。

go
db.Table("test_time").First(&result1)

数据库表

sql
CREATE TABLE `users` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
  `email` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
  `age` tinyint(3) unsigned NOT NULL,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;


CREATE TABLE `articles` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(200) COLLATE utf8mb4_unicode_ci NOT NULL,
  `content` text COLLATE utf8mb4_unicode_ci,
  `user_id` bigint(20) unsigned NOT NULL,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_articles_user_id` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

mock数据

sql
INSERT INTO `test`.`users`(`id`, `name`, `email`, `age`, `created_at`, `updated_at`) VALUES (1, '张三', 'zhangsan@example.com', 25, '2025-09-16 12:53:22', '2025-09-16 12:53:22');
INSERT INTO `test`.`users`(`id`, `name`, `email`, `age`, `created_at`, `updated_at`) VALUES (2, '李四', 'lisi@example.com', 30, '2025-09-16 12:53:22', '2025-09-16 12:53:22');
INSERT INTO `test`.`users`(`id`, `name`, `email`, `age`, `created_at`, `updated_at`) VALUES (3, '赵六', 'zhaoliu@example.com', 35, '2025-09-16 12:53:22', '2025-09-16 12:53:22');


INSERT INTO `test`.`articles`(`id`, `title`, `content`, `user_id`, `created_at`, `updated_at`) VALUES (1, 'GORM使用指南', '这是一篇关于GORM的详细教程...', 1, '2025-09-16 12:53:22', '2025-09-16 12:53:22');
INSERT INTO `test`.`articles`(`id`, `title`, `content`, `user_id`, `created_at`, `updated_at`) VALUES (2, 'Go语言入门', '学习Go语言的基础知识...', 1, '2025-09-16 12:53:22', '2025-09-16 12:53:22');
INSERT INTO `test`.`articles`(`id`, `title`, `content`, `user_id`, `created_at`, `updated_at`) VALUES (3, 'Web开发实战', '使用Go进行Web开发...', 2, '2025-09-16 12:53:22', '2025-09-16 12:53:22');
INSERT INTO `test`.`articles`(`id`, `title`, `content`, `user_id`, `created_at`, `updated_at`) VALUES (4, '数据库设计原则', '良好的数据库设计实践...', 3, '2025-09-16 12:53:22', '2025-09-16 12:53:22');

插入数据

go
package main

import (
	"fmt"
	"log"
	"time"

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

// 定义用户模型
type User struct {
	ID        uint      `gorm:"primaryKey"`           // 主键
	Name      string    `gorm:"size:100;not null"`    // 用户名,长度限制100,非空
	Email     string    `gorm:"size:100;uniqueIndex"` // 邮箱,长度限制100,唯一索引
	Age       uint8     `gorm:"check:age > 0"`        // 年龄,检查约束
	Articles  []Article `gorm:"foreignKey:UserID"`    // 用户拥有的文章列表
	CreatedAt time.Time // 创建时间
	UpdatedAt time.Time // 更新时间
}

// 定义文章模型(与用户是一对多关系)
type Article struct {
	ID        uint      `gorm:"primaryKey"`                                                      // 主键
	Title     string    `gorm:"size:200;not null"`                                               // 文章标题
	Content   string    `gorm:"type:text"`                                                       // 文章内容,使用文本类型
	UserID    uint      `gorm:"not null"`                                                        // 外键,关联用户ID
	User      User      `gorm:"foreignKey:UserID"` // 属于用户关系
	CreatedAt time.Time // 创建时间
	UpdatedAt time.Time // 更新时间
}

func main() {
	// MySQL 连接配置
	// 格式: "user:password@tcp(host:port)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
	dsn := "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"

	// 连接数据库
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		Logger: logger.Default.LogMode(logger.Info), // 设置日志级别为Info,显示所有SQL
	})
	if err != nil {
		log.Fatal("Failed to connect to database:", err)
	}

	// 获取底层的 sql.DB 对象并设置连接池
	sqlDB, err := db.DB()
	if err != nil {
		log.Fatal("Failed to get database instance:", err)
	}

	// 设置连接池参数
	sqlDB.SetMaxIdleConns(10)           // 最大空闲连接数
	sqlDB.SetMaxOpenConns(100)          // 最大打开连接数
	sqlDB.SetConnMaxLifetime(time.Hour) // 连接的最大可复用时间

	// 插入Mock数据
	insertMockData(db)
	
	// 关闭数据库连接
	if err := sqlDB.Close(); err != nil {
		log.Fatal("Failed to close database:", err)
	}
}

// 插入Mock数据
func insertMockData(db *gorm.DB) {
	// 先清空表
	db.Exec("DELETE FROM articles")
	db.Exec("DELETE FROM users")

	// 创建用户
	users := []User{
		{Name: "张三", Email: "zhangsan@example.com", Age: 25},
		{Name: "李四", Email: "lisi@example.com", Age: 30},
		{Name: "赵六", Email: "zhaoliu@example.com", Age: 35},
	}

	for i := range users {
		result := db.Create(&users[i])
		if result.Error != nil {
			log.Fatal("Failed to create user:", result.Error)
		}
	}

	// 创建文章
	articles := []Article{
		{Title: "GORM使用指南", Content: "这是一篇关于GORM的详细教程...", UserID: users[0].ID},
		{Title: "Go语言入门", Content: "学习Go语言的基础知识...", UserID: users[0].ID},
		{Title: "Web开发实战", Content: "使用Go进行Web开发...", UserID: users[1].ID},
		{Title: "数据库设计原则", Content: "良好的数据库设计实践...", UserID: users[2].ID},
	}

	for i := range articles {
		result := db.Create(&articles[i])
		if result.Error != nil {
			log.Fatal("Failed to create article:", result.Error)
		}
	}

	fmt.Println("Mock数据插入完成")
}

查询数据

go
package main

import (
	"fmt"
	"log"
	"time"

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

// 定义用户模型
type User struct {
	ID        uint      `gorm:"primaryKey"`           // 主键
	Name      string    `gorm:"size:100;not null"`    // 用户名,长度限制100,非空
	Email     string    `gorm:"size:100;uniqueIndex"` // 邮箱,长度限制100,唯一索引
	Age       uint8     `gorm:"check:age > 0"`        // 年龄,检查约束
	CreatedAt time.Time // 创建时间
	UpdatedAt time.Time // 更新时间
}

func main() {
	// MySQL 连接配置
	// 格式: "user:password@tcp(host:port)/dbname?charset=utf8mb4&parseTime=True&loc=Asia%2FShanghai"
	dsn := "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"

	// 连接数据库
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		Logger: logger.Default.LogMode(logger.Info), // 设置日志级别为Info,显示所有SQL
	})
	if err != nil {
		log.Fatal("Failed to connect to database:", err)
	}
	// 示例:查询所有用户及其文章
	fmt.Println("=== 所有用户及其文章 ===")
	var users []User
	db.Model(&User{}).Find(&users) // Preload预加载关联的文章
	for _, user := range users {
		fmt.Printf("用户: %s (%d岁), 邮箱: %s\n", user.Name, user.Age, user.Email)
	}
}

根据id主键查询

take 只认主键

go
// 示例:用take查询,后面传id,生成的sql:SELECT * FROM `users` WHERE `users`.`id` = 1 LIMIT 1
// 如果不传id的话,sql则是 SELECT * FROM `users`  LIMIT 1
// 如果传入的 &user 对象id有值的话,则会自动当做条件添加在where后面
var user User
//user.ID = 3  // SELECT * FROM `users` WHERE `users`.`id` = 1 AND `users`.`id` = 3 LIMIT 1
db.Take(&user, 1)
fmt.Printf("user: %+v\n", user)



// 第二种,效果一样
var user User
db.First(&user, 3)
fmt.Printf("user: %+v\n", user)

where 条件查询

go
// 示例:条件查询
fmt.Println("\n=== 年龄大于25岁的用户 ===")
var olderUsers []User
db.Where("age > ?", 25).Find(&olderUsers)
for _, user := range olderUsers {
    fmt.Printf("用户: %s (%d岁)\n", user.Name, user.Age)
}

分页查询

go
package main

import (
	"fmt"
	"log"
	"strings"
	"time"

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

// 定义用户模型
type User struct {
	ID        uint      `gorm:"primaryKey"`           // 主键
	Name      string    `gorm:"size:100;not null"`    // 用户名,长度限制100,非空
	Email     string    `gorm:"size:100;uniqueIndex"` // 邮箱,长度限制100,唯一索引
	Age       uint8     `gorm:"check:age > 0"`        // 年龄,检查约束
	CreatedAt time.Time // 创建时间
	UpdatedAt time.Time // 更新时间
}
type UserQuery struct {
	IDs       []uint     // id in ?
	Name      *string    // name LIKE ?
	Email     *string    // email = ?
	MinAge    *uint8     // age > ?
	StartTime *time.Time // created_at >= ?
	EndTime   *time.Time // created_at <= ?

	Page     int `json:"page" form:"page"`           // 页码
	PageSize int `json:"page_size" form:"page_size"` // 每页数量

	SortField *string `json:"sort_field" form:"sort_field"` // 排序字段,如 "created_at", "age"
	SortOrder *string `json:"sort_order" form:"sort_order"` // 排序顺序:asc 或 desc
}
type PaginatedResult struct {
	List       interface{} `json:"list"`
	Total      int64       `json:"total"`
	Page       int         `json:"page"`
	PageSize   int         `json:"page_size"`
	TotalPages int         `json:"total_pages"`
}

func PaginateUsers(db *gorm.DB, query *UserQuery) (*PaginatedResult, error) {
	var users []User
	var total int64

	// 构建基础查询(带所有 WHERE 条件)
	baseDB := query.BuildWhere(db.Model(&User{}))

	// 第一步:获取总数(COUNT)
	if err := baseDB.Count(&total).Error; err != nil {
		return nil, err
	}

	// 第二步:获取分页数据(LIST)
	page := query.Page
	if page == 0 {
		page = 1
	}
	pageSize := query.PageSize
	if pageSize == 0 {
		pageSize = 10
	}

	offset := (page - 1) * pageSize

	// 构建排序
	order := query.BuildOrder()

	if err := baseDB.Offset(offset).Limit(pageSize).Order(order).Find(&users).Error; err != nil {
		return nil, err
	}

	// 计算总页数
	totalPages := int((total + int64(pageSize) - 1) / int64(pageSize))

	return &PaginatedResult{
		List:       users,
		Total:      total,
		Page:       page,
		PageSize:   pageSize,
		TotalPages: totalPages,
	}, nil
}
func (u *UserQuery) BuildOrder() string {
	// 默认排序
	order := "id DESC"

	// 如果传了排序字段,且在白名单中
	if u.SortField != nil {
		// 默认升序
		direction := "ASC"
		// 如果传了 desc,则降序
		if u.SortOrder != nil && (strings.ToLower(*u.SortOrder) == "desc") {
			direction = "DESC"
		}
		order = fmt.Sprintf("%s %s", *u.SortField, direction)
	}
	return order
}

func (u *UserQuery) BuildWhere(db *gorm.DB) *gorm.DB {
	if len(u.IDs) > 0 {
		db = db.Where("id IN ?", u.IDs)
	}
	if u.Name != nil {
		db = db.Where("name LIKE ?", "%"+*u.Name+"%")
	}
	if u.Email != nil {
		db = db.Where("email = ?", *u.Email)
	}
	if u.MinAge != nil {
		db = db.Where("age > ?", *u.MinAge)
	}
	if u.StartTime != nil {
		db = db.Where("created_at >= ?", *u.StartTime)
	}
	if u.EndTime != nil {
		db = db.Where("created_at <= ?", *u.EndTime)
	}
	return db
}

func main() {
	// MySQL 连接配置
	// 格式: "user:password@tcp(host:port)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
	dsn := "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"

	// 连接数据库
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		Logger: logger.Default.LogMode(logger.Info), // 设置日志级别为Info,显示所有SQL
	})
	if err != nil {
		log.Fatal("Failed to connect to database:", err)
	}

	// 示例查询条件
	name := "john"
	email := "john@example.com"
	minAge := uint8(18)
	startTime := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
	endTime := time.Now()
	sortField := "created_at"
	sortOrder := "desc"

	query := &UserQuery{
		IDs:       []uint{1, 2, 3},
		Name:      &name,
		Email:     &email,
		MinAge:    &minAge,
		StartTime: &startTime,
		EndTime:   &endTime,
		Page:      1,
		PageSize:  10,
		SortField: &sortField,
		SortOrder: &sortOrder,
	}

	result, err := PaginateUsers(db, query)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Total: %d\n", result.Total)
	fmt.Printf("Total Pages: %d\n", result.TotalPages)
	fmt.Printf("Current Page: %d\n", result.Page)
	fmt.Printf("Data: %+v\n", result.List)
}

update 更新数据

有很多方法,Save、Update、UpdateColumn、Updates 不同的方法有不同的区别,如下:

  1. Save,有主键记录就是更新非零值,否则就是创建
  2. Update,可以更新零值,必须要有条件
  3. UpdateColumn,可以更新零值,不会走更新的Hook
  4. Updates,如果是结构体,则更新非零值,map可以更新零值

非空更新

go
package main

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

// User 模型对应users表
type User struct {
	ID        uint      `gorm:"primaryKey;column:id"`
	Name      string    `gorm:"column:name"`
	Email     string    `gorm:"column:email"`
	Age       uint8     `gorm:"column:age"`
	CreatedAt time.Time `gorm:"column:created_at"`
	UpdatedAt time.Time `gorm:"column:updated_at"`
}

// TableName 指定表名
func (User) TableName() string {
	return "users"
}

// UpdateUserByID 根据ID更新用户,只更新非零值字段
func UpdateUserByID(db *gorm.DB, user *User) error {
	// 使用Updates方法,GORM会自动忽略零值字段:
	result := db.Model(&User{}).Where("id = ?", user.ID).Updates(user)
	return result.Error
}

// 使用示例
func main() {
	dsn := "root:123456@tcp(localhost:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		panic("连接数据库失败: " + err.Error())
	}

	// 示例1:只更新Name字段(Age为0,不会被更新)
	user1 := &User{
		ID:   3, // 必须指定ID
		Name: "张三",
		Age:  0, // 零值,不会被更新
	}
	err = UpdateUserByID(db, user1)
	if err != nil {
		panic("更新失败: " + err.Error())
	}
}

空值更新

第一种写法

注意:这种写法必须要有where条件!!!

go
db.Model(&User{}).Where("id = ?", user.ID).Update("age", nil)

如果真的想批量全表更新,那就用1=1这样的写法

db.Model(&User{}).Where("1=?", 1).Update("age", 12)

第二种写法

注意:这种写法必须要有where条件!!!

go
db.Model(&User{}).Where("id = ?", user.ID).Updates(map[string]interface{}{
		"email":  "xxx",
		"status": nil,
	})

事务操作

例子1

go
// 示例:事务操作 - 创建用户同时创建文章
fmt.Println("\n=== 事务操作 - 创建用户同时创建文章 ===")
err = db.Transaction(func(tx *gorm.DB) error {
    // 在事务中执行一些数据库操作
    newUserWithArticle := User{
        Name:  "钱七",
        Email: "qianqi@example.com",
        Age:   32,
    }
    if err := tx.Create(&newUserWithArticle).Error; err != nil {
        // 返回任何错误都会回滚事务
        return err
    }

    newArticle := Article{
        Title:   "事务操作示例",
        Content: "这是一个演示事务操作的示例文章...",
        UserID:  newUserWithArticle.ID,
    }
    if err := tx.Create(&newArticle).Error; err != nil {
        return err
    }

    // 返回 nil 提交事务
    return nil
})

if err != nil {
    log.Fatal("Transaction failed:", err)
}
fmt.Println("事务操作成功完成")

例子2

go
package main

import (
	"context"
	"database/sql"
	"log"

	_ "github.com/go-sql-driver/mysql"
)

func main() {
	// 假设 db 已经通过 sql.Open 创建并配置好
	db, err := sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/test")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	// 开启事务
	ctx := context.Background()
	tx, err := db.BeginTx(ctx, nil) // nil 表示使用数据库默认的事务选项
	if err != nil {
		log.Fatal(err)
	}

	// 使用事务执行操作
	_, err = tx.Exec("INSERT INTO users(name) VALUES(?)", "Alice")
	if err != nil {
		tx.Rollback() // 出错时回滚
		log.Fatal(err)
	}

	// 提交事务
	if err := tx.Commit(); err != nil {
		log.Fatal(err)
	}
}

删除用户

第一种写法

go
var user User
user.ID = 3
db.Model(&User{}).Delete(&user)

第二种写法

go
db.Model(&User{}).Delete(&User{}, 4)

第三种写法

go
db.Where("age > ?", 18).Delete(&User{})

自定义映射对象

下面的写法就是通过传统的orm来映射自定义的对象。准确的来说还不属于原生SQL映射

go
package main

import (
	"fmt"
	"log"
	"time"

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

// 定义用户模型
type User struct {
	ID        uint      `gorm:"primaryKey"`           // 主键
	Name      string    `gorm:"size:100;not null"`    // 用户名,长度限制100,非空
	Email     string    `gorm:"size:100;uniqueIndex"` // 邮箱,长度限制100,唯一索引
	Age       uint8     `gorm:"check:age > 0"`        // 年龄,检查约束
	CreatedAt time.Time // 创建时间
	UpdatedAt time.Time // 更新时间
}
type UserDTO struct {
	ID   uint
	Name string
}

func main() {
	// MySQL 连接配置
	// 格式: "user:password@tcp(host:port)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
	dsn := "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"

	// 连接数据库
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		Logger: logger.Default.LogMode(logger.Info), // 设置日志级别为Info,显示所有SQL
	})
	if err != nil {
		log.Fatal("Failed to connect to database:", err)
	}
	var user []UserDTO
	db.Model(&User{}).Where("id > ?", 4).Scan(&user)
	fmt.Printf("user: %d\n", len(user))
	fmt.Printf("user: %+v\n", user)
}

去重&指定查询字段

go
// 示例 1: 查询单个用户信息
var userName = &[]string{}
// 使用 Raw 执行原生 SQL 查询,去重查询
result := db.Model(&User{}).Where("id > ?", 1).Select("age").Distinct("age").Scan(userName)
// 检查 RowsAffected
if result.Error != nil {
    log.Fatal("查询执行失败:", result.Error)
}

fmt.Println(*userName)

指定表名

go

原生查询

类似mybatis那种的结果映射

单对象映射

go
package main

import (
	"fmt"
	"log"
	"time"

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

// 定义用户模型
type User struct {
	ID        uint      `gorm:"primaryKey"`           // 主键
	Name      string    `gorm:"size:100;not null"`    // 用户名,长度限制100,非空
	Email     string    `gorm:"size:100;uniqueIndex"` // 邮箱,长度限制100,唯一索引
	Age       uint8     `gorm:"check:age > 0"`        // 年龄,检查约束
	CreatedAt time.Time // 创建时间
	UpdatedAt time.Time // 更新时间
}

// 定义一个结构体来映射查询结果
type UserResult struct {
	Id        uint      `gorm:"column:id"` // 使用标签指定列名
	Name      string    `gorm:"column:name"`
	Email     string    `gorm:"column:email"`
	Age       int       `gorm:"column:age"`
	CreatedAt time.Time `gorm:"column:created_at"`
}

func main() {
	// MySQL 连接配置
	// 格式: "user:password@tcp(host:port)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
	dsn := "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"

	// 连接数据库
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		Logger: logger.Default.LogMode(logger.Info), // 设置日志级别为Info,显示所有SQL
	})
	if err != nil {
		log.Fatal("Failed to connect to database:", err)
	}

	// 示例 1: 查询单个用户信息
	var user = &UserResult{}
	userId := 5
	// 使用 Raw 执行原生 SQL 查询,并通过 Scan 将结果映射到结构体
	result := db.Raw("SELECT id, name, email, age, created_at FROM users WHERE id = ?", userId).Scan(user)
	// 检查 RowsAffected
	if result.Error != nil {
		log.Fatal("查询执行失败:", result.Error)
	}

	if result.RowsAffected == 0 {
		fmt.Printf("未找到ID为 %d 的用户\n", userId)
	} else {
		fmt.Printf("用户信息: %+v\n", user)
	}
}

多对象映射

go
// 示例: 查询多个用户信息
var users []UserResult
userId := 2
// 使用 Raw 执行原生 SQL 查询,并通过 Scan 将结果映射到结构体
result := db.Raw("SELECT id, name, email, age, created_at FROM users WHERE id >= ?", userId).Scan(&users)
if result.Error != nil {
    log.Fatal("查询执行失败:", result.Error)
} else {
    for _, user := range users {
        fmt.Printf("用户信息: %+v\n", user)
    }

}

更新删除操作

go
// 示例 5: 执行更新操作并获取影响行数
newAge := 30
updateResult := db.Exec("UPDATE users SET age = ? WHERE age < ?", newAge, 25)
if updateResult.Error != nil {
    log.Fatal("Failed to execute update:", updateResult.Error)
}
rowsAffected := updateResult.RowsAffected
fmt.Printf("更新了 %d 行数据\n", rowsAffected)

如有转载或 CV 的请标注本站原文地址