什么是 ORM
ORM(Object-Relational Mapping)是一种程序设计技术,用于将数据库中的数据映射到程序中的对象。这样,开发者可以使用面向对象的方式来操作数据库,而不需要编写复杂的 SQL 语句。
GORM 是 Go 语言的一个 ORM(对象关系映射)库,它提供了强大的功能和简洁的 API。支持连接MySQL, PostgreSQL, SQLite, SQL Server 和 TiDB数据库。下面以连接MySQL数据库为例,展示操作过程。
GORM连接MySQL数据库初试
首先,需要下载GORM库并安装对于MySQL的驱动:
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
数据库表对应结构体的定义
GORM 通过将 Go 结构体(Go structs) 映射到数据库表来简化数据库交互。因此需要先定义对应的结构体。
type Task struct {
gorm.Model
Uid uint `gorm:"not null"`
Title string `gorm:"index; not null"`
Status int `gorm:"default:0"`
Content string `gorm:"type:longtext"`
StartTime int64
EndTime int64 `gorm:"default:0"`
}
在这其中有一些约定:
- GORM提供了一个预定义的结构体,名为
gorm.Model,我们常将其嵌套入定义的结构体中其中包含常用字段:
type Model struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
- GORM 使用一个名为
ID的字段作为每个模型的默认主键。 - 默认情况下,GORM 将结构体名称转换为
snake_case并为表名加上复数形式。 例如,一个User结构体在数据库中的表名变为users。自定义表名的方法是实现模型结构体的TableName方法。例如对于上述结构体:
func (Task) TableName() string {
return "todo_tasks"
}
- GORM 自动将结构体字段名称转换为
snake_case作为数据库中的列名。 - GORM使用字段
CreatedAt和UpdatedAt来自动跟踪记录的创建和更新时间。 - 结构体中每一个字段可定义字段标签,可用于指定数据库列映射(column)、数据类型指定(type)、列大小(size)、主键(primaryKey)、唯一性约束(unique)、默认值(default)、非空约束(not null)等等作用。
连接到数据库
首先我们需要通过定义DSN指明要连接的数据库信息,DSN(Data Source Name)是一个字符串,用于指定数据库连接的所有必要信息,以便数据库驱动程序能够建立到数据库的连接。以MySQL为例,其格式如下:
username:password@protocol(address)/dbname?param1=value1¶m2=value2
实现连接:
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{})
在这其中,db 来实现。是一个 *gorm.DB 类型的变量,它代表了一个 GORM 数据库连接实例。之后的各种操作需要这个db 来实现。
自动迁移:
db.AutoMigrate(&Product{})
AutoMigrate 是 GORM 中的一个方法调用,它用于自动迁移数据库表结构。这意味着 GORM 会根据 Product 结构体的定义自动创建相应的数据库表,或者如果表已经存在,它会检查结构体定义与现有数据库表结构是否一致,并自动修改表结构以匹配结构体。
CRUD操作
以一个小的结构体为例:
type Product struct {
gorm.Model
Code string
Price uint
}
func main() {
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
// 自动迁移表结构
db.AutoMigrate(&Product{})
}
1. 创建(Create)
在 GORM 中,创建记录可以通过 Create 方法实现。以下是一个创建记录的例子:
// 创建记录
db.Create(&Product{Code: "D42", Price: 100})
在这个例子中,我们首先定义了一个 Product 结构体,然后使用 db.Create 方法创建了一条新记录。
2. 读取(Read)
读取记录可以通过 First、Take、Last 和 Find 方法实现。以下是一些读取记录的例子:
go
var product Product
// 根据主键查找
db.First(&product, 1)
// 查找第一条记录
db.Take(&product)
// 查找最后一条记录
db.Last(&product)
// 查找多条记录
var products []Product
db.Find(&products)
First 方法会根据主键升序查找第一条记录,Take 方法会获取一条记录而不关心排序,Last 方法会根据主键降序查找最后一条记录,而 Find 方法可以获取多条记录。
3. 更新(Update)
更新记录可以通过 Update 和 Updates 方法实现。以下是一些更新记录的例子:
go
var product Product
db.First(&product, 1) // 先查询到记录
// 更新单个字段
db.Model(&product).Update("Price", 200)
// 更新多个字段
db.Model(&product).Updates(Product{Price: 200, Code: "F42"})
Update 方法用于更新单个字段,而 Updates 方法可以同时更新多个字段。这些方法都需要先查询到要更新的记录。
4. 删除(Delete)
删除记录可以通过 Delete 方法实现。以下是删除记录的例子:
go
var product Product
db.First(&product, 1) // 先查询到记录
// 删除记录
db.Delete(&product, 1)
Delete 方法会删除指定的记录。如果需要物理删除,可以使用 Unscoped 方法来绕过软删除。
链式调用法则
GORM 实现了链式操作接口,允许你将多个方法调用链接在一起,直到遇到一个立即执行方法。在调用立即执行方法前,不会生成 Query 语句,这样你可以灵活地组合查询条件。
立即执行方法是指那些会立即生成 SQL 语句并发送到数据库的方法,如 Create, First, Find, Take, Save, Update, Delete, Scan, Row, Rows 等。这些方法会结束链式操作,并执行之前链式调用中累积的所有数据库操作