前言
前两篇笔记分别介绍了 Golang 微服务 HTTP 框架 Hertz 和 Golang 微服务 RPC 框架 Kitex,本文将要介绍面向ORM(持久层)框架 GORM。
官方文档
GORM 是面向 Golang 语言的一种 ORM(持久层)框架,支持多种数据库的接入,例如 MySQL,PostgreSQL,SQLite,SQL Server,Clickhouse。此框架的特点,弱化了开发者对于 SQL 语言的掌握程度,使用提供的 API 进行底层数据库的访问。
GORM 官方支持的数据库类型有: MySQL, PostgreSQL, SQlite, SQL Server。
作者是中国人,中文文档齐全,对开发者友好,支持主流数据库。
特点:
- 全功能ORM;
- 关联(包含一个,包含多个,属于,多对多,多种包含);
- Callbacks(创建/保存/更新/删除/查找之前/之后);
- 预加载;
- 事务
- 复合主键
- SQL Builder
- 自动迁移
- 日志
- 可扩展,编写基于GORM回调的插件
- 每个功能都有测试
- 开发人员友好
快速启动
安装与连接:
go get github.com/jinzhu/gorm
连接 MySQL 数据库:
package main
import("fmt""gorm.io/driver/mysql""gorm.io/gorm""time")funcmain(){// 参考 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{})
db, err := gorm.Open(mysql.New(mysql.Config{
DSN:"root:123456@tcp(192.168.168.101: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{})if err !=nil{panic("failed to connect database")}// ----------------------------数据库连接池----------------------------
sqlDB, err := db.DB()// SetMaxIdleConns 设置空闲连接池中连接的最大数量
sqlDB.SetMaxIdleConns(10)// SetMaxOpenConns 设置打开数据库连接的最大数量。
sqlDB.SetMaxOpenConns(100)// SetConnMaxLifetime 设置了连接可复用的最大时间。
sqlDB.SetConnMaxLifetime(time.Hour)
fmt.Println("success to link mysql")select{}}
注意: 想要正确的处理
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, 详情参考: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{})
表数据操作:增删改查
package main
import("fmt""gorm.io/driver/mysql""gorm.io/gorm")type User struct{
Id int
Name string
Age int
Addr string
Pic string}funcmain(){
dsn :="root:root123\@tcp(127.0.0.1:3306)/test\_gorm?charset=utf8mb4\&parseTime=True\&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), \&gorm.Config{})if err !=nil{panic(err)}// 自动迁移
db.Set("gorm:table\_options","ENGINE=InnoDB").AutoMigrate(\&User{})// 增
db.Create(&User{
Name:"张三",
Age:18,
Addr:"北京市",
Pic:"/static/img.png",})// 查var user User
db.First(&user)
fmt.Println(user)// {1 张三 18 北京市 /static/img.png}// 改
user.Name ="lisi"
db.Save(&user)
fmt.Println(user)// {1 lisi 18 北京市 /static/img.png}// 删
db.Delete(&user)}
模型定义:
模型名和表名的映射关系
规则:
- 第一个大写字母变为小写;
- 遇到其他大写字母变为小写并且在前面加下划线;
- 连着的几个大写字母,只有第一个遵循上面的两条规则,其他的大写字母转为小写,不加下划线,遇到小写,前面的第一个大写字母变小写并加下划线;
- 复数形式;
举例:
- User => users 首字母小写,复数
- UserInfo => user_infos
- DBUserInfo => db_user_infos
- DBXXXXUserInfo => dbxxxx_user_infos
结构体字段名和列名的对应规则
规则 * 列名是字段名的蛇形小写
举例
- Name --> name
- CreatedTime --> create_time 可以通过gorm标签指定列名,AnimalId int64
gorm:"column:beast_id"
gorm.Model
基本模型定义gorm.Model,包括字段 ID,CreatedAt,UpdatedAt,DeletedAt
参数说明:
- ID:主键自增长;
- CreatedAt:用于存储记录的创建时间;
- UpdatedAt:用于存储记录的修改时间;
- DeletedAt:用于存储记录的删除时间;
只需要在自己的模型中指定gorm.Model匿名字段,即可使用上面的四个字段
gorm.Model.gopackage gorm
import"time"// Model a basic GoLang struct which includes the following fields: ID, CreatedAt, UpdatedAt, DeletedAt// It may be embedded into your model or you may build your own model without it// type User struct {// gorm.Model// }type Model struct{
ID uint`gorm:"primarykey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt DeletedAt `gorm:"index"`}// 添加字段 `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`type User struct{
gorm.Model
Name string}
高级选项
结构体标签gorm的使用:
type User struct{
Name string`gorm:"<-:create"`// 允许读和创建
Name string`gorm:"<-:update"`// 允许读和更新
Name string`gorm:"<-"`// 允许读和写(创建和更新)
Name string`gorm:"<-:false"`// 允许读,禁止写
Name string`gorm:"->"`// 只读(除非有自定义配置,否则禁止写)
Name string`gorm:"->;<-:create"`// 允许读和写
Name string`gorm:"->:false;<-:create"`// 仅创建(禁止从 db 读)
Name string`gorm:"-"`// 读写操作均会忽略该字段}
创建/更新时间追踪(纳秒、毫秒、秒、Time):
GORM 约定使用 CreatedAt、UpdatedAt 追踪创建/更新时间。如果您定义了这种字段,GORM 在创建、更新时会自动填充 当前时间
要使用不同名称的字段,您可以配置 autoCreateTim、autoUpdateTim 标签
如果您想要保存 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"`// 使用时间戳秒数填充创建时间}
字段标签
声明 model 时,tag 是可选的,GORM 支持以下 tag: tag 名大小写不敏感,但建议使用 camelCase 风格,也就是驼峰
camelCase
命名风格。多个属性值之间用分号分隔(英文的;):
gorm:"size:64;not null"
案例
package main
import("gorm.io/driver/mysql""gorm.io/gorm""gorm.io/gorm/logger""log""os""time")type User struct{
UserId uint`gorm:"primaryKey"`
Name string`gorm:"column:user_name;type:varchar(60)"`
Gender uint`gorm:"index"`}funcmain(){// 日志配置
newLogger := logger.New(
log.New(os.Stdout,"\r\n", log.LstdFlags),// io writer(日志输出的目标,前缀和日志包含的内容——译者注)
logger.Config{
SlowThreshold: time.Second,// 慢 SQL 阈值
LogLevel: logger.Info,// 日志级别为info
IgnoreRecordNotFoundError:true,// 忽略ErrRecordNotFound(记录未找到)错误
Colorful:true,// 彩色打印},)
dsn :="root:123@tcp(127.0.0.1:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn),&gorm.Config{
Logger: newLogger,})if err !=nil{panic(err)// 如果数据库不存在会报错}
db.AutoMigrate(&User{})// 如果表之前存在会修改,但是只会修改之前存在的字段的属性,无法识别删除字段}
总结
本文主要介绍了 GORM 框架的相关基础知识,介绍了常用的接口函数,具体的细节还是需要仔细研究官方文档。这三个框架的学习都可以看出官方文档的重要性,同时学习框架还是要多上手练习才行。
版权归原作者 yumuing blog 所有, 如有侵权,请联系我们删除。