前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Gorm框架学习--入门

Gorm框架学习--入门

作者头像
大忽悠爱学习
发布2022-09-23 15:52:32
1.9K0
发布2022-09-23 15:52:32
举报
文章被收录于专栏:c++与qt学习c++与qt学习

Gorm框架学习--入门


引言

前面,已经介绍了go标准库sqlx库操作mysql的教程,下面介绍专业的ORM框架Gorm来操作各类数据库。

本文内容摘抄自Gorm 2022-8月份官方文档教程,如果Gorm框架后续有更新,还是以最新版本的官方文档为准

  • 安装
代码语言:javascript
复制
go get -u gorm.io/gorm

根据操作的底层数据库不同,引入相关数据库驱动:

代码语言:javascript
复制
#操作mysql需要下载下面的依赖
go get -u gorm.io/driver/mysql
#操作sqllite需要下载下面的依赖
go get -u gorm.io/driver/sqlite
#其他版本数据库依赖可以自行查找
...

本文所有演示,均基于mysql,其余关系型数据库操作大同小异


快速入门

代码语言:javascript
复制
package main

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

var MYSQL_ADDR ="user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"

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

//gorm.Model结构如下: 主要是提供一些通用字段
//type Model struct {
//	ID        uint `gorm:"primarykey"`
//	CreatedAt time.Time
//	UpdatedAt time.Time
//	DeletedAt DeletedAt `gorm:"index"`
//}

func main() {
	//创建数据库连接
	db, err := gorm.Open(mysql.Open(MYSQL_ADDR), &gorm.Config{})
	if err != nil {
		panic("failed to connect database")
	}

	//根据实体对象创建对应的表结构
	db.AutoMigrate(&Product{})

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

	//查询数据
	var product Product
	db.First(&product, 1)                 // 根据整型主键查找
	db.First(&product, "code = ?", "D42") // 查找 code 字段值为 D42 的记录

	// Update - 将 product 的 price 更新为 200
	db.Model(&product).Update("Price", 200)
	// Update - 更新多个字段
	db.Model(&product).Updates(Product{Price: 200, Code: "F42"}) // 仅更新非零值字段
	db.Model(&product).Updates(map[string]interface{}{"Price": 200, "Code": "F42"})

	// Delete - 删除 product---这里其实是隐式删除
	db.Delete(&product, 1)
}

模型定义

模型是标准的 struct,由 Go 的基本数据类型、实现了 ScannerValuer 接口的自定义类型及其指针或别名组成

例如:

代码语言:javascript
复制
type User struct {
  ID           uint
  Name         string
  Email        *string
  Age          uint8
  Birthday     *time.Time
  MemberNumber sql.NullString
  ActivatedAt  sql.NullTime
  CreatedAt    time.Time
  UpdatedAt    time.Time
}

约定

GORM 倾向于约定,而不是配置。默认情况下,GORM 使用 ID 作为主键,使用结构体名的 蛇形复数 作为表名,字段名的 蛇形 作为列名,并使用 CreatedAt、UpdatedAt 字段追踪创建、更新时间

在这里插入图片描述
在这里插入图片描述

遵循 GORM 已有的约定,可以减少您的配置和代码量。如果约定不符合您的需求,GORM 允许您自定义配置它们,这个后面再说。


gorm.Model

GORM 定义一个 gorm.Model 结构体,其包括字段 IDCreatedAtUpdatedAtDeletedAt

代码语言:javascript
复制
// gorm.Model 的定义
type Model struct {
  ID        uint           `gorm:"primaryKey"`
  CreatedAt time.Time
  UpdatedAt time.Time
  DeletedAt gorm.DeletedAt `gorm:"index"`
}

您可以将它嵌入到您的结构体中,以包含这几个字段,具体怎么嵌入,下面会说到。


高级选项

字段级权限控制

可导出的字段在使用 GORM 进行 CRUD 时拥有全部的权限,此外,GORM 允许您用标签控制字段级别的权限。这样您就可以让一个字段的权限是只读、只写、只创建、只更新或者被忽略

注意: 使用 GORM Migrator 创建表时,不会创建被忽略的字段

