这是我参与「第五届青训营」伴学笔记创作活动的第15天
GORM正式支持数据库MySQL、PostgreSQL、SQlite、SQL Server
MYSQL部署:
docker pull mysql //下载镜像
//创建并运行Mysql容器
sudo docker run --name myMysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=qqqqqq -d --net=host mysql
注意:一定需要是host网络模式,否则主机访问不到虚拟机docker
GORM声明模型
GORM约定使用:
ID作为主键snake_case:表名snake_cases:列名CreatedAt:创建时间UpdatedAt:更新时间
type Model struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
建表权限控制
- grom:
->:仅可读 - grom:
->:false:不可读,不可写 - grom:
<-:可读,可写 - grom:
<-:update:可读,仅可更新
注意:
- 默认可读,不加
->是可读的 - 默认不可写,不加
<-是不可写的 - 写包含了:更新
、创建
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
}
嵌入结构体
- gorm.Model成员等于嵌入Model结构体(如上)
type User struct {
gorm.Model
Name string
}
// equals
type User struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
Name string
}
- 若需要嵌入自定义的结构体,则需要加上TAG:
gorm:"embedded" - 若还需要更改嵌入结构体的数据库中的名字,则需要加上
TAG:embeddedPrefix:
type Blog struct {
ID int
Author Author `gorm:"embedded;embeddedPrefix:author_"`
Upvotes int32
}
type Author struct {
Name string
Email string
}
// equals
type Blog struct {
ID int64
AuthorName string
AuthorEmail string
Upvotes int32
}
连接数据库
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
func main() {
// refer https://github.com/go-sql-driver/mysql#dsn-data-source-name for details
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{})
}
CRUD:插入
登录建立连接
dsn := "root:qqqqqq@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
d, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
插入数据
creatTable()
result := db.Create(&user)
fmt.Printf("user.ID:%v", user.ID)
fmt.Printf("插入记录的条数:%v", result.RowsAffected)
用指定字段创建记录
- 创建记录并更新给出的字段。
user := User{
Name: "Jinzhu",
Age: 18,
Birthday: time.Now(),
}
db.Select("Name", "Age", "CreatedAt").Create(&user)
创建一个记录且一同
忽略传递给略去的字段值。
db.Omit("Name", "Age", "CreatedAt").Create(&user)
根据 Map 创建
GORM 支持根据 map[string]interface{} 和 []map[string]interface{}{} 创建记录
db.Model(&User{}).Create(map[string]interface{}{
"Name": "hyz",
"Age": 18,
})
// batch insert from `[]map[string]interface{}{}`
db.Model(&User{}).Create([]map[string]interface{}{
{"Name": "hyz1", "Age": 18},
{"Name": "hyz_2", "Age": 20},
})
注意: 根据
map创建记录时,association 不会被调用,且主键也不会自动填充
默认值
- 插入记录到数据库时,默认值 会被用于 填充值为 零值 的字段
- 对于声明了默认值的字段,像 0、' '、false 等零值是不会保存到数据库。您需要使用指针类型或
Scanner/Valuer来避免这个问题,例如: - 若要数据库有默认、虚拟/生成的值,你必须为字段设置
default标签。若要在迁移时跳过默认值定义,你可以使用default:(-) - 使用虚拟/生成的值时,你可能需要禁用它的创建、更新权限