读书笔记GO

《go web 编程》第四章 访问数据库:database/sq

2022-09-13  本文已影响0人  bycall

Go 与 PHP 不同的地方是 Go 官方没有提供数据库驱动,而是为开发数据库驱动定义了一些标准接口,开发者可以根据定义的接口来开发相应的数据库驱动,这样做有一个好处,只要是按照标准接口开发的代码, 以后需要迁移数据库时,不需要任何修改。那么 Go 都定义了哪些标准接口呢?让我们来详细的分析一下

sql.Register

这个存在于 database/sql 的函数是用来注册数据库驱动的,当第三方开发者开发数据库驱动时,都会实现 init 函数,在 init 里面会调用这个 Register(name string, driver driver.Driver) 完成本驱动的注册。

我们来看一下 mymysql、sqlite3 的驱动里面都是怎么调用的:


// https://github.com/mattn/go-sqlite3 驱动
func init() {
    sql.Register("sqlite3", &SQLiteDriver{})
}

// https://github.com/mikespook/mymysql 驱动
// Driver automatically registered in database/sql
var d = Driver{proto: "tcp", raddr: "127.0.0.1:3306"}
func init() {
    Register("SET NAMES utf8")
    sql.Register("mymysql", &d)
}

我们看到第三方数据库驱动都是通过调用这个函数来注册自己的数据库驱动名称以及相应的 driver 实现。在 database/sql 内部通过一个 map 来存储用户定义的相应驱动。


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

drivers[name] = driver

因此通过 database/sql 的注册函数可以同时注册多个数据库驱动,只要不重复。

在我们使用 database/sql 接口和第三方库的时候经常看到如下:

 import (
      "database/sql"
      _ "github.com/mattn/go-sqlite3"
  )

新手都会被这个 _ 所迷惑,其实这个就是 Go 设计的巧妙之处,我们在变量赋值的时候经常看到这个符号,它是用来忽略变量赋值的占位符,那么包引入用到这个符号也是相似的作用,这儿使用 _ 的意思是引入后面的包名而不直接使用这个包中定义的函数,变量等资源。

我们在 2.3 节流程和函数一节中介绍过 init 函数的初始化过程,包在引入的时候会自动调用包的 init 函数以完成对包的初始化。因此,我们引入上面的数据库驱动包之后会自动去调用 init 函数,然后在 init 函数里面注册这个数据库驱动,这样我们就可以在接下来的代码中直接使用这个数据库驱动了。

上一篇下一篇

猜你喜欢

热点阅读