代码语言:javascript
复制
type User struct {
  Name string `gorm:"<-:create"` // allow read and create
  Name string `gorm:"<-:update"` // allow read and update
  Name string `gorm:"<-"`        // allow read and write (create and update)
  Name string `gorm:"<-:false"`  // allow read, disable write permission
  Name string `gorm:"->"`        // readonly (disable write permission unless it configured)
  Name string `gorm:"->;<-:create"` // allow read and create
  Name string `gorm:"->:false;<-:create"` // createonly (disabled read from db)
  Name string `gorm:"-"`            // ignore this field when write and read with struct
  Name string `gorm:"-:all"`        // ignore this field when write, read and migrate with struct
  Name string `gorm:"-:migration"`  // ignore this field when migrate with struct
}

创建/更新时间追踪(纳秒、毫秒、秒、Time)

GORM 约定使用 CreatedAtUpdatedAt 追踪创建/更新时间。如果您定义了这种字段,GORM 在创建、更新时会自动填充当前时间。

要使用不同名称的字段,您可以配置 autoCreateTimeautoUpdateTime 标签

如果您想要保存 UNIX(毫/纳)秒时间戳,而不是 time,您只需简单地将 time.Time 修改为 int 即可

代码语言:javascript
复制
type User struct {
  CreatedAt time.Time // 在创建时,如果该字段值为零值,则使用当前时间填充
  UpdatedAt int       // 在创建时该字段值为零值或者在更新时,使用当前时间戳秒数填充
  Updated   int64 `gorm:"autoUpdateTime:nano"` // 使用时间戳填纳秒数充更新时间
  Updated   int64 `gorm:"autoUpdateTime:milli"` // 使用时间戳毫秒数填充更新时间
  Created   int64 `gorm:"autoCreateTime"`      // 使用时间戳秒数填充创建时间
}

嵌入结构体

对于匿名字段,GORM 会将其字段包含在父结构体中,例如:

代码语言:javascript
复制
type User struct {
  gorm.Model
  Name string
}
// 等效于
type User struct {
  ID        uint           `gorm:"primaryKey"`
  CreatedAt time.Time
  UpdatedAt time.Time
  DeletedAt gorm.DeletedAt `gorm:"index"`
  Name string
}

对于正常的结构体字段,你也可以通过标签 embedded 将其嵌入,例如:

代码语言:javascript
复制
type Author struct {
    Name  string
    Email string
}

type Blog struct {
  ID      int
  Author  Author `gorm:"embedded"`
  Upvotes int32
}
// 等效于
type Blog struct {
  ID    int64
  Name  string
  Email string
  Upvotes  int32
}

并且,您可以使用标签 embeddedPrefix 来为 db 中的字段名添加前缀,例如:

代码语言:javascript
复制
type Blog struct {
  ID      int
  Author  Author `gorm:"embedded;embeddedPrefix:author_"`
  Upvotes int32
}
// 等效于
type Blog struct {
  ID          int64
    AuthorName  string
    AuthorEmail string
  Upvotes     int32
}

如果根据Blog结构体来创建表,那么最终的表结构如下所示:

在这里插入图片描述
在这里插入图片描述

字段标签

声明 model 时,tag 是可选的,GORM 支持以下 tag: tag 名大小写不敏感,但建议使用 camelCase 风格

golang中的tag类似java中注解的作用

标签名

说明

column

指定 db 列名

type

列数据类型,推荐使用兼容性好的通用类型,例如:所有数据库都支持 bool、int、uint、float、string、time、bytes 并且可以和其他标签一起使用,例如:not null、size, autoIncrement… 像 varbinary(8) 这样指定数据库数据类型也是支持的。在使用指定数据库数据类型时,它需要是完整的数据库数据类型,如:MEDIUMINT UNSIGNED not NULL AUTO_INCREMENT

serializer

specifies serializer for how to serialize and deserialize data into db, e.g: serializer:json/gob/unixtime

size

specifies column data size/length, e.g: size:256

primaryKey

specifies column as primary key

unique

specifies column as unique

default

specifies column default value

precision

specifies column precision

scale

specifies column scale

not null

specifies column as NOT NULL

autoIncrement

specifies column auto incrementable

autoIncrementIncrement

