golang常用库之-操作数据库ORM:GORM 包介绍 | 一些 GORM 提示和注意事项

文章目录

  • [golang操作数据库ORM:GORM 包介绍及实战](#golang操作数据库ORM:GORM 包介绍及实战)
  • 参考

golang操作数据库ORM:GORM 包介绍及实战

一、什么是GORM 包

官网:https://gorm.io/

github:https://github.com/go-gorm/gorm

官方文档:https://gorm.io/zh_CN/docs/index.html

GORM 是 Go 语言的 ORM 包,功能强大,调用方便。像腾讯、华为、阿里这样的大厂,都在使用 GORM 来构建企业级的应用。

  • 全功能 ORM
  • 关联 (拥有一个,拥有多个,属于,多对多,多态,单表继承)
  • Create,Save,Update,Delete,Find 中钩子方法
  • 支持 Preload、Joins 的预加载
  • 事务,嵌套事务,Save Point,Rollback To to Saved Point
  • Context、预编译模式、DryRun 模式
  • 批量插入,FindInBatches,Find/Create with Map,使用 SQL 表达式、Context Valuer 进行 CRUD
  • SQL 构建器,Upsert,锁,Optimizer/Index/Comment Hint,命名参数,子查询
  • 复合主键,索引,约束
  • 自动迁移
  • 自定义 Logger
  • 灵活的可扩展插件 API:Database Resolver(多数据库,读写分离)、Prometheus...
  • 每个特性都经过了测试的重重考验
  • 开发者友好

二、GORM基本使用

官方快速开始demo

官方文档:https://gorm.io/docs/

go 复制代码
package main

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

type Product struct {
  gorm.Model
  Code  string
  Price uint
}

func main() {
  db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
  if err != nil {
    panic("failed to connect database")
  }

  // Migrate the schema
  db.AutoMigrate(&Product{})

  // Create
  db.Create(&Product{Code: "D42", Price: 100})

  // Read
  var product Product
  db.First(&product, 1) // find product with integer primary key
  db.First(&product, "code = ?", "D42") // find product with code D42

  // Update - update product's price to 200
  db.Model(&product).Update("Price", 200)
  // Update - update multiple fields
  db.Model(&product).Updates(Product{Price: 200, Code: "F42"}) // non-zero fields
  db.Model(&product).Updates(map[string]interface{}{"Price": 200, "Code": "F42"})

  // Delete - delete product
  db.Delete(&product, 1)
}

db.AutoMigrate 意思 表不存在,会帮你创建表~

在 GORM 中,db.AutoMigrate(&Product{}) 函数只会在表不存在时执行数据库的自动迁移操作。如果指定的表已经存在于数据库中,并且与模型定义匹配,AutoMigrate 函数将不会对表结构进行任何更改。

  • 连接和关闭数据库。连接数据库时,可能需要设置一些参数,比如最大连接数、最大空闲连接数、最大连接时长等。
  • 插入表记录。可以插入一条记录,也可以批量插入记录。
  • 更新表记录。可以更新某一个字段,也可以更新多个字段。
  • 查看表记录。可以查看某一条记录,也可以查看符合条件的记录列表。
  • 删除表记录。可以删除某一个记录,也可以批量删除。删除还支持永久删除和软删除。

使用思路:

0) 创建一个GORM数据库连接

GORM中,你可以使用gorm.Open()方法来打开数据库连接。根据你的数据库类型和连接配置,选择合适的数据库驱动。

go 复制代码
db, err := gorm.Open("sqlite3", dbPath)
if err != nil {
    ylog.Errorf("uploadFile", "open db failed, err:%v", err)
    return
}
defer db.Close()

1) 定义与数据库表对应的模型结构体

首先定义了一个 GORM 模型(Models),Models 是标准的 Go struct,用来代表数据库中的一个表结构。我们可以给 Models 添加 TableName 方法,来告诉 GORM 该 Models 映射到数据库中的哪张表。

Models 定义如下:

go 复制代码
type Product struct {
	gorm.Model
	Code  string `gorm:"column:code"`
	Price uint   `gorm:"column:price"`
}

// TableName maps to mysql table name.
func (p *Product) TableName() string {
	return "product"
}

如果没有指定表名,则 GORM 使用结构体名的蛇形复数作为表名。例如:结构体名为 DockerInstance ,则表名为 dockerInstances 。

  1. 解析命令行参数,建立数据库链接
    在之后的代码中,使用 Pflag 来解析命令行的参数,通过命令行参数指定数据库的地址、用户名、密码和数据库名。之后,使用这些参数生成建立 MySQL 连接需要的配置文件,并调用 gorm.Open 建立数据库连接:

