xorm - 课时 1:常见用法指导
注意事项
本博客隶属于 xorm - 课时 1:常见用法指导 请注意配套使用。
本博文为 xorm - Go 语言 ORM 的配套博客,旨在通过文字结合代码示例对该库的使用方法和案例进行讲解,便于各位同学更好地使用和深入了解。
库简介
xorm 是一款针对 Go 语言的 ORM 第三方库,特点是提供简单但丰富实用的 API 来完成对数据库的各类操作。该库支持包括 MySQL、PostgreSQL、SQLite3 和 MsSQL 在内的主流数据库,其在支持链式操作的基础上,还允许结合 SQL 语句进行混合处理。另外,支持 session 事务和回滚以及乐观锁也是使得该库逐渐流行的原因之一。
下载安装
您可以通过以下两种方式下载安装 xorm:
gopm get github.com/go-xorm/xorm
或
go get github.com/go-xorm/xorm
API 文档
请移步 Go Walker。
基本使用方法
定义模型
在使用 Go 语言的 ORM 之前,都需要对模型进行定义。对于 Go 语言而言,通过定义一个结构体(struct)和该结构体的字段的类型与 tag 来完成对模型的定义。例如,在本课时的例子中,我们就通过以下代码来定义一个银行账户的模型:
type Account struct {
Id int64
Name string `xorm:"unique"`
Balance float64
Version int `xorm:"version"` // 乐观锁
}
由于关系型数据库涉及到主键问题,为了方便用户的使用,凡是类型为 int64
且字段名为 Id
且没有定义任何 tag 的字段,都会自动被认为是主键。如果您想要采用其它名称为主键,则可以在 tag 中设置 pk
来告知 xorm。
字段 Name
的 tag 使用了 unique
则表示该字段记录的值在整个数据表中是唯一的,不能够出现重复的用户名。
最后一行的乐观锁暂不深入,后文会讲到。
在定义模型时需要注意的是所有字段的首字母必须是大写的(Go 语言的导出规则),否则 ORM 是无法通过反射获取到字段的名称和类型,可能会引发 panic。
由于例子比较简单,并不能够列举出所有 xorm 支持的 tag 定义,完整的列表可以查看 这里。
创建 ORM 引擎
在完成模型定义之后,我们就需要创建 ORM 的引擎了。在创建 ORM 引擎这个步骤时,您需要确定您所使用的数据库驱动以及相关的链接信息(数据库 HOST、用户、密码等)。本例采用的是 SQLite3,所以只需要指定数据库文件所在的路径就可以了:
x, err = xorm.NewEngine("sqlite3", "./bank.db")
Go 语言要求所使用的数据库驱动必须注册之后才能使用,因此所有的驱动库都会在 init 函数中对自身进行注册,以便我们在使用时候不会出现错误。同样地,使用 ORM 也是需要对我们所使用的数据库驱动进行注册,那么如何注册呢?
由于数据库驱动的种类较多,一般每个 ORM 都只会对一种数据库选择一个驱动进行支持,所以在注册驱动之前,需要确认一下您所使用的 ORM 是否支持您所选的驱动。比如 xorm 就支持多达 5 种数据库驱动。
注册数据库驱动的方法如下:
import (
_ "github.com/mattn/go-sqlite3"
)
很多同学看到导入路径前面的 _
下划线表示不解,这是没有学习好无闻出品的 《Go编程基础》 的恶果。在导入路径前加入下划线表示只执行该库的 init 函数而不对其它导出对象进行真正地导入。因为 Go 语言的数据库驱动都会在 init 函数中注册自己,所以我们只需要进行上述操作即可;否则的话,Go 语言的编译器会提示导入了包却没有使用的错误。
自动同步表结构
xorm 有一个非常赞的功能,就是支持自动增量同步数据表结构。什么意思呢?就是在您完成数据库的创建之后,ORM 会自动根据所定义的模型来自动创建数据表,这就是为什么我们需要使用 tag 来对字段进行一些特别的指定(例如:unique)。所谓增量同步,就是指只会对新增的字段或 tag 定义进行同步,包括新定义的模型、字段和 tag 规则;如果您删除或修改了某个字段,出于安全考虑,已经创建的列(column)是不会被删除或修改的,而是直接忽略或新建修改后的列。
通过下面的方法,就能够调用 xorm 提供的自动同步数据表结构的功能:
err = x.Sync(new(Account))
方法 Sync
需要传入所有您将会用到的模型,本例中只有 Account
。之所以使用 new()
方法进行一次创建对象是因为 ORM 的解析结构体的工作都是通过反射完成的,只有传递一个实例对象才能够让 ORM 获取到相应的字段和 tag。
增、删、改操作
首先,我们来看看如何使用 xorm 实现最基本的增、删、改操作。
新增记录
插入一条新的记录,该记录必须是未存在的,否则会返回错误:
_, err := x.Insert(&Account{Name: name, Balance: balance})
删除记录
删除一条记录:
_, err := x.Delete(&Account{Id: id})
方法 Delete
接受参数后,会自动根据传进去的值进行查找,然后删除。比如此处,我们指定了 Account
的 ID 字段,那么就会删除 ID 字段值与我们所赋值相同的记录;如果您只对 Name 字段赋值,那么 xorm 就会去查找 Name 字段值匹配的记录。如果多个字段同时赋值,则是多个条件同时满足的记录才会被删除。
删除操作针对的对象没有限制,凡是按照条件查找到的,都会被删除(单个与批量删除)。
获取与修改记录
根据 xorm 的要求,想要更新一条记录则该记录必须是已存在的,所以我们需要先获取记录的相应信息,然后做修改,最后进行更新:
a := &Account{}
has, err := x.Id(id).Get(a)
方法 Get
只会返回单个记录,与删除操作类似的,任何对于变量 a 的赋值就会变成查找条件。但 xorm 的灵活之处在于,您还可以通过链式操作方便的达到同样的需求。正如本例中直接使用 Id
方法来获取指定 ID 的记录一样。
该方法会返回两个值,第一个为 bool 类型,表示是否查找到记录;第二个为 error 类型,表示是否发生其它错误。
在获取到记录之后,我们就需要进行一些修改,然后更新到数据库:
a.Balance += deposit
// 对已有记录进行更新
_, err = x.Update(a)
方法 Update
接受的第一个参数必须是指针地址,指向需要更新的内容。此外,它还允许接收第二个参数,与之前在删除和获取操作中提到的条件查询作用相同,如果您传入了第二个参数,则会根据参数进行条件筛选,然后更新相应的字段。
批量获取信息
除了对单个记录进行获取之外,为了能够更好的查看内容,有时我们会需要一次性取出多条记录,并进行一定的排序。
因此,与获取单个记录的 Get
方法相对应的是获取所有符合条件的记录的 Find
方法:
err = x.Desc("balance").Find(&as)
在这里,我们还调用了 Desc
方法对记录按照存款数额将账户从大到小排序。
方法 Find
接受的第一个参数必须是某个类型的 slice 的指针地址,本例中使用的是元素类型为 Account
类型的 slice 的指针地址;它的第二个参数也是条件参数,作用前文已经详细描述。
乐观锁
乐观锁是 xorm 提供的一个比较实用的功能,通过在 tag 中指定 version
来开启它。开启之后,每次对记录进行更新的时候,该字段的值就会自动递增 1。如此一来,您就可以判断是否有其它地方同时修改了该记录,如果是,则应当重新操作,否则会出现错误的数据(同时对一个帐号进行取款操作却只扣了一次的数额)。
小结
本课时只是针对 xorm 的讲解的第一课时,在代码实现上追求基础、直观,并未涉及到非常多的内容,以免让新手显得迷茫。所以,本例中的代码实际上是存在一些缺陷的,比如说在转账就应该使用事务以便发生错误时进行回滚,以免转账失败时转账双方都没有回归到原有的数额。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。