golang数据库相关的几个package的关系

挑orm的过程中不知不觉被搞晕了,怎么那么多相关的package,下面我们来理一理这些package的关系

database/sql

database/sql是go的一个标准库,提供了一些sql数据库的通用接口。它需要和数据库驱动一起使用,这里是一个数据库驱动的列表。

对于mysql而言,我们最常用的是https://github.com/go-sql-driver/mysql/

driver数据库驱动

数据库驱动具体是什么呢?

每一个数据库都有一套客户端-服务端的通信协议。作为客户端,如果要从数据库中查询/插入数据,就要遵循这套协议,按照协议格式发送请求。显然,让每个用户实现协议非常浪费而不切实际。所以数据库作者提供了一个软件(或者说package),这个软件实现了协议,并且暴露出了一些API接口供客户端与数据库交互,这个软件就是数据库驱动。

驱动有标准,比如ODBC和JDBC,符合标准的驱动会实现一套相同的API接口,这样即使更换了数据库,客户端也不需要变更。

另外显而易见的是,驱动是语言相关的,不同的编程语言操作数据库需要对应语言实现的数据库驱动。所以驱动主要就是实现了与数据库交互的协议,当我们使用时,一般会这么写:

1
2
3
4
5
6
7
8
9
10
11
12
package main
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
func main() {
// mysql是驱动的名字
db, err := sql.Open("mysql", "username:passwd@/test?charset=utf8")
}

上面的

1
2
3
import (
_ "github.com/go-sql-driver/mysql"
)

会执行init函数,将mysql驱动注册到database/sql中的drivers中去,drivers是一个map:

1
drivers = make(map[string]driver.Driver)

显然,我们可以注册多个驱动,如果我们后端使用了不同的数据库的话,比如同时使用了mysqlpostgresql

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
_ "github.com/lib/pq"
)
func main() {
// mysql和postgres是驱动的名字
my_db, err := sql.Open("mysql", "username:passwd@/test?charset=utf8")
postgre_db, err := sql.Open("postgres", "username:passwd@/test?charset=utf8")
}

sqlx

sql是标准库database/sql的一个扩展,提供了一些更友好的接口,但是并没有过度封装,很多人放弃使用各种orm转而使用了sqlx