gorm框架学习--入门(代码片段)

大忽悠爱忽悠 大忽悠爱忽悠     2022-12-01     190

关键词:

Gorm框架学习--入门


引言

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

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

  • 安装
go get -u gorm.io/gorm

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

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

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


快速入门

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(&ProductCode: "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(ProductPrice: 200, Code: "F42") // 仅更新非零值字段
	db.Model(&product).Updates(map[string]interface"Price": 200, "Code": "F42")

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



模型定义

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

例如:

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

// 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 创建表时,不会创建被忽略的字段

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 即可

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


嵌入结构体

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

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 将其嵌入,例如:

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 中的字段名添加前缀,例如:

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 nullsize, autoIncrement… 像 varbinary(8) 这样指定数据库数据类型也是支持的。在使用指定数据库数据类型时,它需要是完整的数据库数据类型,如:MEDIUMINT UNSIGNED not NULL AUTO_INCREMENT
serializerspecifies serializer for how to serialize and deserialize data into db, e.g: serializer:json/gob/unixtime
sizespecifies column data size/length, e.g: size:256
primaryKeyspecifies column as primary key
uniquespecifies column as unique
defaultspecifies column default value
precisionspecifies column precision
scalespecifies column scale
not nullspecifies column as NOT NULL
autoIncrementspecifies column auto incrementable
autoIncrementIncrementauto increment step, controls the interval between successive column values
embeddedembed the field
embeddedPrefixcolumn name prefix for embedded fields
autoCreateTimetrack 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
autoUpdateTimetrack 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
indexcreate index with options, use same name for multiple fields creates composite indexes, refer Indexes for details
uniqueIndexsame as index, but create uniqued index
checkcreates 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
commentadd comment for field when migration

关联标签

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


连接到数据库

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

MySQL

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 驱动程序提供了 一些高级配置 可以在初始化过程中使用,例如:

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 驱动,例如:

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

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 维护连接池

sqlDB, err := db.DB()

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

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

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

查看 通用接口 获取详情。


参考

Gorm官网

gorm框架学习---crud接口之查询(代码片段)

Gorm框架学习---CRUD接口之查询环境搭建检索单个对象用主键检索检索全部对象条件String条件Struct&Map条件指定结构体查询字段内联条件Not条件Or条件选择特定字段OrderLimit&OffsetGroupBy&HavingDistinctJoinsJoins预加载join派生表(Derived... 查看详情

go语言学习之旅--gorm(代码片段)

Go语言学习之旅--gormgorm概述ORM简介安装gorm声明模型模型定义约定gorm.Modelgorm连接到数据库快速入门gorm的增删查改增gorm创建记录用指定的字段创建记录批量插入查检索单个对象用主键检索检索全部对象String条件Struct&Map条件更... 查看详情

初学go入门-案例-教程-记录(13)orm框架gorm简单案例-连接sqlserver,并查询数据(代码片段)

初学go入门-案例-教程-记录(13)orm框架Gorm简单案例-连接sqlserver,并查询数据初安装依赖代码:结果附表结构表结构图表结构代码初希望能写一些简单的教程和案例分享给需要的人欢迎进qq群交流:546496965怎么... 查看详情

gorm入门指南(代码片段)

gorm是一个使用Go语言编写的ORM框架。它文档齐全,对开发者友好,支持主流数据库。gorm介绍GithubGORM中文官方网站内含十分齐全的中文文档,有了它你甚至不需要再继续向下阅读本文。安装goget-ugithub.com/jinzhu/gorm连接数据库连接... 查看详情

gin框架学习-gin框架和gorm框架搭建一个简单的api微服务(代码片段)

...术,不太熟悉的可以去看看我以前的文章快速安装gin框架:https://blog.csdn.net/weixin_46618592/article/details/125540869HTTP请求:https://blog.csdn.net/weixin_46618592/article/details/125565789Gorm入门指南:https://blog.csdn.net/weixin_46618592/articl... 查看详情

golang之orm框架gorm快速开始(代码片段)

Gorm快速入门Gorm是Go语言的ORM框架,其特点有:全特性ORM(几乎包含所有特性)模型关联(一对一,一对多,一对多(反向),多对多,多态关联)钩子(Before/AfterCreate/Save/Update/Delete/Find)预加载事务复合主... 查看详情

golang之orm框架gorm快速开始(代码片段)

Gorm快速入门Gorm是Go语言的ORM框架,其特点有:全特性ORM(几乎包含所有特性)模型关联(一对一,一对多,一对多(反向),多对多,多态关联)钩子(Before/AfterCreate/Save/Update/Delete/Find)预加载事务复合主... 查看详情

012-goorm框架之gorm测试(代码片段)

1:参考:https://github.com/jinzhu/gorm2:数据库脚本(pg)--createtableposts(idserialprimarykey,contenttext,authorvarchar(100),create_timetimestamptz);createtablecomments(idserialprimarykey,contenttext,authorvarc 查看详情

go语言学习之旅--gorm(代码片段)

Go语言学习之旅--gormgorm概述ORM简介安装gorm声明模型模型定义约定gorm.Modelgorm连接到数据库快速入门gorm的增删查改增gorm创建记录用指定的字段创建记录批量插入查检索单个对象用主键检索检索全部对象String条件Struct&Map条件更... 查看详情

go语言学习之旅--gorm(代码片段)

Go语言学习之旅--gormgorm概述ORM简介安装gorm声明模型模型定义约定gorm.Modelgorm连接到数据库快速入门gorm的增删查改增gorm创建记录用指定的字段创建记录批量插入查检索单个对象用主键检索检索全部对象String条件Struct&Map条件更... 查看详情

学习笔记golang之gorm学习笔记(代码片段)

一、模型定义1.模型定义模型是标准的struct,由Go的基本数据类型、实现了Scanner和Valuer接口的自定义类型及其指针或别名组成,如:typeUserstructIDuintNamestringEmail*stringAgeuint8Birthday*time.TimeMemberNumbersql.NullStringActivedAtsql 查看详情

mybatisjava持久层框架入门与实践|学习笔记(代码片段)

Java持久层框架入门与实践|学习笔记导读本篇文章将带领读者学习MyBatis框架。开始文章简述MyBatis。之后将手把手的搭建一个简单的MyBatis框架的测试,先跑起来。随后将基于该测试讲解MyBatis框架中重要的几个配置文件。然后... 查看详情

深度学习框架tensorflow快速入门(代码片段)

...装3张量及其操作4tf.keras介绍5总结1TensorFlow介绍深度学习框架TensorFlow一经发布,就受到了广泛的关注,并在计算机视觉、音频处理、推荐系统和自然语言处理等场景下都被大面积推广使用,接下来我们深入浅出的介绍T... 查看详情

web框架-gojs入门学习(代码片段)

gojs是一个可以用于快速构建交互式图表的Web框架引入cdn<scriptsrc="https://unpkg.com/gojs/release/go-debug.js"></script>基本使用创建一个容器<!--图形的容器div需要明确指定大小,否则无法显示,本例子中我们还给... 查看详情

从java到go搭建go的orm框架gorm(代码片段)

【提问】如何使用Goland软件,搭建一个ORM框架GORM?【解答】具体步骤如下:1、检查Go的安装在任意目录执行如下命令:goversion若有如下返回,则安装成功;如果报异常,则重新安装golanggoversiongo1.19.1darw... 查看详情

shiro安全框架学习01-入门(代码片段)

ApacheShiro是一个开源安全框架,可用于身份验证、授权、加密和会话管理。身份验证和授权在对系统进行安全保障时,有两个安全性元素非常重要:身份验证和授权。身份验证指的时验证用户的身份。在验证用户身份... 查看详情

从java到go搭建go的orm框架gorm(代码片段)

【提问】如何使用Goland软件,搭建一个ORM框架GORM?【解答】具体步骤如下:1、检查Go的安装在任意目录执行如下命令:goversion若有如下返回,则安装成功;如果报异常,则重新安装golanggoversiongo1.19.1darw... 查看详情

grpc学习入门(代码片段)

grpc框架参考资料:官方文档教学grpc-go入门https://www.cnblogs.com/hongjijun/p/13724738.htmlGRPC是Google公司基于Protobuf开发的跨语言的、高性能的、通用的开源RPC框架。GRPC基于HTTP/2协议设计,可以基于一个HTTP/2链接提供多个服务,... 查看详情