使用 GORM(Go 的 ORM 库)连接数据库,并实现增删改查操作 | 青训营

63 阅读3分钟

GORM实践

简介

Gorm 是一个已迭代多年的功能强大的ORM(Object Relational Mapping)框架,对开发人员极其友好,可以很方便地与包括 MySQL 在内的多种数据库交互,省略许多重复操作。

基础操作及使用

安装

要安装 gorm 相关包,可以使用如下命令行进行安装。

go get -u gorm.io/gorm
go get -u gorm.io/driver/sqlite

连接数据库

GORM 支持 MySQLSQLServerPostgreSQL 等数据库,连接数据库的 DSN 都有所差别。下例展示了连接 MySQL 数据库的方法,需要导入对应包。

import (
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)

dsn := "username:password@tcp(localhost:9910)/database?charset=utf8"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

CRUD及高级操作

创建和插入

在创建表之前,先要有一个对应表的结构体。在每一个变量后可以附加相关信息,譬如指明其主键性质或其在数据库中的列名。 其后可以进行数据插入。在插入单条记录时,需要先创建一个结构体对应的实体,再调用 db.Create() 函数。 而在进行批量插入时,可以先创建一个对应的实体切片,同样使用 db.Create() 函数。 注意,上述函数的返回值 res 中包含异常信息,可以通过 res.Error 查看。而在插入后,对应实体数据会被赋予主键值,通过 p.ID 查看。

type Product struct {
    ID      uint    `gorm:"primarykey"`
    Code    string  `gorm:"column: code"`
    Price   uint    `gorm:"column: price"`
}

func main() {
    // ... db connection
    p := &Product{Code: "B13"}
    res := db.Create(p)

    products := []*Product{{Code: "L14"}, {Code: "T40"}, {Code: "X13"}}
    res = db.Create(products)

    fmt.Println(res.Error)
    fmt.Println(p.ID)
}

查询

在数据库中查询信息时,可以调用 db.First() 函数以获取查询到的第一条数据(按主键升序),若无查询结果则返回 ErrRecordNotFound 。 但更通用的形式是以SQL查询语句的形式获取全部查询结果,这需要链式地调用 db.Where().Find() ,而需要更复杂的查询语句时参数也会更复杂。可以通过调用 res.RowsAffected 查看查询结果行数,通过调用 res.Error 获取异常。

p := &Product{}
db.First(p)

products := make([]*Product, 0)
res := db.Where("price > 10").Find(&products)
// SELECT * FROM products where price > 10

res = db.Where("code IN ?", []string{"B13", "D20"}).Find(&products)
// SELECT * FROM products WHERE code IN ('B13','D20')
​
res = db.Where("code LIKE ?", "%D%").Find(&products)
// SELECT * FROM products WHERE code LIKE '%D%';
​
res = db.Where("code = ? AND price >= ?", "B13", "20").Find(&products)
// SELECT * FROM products WHERE code = 'B13' AND price >= 20

修改

根据条件更新对应行的列时,一般调用 db.Model().Where().Update ,从 Model() 中获取主键数据,再根据 Where() 获取条件,以更新对应数据。 若要更新多列,则需调用类似 db.Model().Updates() 的形式。若在 Updates() 前加上 Select() 函数,则只会更新选定字段。

db.Model(&Product{ID: 100}).Where("price > ?", 20).Update("code", "XX21")

db.Model(&Product{ID: 100}).Updates(Product{Code: "XX21", Price: 20})
db.Model(&Product{ID: 100}).Select("code").Updates(map[string]interface{}{"code": "XX21", "price": 20})

删除

通常的删除形式如下代码所示,一般最后可以附加上主键信息。

db.Where("code = ?", "XX21").Delete(&Product{}, []int{1,2,3,4})
// DELETE FROM products WHERE code = 'XX21' AND id IN (1,2,3,4)

事务

事务是数据库最重要的性质之一,可以保证数据处理的ACID性质。 在 GORM 中,提供了 Begin()Commit()Rollback() 等方法。一套完整的事务流程保证了数据执行的一致性和完整性,避免了数据出错的情况。

tx := db.Begin()
// operations with tx
if err = tx.Create(&Product{Code: "XT13"}).Error; err != nil {
    tx.Rollback()
    return
}
tx.Commit()