Gorm 框架
安装
go get -u gorm.io/gorm
go get -u gorm.io/driver/sqlite
模型定义
type Student struct {
Id int `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` //column指定在数据库中对应的字段
Name string `gorm:"column:name" json:"name"`
Sex string `gorm:"column:sex" json:"sex"`
Age string `gorm:"column:age" json:"age"`
}
GORM 倾向于约定优于配置:
- 默认情况下,GORM 使用
ID作为主键,使用结构体名的蛇形复数作为表名,字段名的蛇形作为列名,并使用CreatedAt、UpdatedAt字段追踪创建、更新时间 - gorm提供了一个gorm.Model结构体,其包括字段
ID、CreatedAt、UpdatedAt、DeletedAt,我们可以直接把它嵌入我们的结构体 - 我们可以使用tag来控制字段,详见官方文档
- 需要注意的是,在gorm中,表名默认是结构体名的复数,列名默认是字段名的蛇形小写。比如上述结构体,gorm会认为表名是studnets,那如何解决这个问题呢?只需要在init的时候加一句
db.SingularTable(true)或者在查询时临时指定表名
连接到数据库
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 := "student:pass@tcp(127.0.0.1:3306)/school?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
}
GORM 允许通过一个现有的数据库连接来初始化 *gorm.DB,例如:
import (
"database/sql"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
var db *gorm.DB
func initDB() {
var err error
dsn := "student:pass@tcp(127.0.0.1:3306)/school?charset=utf8mb4&parseTime=True&loc=Local"
//dsn := dsn.DSN
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
log.Println(err)
}
db.SingularTable(true)
log.Println("connect success:")
}
在使用ORM工具时,通常我们需要在代码中定义模型(Models)与数据库中的数据表进行映射,在GORM中模型(Models)通常是正常定义的结构体、基本的go类型或它们的指针。 同时也支持sql.Scanner及driver.Valuer接口(interfaces)。
为了方便模型定义,GORM内置了一个gorm.Model结构体。gorm.Model是一个包含了ID, CreatedAt, UpdatedAt, DeletedAt四个字段的Golang结构体。
插入
CreatedAt
如果模型有 CreatedAt字段,该字段的值将会是初次创建记录的时间。
user := User{Name: "Jinzhu", Age: 18}
result := db.Create(&user) // 通过数据的指针来创建
//当然也支持创建多条信息(传递一个`slice`给`Create`函数),分批创建(`CreateInBatches()`)
查询
db.Model("所使用的表对应的结构体").Where("你的条件").Find("结果储存的位置的地址")
// 获取第一条记录(主键升序)
db.First(&user)
// 获取一条记录,没有指定排序字段
db.Take(&user)
// 获取最后一条记录(主键降序)
db.Last(&user)
// SELECT * FROM users ORDER BY id DESC LIMIT 1;
result := db.First(&user)
result.RowsAffected // 返回找到的记录数
result.Error // returns error or nil
// 检查 ErrRecordNotFound 错误
errors.Is(result.Error, gorm.ErrRecordNotFound)
更新
UpdatedAt
如果模型有UpdatedAt字段,该字段的值将会是每次更新记录的时间。
// save会储存所有的字段-即使字段是零值
db.Save(&user)
// 条件更新
db.Model(&User{}).Where("active = ?", true).Update("name", "hello")
// User 的 ID 是 `111`
db.Model(&user).Update("name", "hello")
// 根据条件和 model 的值进行更新
db.Model(&user).Where("active = ?", true).Update("name", "hello")
删除
DeletedAt
如果模型有DeletedAt字段,调用Delete删除该记录时,将会设置DeletedAt字段为当前时间,而不是直接将记录从数据库中删除。
// Email 的 ID 是 `10`
db.Delete(&email)
// DELETE from emails where id = 10;
// 带额外条件的删除
db.Where("name = ?", "jinzhu").Delete(&email)