完整测试验证代码:

go 复制代码
package main

import (
	"fmt"
	"log"

	"github.com/spf13/pflag"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

type Product struct {
	gorm.Model
	Code  string `gorm:"column:code"`
	Price uint   `gorm:"column:price"`
}

// TableName maps to mysql table name.
func (p *Product) TableName() string {
	return "product"
}

var (
	host     = pflag.StringP("host", "H", "127.0.0.1:3306", "MySQL service host address")
	username = pflag.StringP("username", "u", "root", "Username for access to mysql service")
	password = pflag.StringP("password", "p", "root", "Password for access to mysql, should be used pair with password")
	database = pflag.StringP("database", "d", "test", "Database name to use")
	help     = pflag.BoolP("help", "h", false, "Print this help message")
)

func main() {
	// Parse command line flags
	pflag.CommandLine.SortFlags = false
	pflag.Usage = func() {
		pflag.PrintDefaults()
	}
	pflag.Parse()
	if *help {
		pflag.Usage()
		return
	}

	dns := fmt.Sprintf(`%s:%s@tcp(%s)/%s?charset=utf8&parseTime=%t&loc=%s`,
		*username,
		*password,
		*host,
		*database,
		true,
		"Local")
	db, err := gorm.Open(mysql.Open(dns), &gorm.Config{})
	if err != nil {
		panic("failed to connect database")
	}

	// 不建议在正式的代码中自动迁移表结构,生产环境注意注掉本行
	// 1. Auto migration for given models
	db.AutoMigrate(&Product{})

	// 2. Insert the value into database
	if err := db.Create(&Product{Code: "D42", Price: 100}).Error; err != nil {
		log.Fatalf("Create error: %v", err)
	}
	PrintProducts(db)

	// 3. Find first record that match given conditions
	product := &Product{}
	if err := db.Where("code= ?", "D42").First(&product).Error; err != nil {
		log.Fatalf("Get product error: %v", err)
	}

	// 4. Update value in database, if the value doesn't have primary key, will insert it
	product.Price = 200
	if err := db.Save(product).Error; err != nil {
		log.Fatalf("Update product error: %v", err)
	}
	PrintProducts(db)

	// 5. Delete value match given conditions
	if err := db.Where("code = ?", "D42").Delete(&Product{}).Error; err != nil {
		log.Fatalf("Delete product error: %v", err)
	}
	PrintProducts(db)
}

// List products
func PrintProducts(db *gorm.DB) {
	products := make([]*Product, 0)
	var count int64
	d := db.Where("code like ?", "%D%").Offset(0).Limit(2).Order("id desc").Find(&products).Offset(-1).Limit(-1).Count(&count)
	if d.Error != nil {
		log.Fatalf("List products error: %v", d.Error)
	}

	log.Printf("totalcount: %d", count)
	for _, product := range products {
		log.Printf("\tcode: %s, price: %d\n", product.Code, product.Price)
	}
}

一些 GORM 提示和注意事项

一些 GORM 提示和注意事项

参考URL: https://dev.to/daniel1in/some-gorm-tips-and-notes-3lm2

参考

官方文档:https://gorm.io/zh_CN/docs/index.html

30 | ORM:CURD 神器 GORM 包介绍及实战

https://time.geekbang.org/column/article/403351

相关推荐
时见先生8 小时前
Python库和conda搭建虚拟环境
开发语言·人工智能·python·自然语言处理·conda
a努力。8 小时前
国家电网Java面试被问:混沌工程在分布式系统中的应用
java·开发语言·数据库·git·mysql·面试·职场和发展
Yvonne爱编码8 小时前
Java 四大内部类全解析:从设计本质到实战应用
java·开发语言·python
wqwqweee8 小时前
Flutter for OpenHarmony 看书管理记录App实战:搜索功能实现
开发语言·javascript·python·flutter·harmonyos
li_wen018 小时前
文件系统(八):Linux JFFS2文件系统工作原理、优势与局限
大数据·linux·数据库·文件系统·jffs2
yongui478349 小时前
基于MATLAB的NALM锁模光纤激光器仿真实现
开发语言·matlab
wWYy.9 小时前
详解redis(16):缓存击穿
数据库·redis·缓存
JosieBook9 小时前
【数据库】Oracle迁移至KingbaseES:挑战、策略与最佳实践
数据库·oracle
-To be number.wan9 小时前
Python数据分析:numpy数值计算基础
开发语言·python·数据分析
一休哥助手10 小时前
时序数据库选型指南:从核心考量到四大主流数据库深度解析
数据库·时序数据库