auto increment step, controls the interval between successive column values

embedded

embed the field

embeddedPrefix

column name prefix for embedded fields

autoCreateTime

track current time when creating, for int fields, it will track unix seconds, use value nano/milli to track unix nano/milli seconds, e.g: autoCreateTime:nano

autoUpdateTime

track current time when creating/updating, for int fields, it will track unix seconds, use value nano/milli to track unix nano/milli seconds, e.g: autoUpdateTime:milli

index

create index with options, use same name for multiple fields creates composite indexes, refer Indexes for details

uniqueIndex

same as index, but create uniqued index

check

creates check constraint, eg: check:age > 13, refer Constraints

<-

set field’s write permission, <-:create create-only field, <-:update update-only field, <-:false no write permission, <- create and update permission

->

set field’s read permission, ->:false no read permission

-

ignore this field, - no read/write permission, -:migration no migrate permission, -:all no read/write/migrate permission

comment

add comment for field when migration


关联标签

GORM 允许通过标签为关联配置外键、约束、many2many 表,详情请参考关联部分


连接到数据库

GORM 官方支持的数据库类型有: MySQL, PostgreSQL, SQlite, SQL Server

MySQL

代码语言:javascript
复制
import (
  "gorm.io/driver/mysql"
  "gorm.io/gorm"
)

func main() {
  // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
  dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
  db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
}

注意: 想要正确的处理 time.Time ,您需要带上 parseTime 参数, (更多参数) 要支持完整的 UTF-8 编码,您需要将 charset=utf8 更改为 charset=utf8mb4 查看 此文章 获取详情

MySQL 驱动程序提供了 一些高级配置 可以在初始化过程中使用,例如:

代码语言:javascript
复制
db, err := gorm.Open(mysql.New(mysql.Config{
  DSN: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8&parseTime=True&loc=Local", // DSN data source name
  DefaultStringSize: 256, // string 类型字段的默认长度
  DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
  DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
  DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
  SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置
}), &gorm.Config{})

自定义驱动

GORM 允许通过 DriverName 选项自定义 MySQL 驱动,例如:

代码语言:javascript
复制
import (
  _ "example.com/my_mysql_driver"
  "gorm.io/driver/mysql"
  "gorm.io/gorm"
)

db, err := gorm.Open(mysql.New(mysql.Config{
  DriverName: "my_mysql_driver",
  DSN: "gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True&loc=Local", // data source name, refer https://github.com/go-sql-driver/mysql#dsn-data-source-name
}), &gorm.Config{})

现有的数据库连接

GORM 允许通过一个现有的数据库连接来初始化 *gorm.DB

代码语言:javascript
复制
import (
  "database/sql"
  "gorm.io/driver/mysql"
  "gorm.io/gorm"
)

sqlDB, err := sql.Open("mysql", "mydb_dsn")
gormDB, err := gorm.Open(mysql.New(mysql.Config{
  Conn: sqlDB,
}), &gorm.Config{})

其他

SQLite,SQL Server,Clickhouse,PostgreSQL相关数据库连接操作可以参考官方文档


连接池

GORM 使用 database/sql 维护连接池

代码语言:javascript
复制
sqlDB, err := db.DB()

// SetMaxIdleConns 设置空闲连接池中连接的最大数量
sqlDB.SetMaxIdleConns(10)

// SetMaxOpenConns 设置打开数据库连接的最大数量。
sqlDB.SetMaxOpenConns(100)

// SetConnMaxLifetime 设置了连接可复用的最大时间。
sqlDB.SetConnMaxLifetime(time.Hour)

查看 通用接口 获取详情。


参考

Gorm官网

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-08-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Gorm框架学习--入门
  • 引言
  • 快速入门
  • 模型定义
    • 约定
      • gorm.Model
        • 高级选项
          • 字段级权限控制
          • 创建/更新时间追踪(纳秒、毫秒、秒、Time)
          • 嵌入结构体
          • 字段标签
          • 关联标签
      • 连接到数据库
        • MySQL
          • 自定义驱动
          • 现有的数据库连接
        • 其他
          • 连接池
          • 参考
          相关产品与服务
          云数据库 SQL Server
          腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档