GORM快速入门
Gorm(Go-orm框架)
The fantastic ORM library for Golang aims to be developer friendly. (Go语言对开发者最友好的ORM框架。)
gorm
是一个使用Go
语言编写的ORM
框架。它文档齐全,对开发者友好,支持主流数据库。
特性
链接
GitHub GORM地址: https://github.com/jinzhu/gorm
GORM中文官方文档地址:https://gorm.io/zh_CN/docs/
安装
# 安装gorm模块
go get -u gorm.io/gorm
# 安装链接数据库的包
# mysql
go get -u gorm.io/driver/mysql
# postgres
go get -u gorm.io/driver/postgres
# sqlserver
go get -u gorm.io/driver/sqlserver
# sqlite 基于 GGO 的 Sqlite 驱动
go get -u gorm.io/driver/sqlite
# sqlite 纯 Go 实现的 SQLite 驱动
go get -u github.com/glebarez/sqlite
连接数据库
GORM 官方支持的数据库类型有: MySQL
, PostgreSQL
, SQlite
, SQL Server
。
MySQL
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
func main() {
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{})
}
PostgreSQL
import (
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
func main() {
dsn := "host=localhost user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai"
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
}
SQL Server
import (
"gorm.io/driver/sqlserver"
"gorm.io/gorm"
)
func main() {
dsn := "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"
db, err := gorm.Open(sqlserver.Open(dsn), &gorm.Config{})
}
SQLite
import (
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
func main() {
db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{})
}
连接池配置
在一个高效稳定的应用程序中,池化技术
是非常重要的,他能最大程度上的保证应用程序的稳定性。GORM
在数据库连接池为了让我们更加容易配置,它维护了连接的DB()
方法,其返回值是*sql.DB
的一个对象。该对象是database/sql 包我们可通过该对象的一些方法来自定义配置我们的数据库连接池,当然该对象的更多配置可参考具体官网。
// 通过调用DB()方法获取 *sql.DB对象
sqlDB, err := db.DB()
// SetMaxIdleConns 设置空闲连接池中连接的最大数量
sqlDB.SetMaxIdleConns(10)
// SetMaxOpenConns 设置打开数据库连接的最大数量。
sqlDB.SetMaxOpenConns(100)
// SetConnMaxLifetime 设置了连接可复用的最大时间。
sqlDB.SetConnMaxLifetime(time.Hour)
当然
GORM
实现了许多的数据库连接,并不是所有连接都使用了database/sql ,所有使用该方法当底层不是*sql.DB
对象时会抛出错误。
模型(Model)定义
任何ORM
框架中,Model
(ORM=>M)模型是必须存在的,在不同的语言中表示不同,在Java
中,我们常常用类Class
来表示一个模型。在Go
中模型的标准则是sturct
来表示。
示例:
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.Model的结构体,它为我们提供了ID
、CreatedAt
、UpdatedAt
、DeletedAt
。这个四个字段来满足我们常用的开发结构体。
// gorm 定义的结构体
type Model struct {
ID uint `gorm:"primarykey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt DeletedAt `gorm:"index"`
}
如果需要使用其内置结构体,我们自需要更具Go
结构体的语法糖嵌入到自己的模型中即可正常使用。
// 嵌入内置结构体
type User struct {
gorm.Model
Name string
Email *string
}
// 嵌入gorm.Model后,该模型就有了以下七个属性
// ID CreatedAt UpdatedAt UpdatedAt DeletedAt Name Email
模型标记(tags)
tags
是一种标记,其目的是为了让结构体能更好的模拟我们的数据库字段的属性。例如,在内置结构体中ID uint gorm:"primarykey"
属性,其中gorm:"primarykey"
就是对该字段的约束,表示该字段是表的主键
。
在GORM
中支持的模型tags
如下:
结构体标记(Tag) | 描述 |
---|---|
column |
映射的列名 |
type |
列数据类型 |
size |
列的大小或长度 |
primaryKey |
将列定义为主键 |
unique |
将列定义为唯一键 |
default |
定义列的默认值 |
precision |
指定列的精度 |
scale |
指定列大小 |
not null |
指定列为 NOT NULL |
default |
列默认值 |
comment |
列的注释 |
- |
忽略字段加入数据库 |
autoUpdateTime |
创建更新时更新时间 |
autoCreateTime |
创建时插入时间 |
<- |
设置字段写入权限<-false 无写入权限,<-:create 新增写入权限,<-:update 更新权限 |
-> |
设置字段读权限->:false 不可读 |
check |
约束索引,check:age>13 、check:name<>"小鸟" |
index |
创建索引 |
uniqueIndex |
唯一性索引 |
autoIncrement |
列自增 |
autoIncrementIncrement |
自增步长 |
注意:tag 是可选的,GORM 支持以下 tag:
tag 名不区分大小写
,但建议使用驼峰命名。
当然,除了上面的标记tags
之外,GORM还提供了关联关系的tags
,在实际的开发中为了能提高数据库的运行效率,一般不推荐通过关联外键的形势来创建库表,所以下面的关联tags
了解即可。
GORM约定
在GORM
中,为了能使开发者更加的关注业务开发,其使用了约定大于配置的设计思想。这些约定主要体现于表名
、主键
、列名
、原始的gorm.Model字段
表名
:表名默认就是结构体名称的复数
type User struct {} // 默认表名是 `users`
// 将 User 的表名设置为 `profiles`
func (User) TableName() string {
return "profiles"
}
// 禁用默认表名的复数形式,如果置为 true,则 `User` 的默认表名是 `user`
db.SingularTable(true)
// 也可以通过Table()方法指定表名
// 使用User结构体创建名为`deleted_users`的表
db.Table("deleted_users").CreateTable(&User{})
// 自定义默认表名规则(在表名前加上表前缀)
gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName string) string {
return "prefix_" + defaultTableName;
}
列名
:列名默认为驼峰命名转下划线
// 默认映射数据库列名
type User struct {
ID uint // column name is `id`
Name string // column name is `name`
Birthday time.Time // column name is `birthday`
CreatedAt time.Time // column name is `created_at`
}
// 可以使用结构体tag指定列名
type Animal struct {
AnimalId int64 `gorm:"column:beast_id"` // set column name to `beast_id`
}
主键
:默认使用ID来做主键
type User struct {
ID string // 名为`ID`的字段会默认作为表的主键
Name string
}
// 可以使用结构体tag指定主键
type Animal struct {
AnimalID int64 `gorm:"primary_key"`
Name string
Age int64
}
原始的gorm.Model字段
:CreatedAt、UpdatedAt、 DeletedAt
// CreatedAt
// 如果模型有 CreatedAt字段,该字段的值将会是初次创建记录的时间。
db.Create(&user) // `CreatedAt`将会是当前时间
// 可以使用`Update`方法来改变`CreateAt`的值
db.Model(&user).Update("CreatedAt", time.Now())
// UpdatedAt
// 如果模型有UpdatedAt字段,该字段的值将会是每次更新记录的时间。
db.Save(&user) // `UpdatedAt`将会是当前时间
db.Model(&user).Update("name", "jinzhu") // `UpdatedAt`将会是当前时间
// DeletedAt
// 如果模型有DeletedAt字段,调用Delete删除该记录时,将会设置DeletedAt字段为当前时间,而不是直接将记录从数据库中删除。