driver.RowsAffected
RowsAffected 其实就是一个 int64 的别名,但是他实现了 Result 接口,用来底层实现 Result 的表示方式
type RowsAffected int64
func (RowsAffected) LastInsertId() (int64, error)
func (v RowsAffected) RowsAffected() (int64, error)
driver.Value
Value 其实就是一个空接口,他可以容纳任何的数据
type Value interface{}
drive 的 Value 是驱动必须能够操作的 Value,Value 要么是 nil,要么是下面的任意一种
int64
float64
bool
[]byte
string [*]除了Rows.Next 返回的不能是 string.
time.Time
driver.ValueConverter
ValueConverter 接口定义了如何把一个普通的值转化成 driver.Value 的接口
type ValueConverter interface {
ConvertValue(v interface{}) (Value, error)
}
在开发的数据库驱动包里面实现这个接口的函数在很多地方会使用到,这个 ValueConverter 有很多好处:
转化 driver.value 到数据库表相应的字段,例如 int64 的数据如何转化成数据库表 uint16 字段
把数据库查询结果转化成 driver.Value 值
在 scan 函数里面如何把 driver.Value 值转化成用户定义的值
driver.Valuer
Valuer 接口定义了返回一个 driver.Value 的方式
type Valuer interface {
Value() (Value, error)
}
很多类型都实现了这个 Value 方法,用来自身与 driver.Value 的转化。
通过上面的讲解,你应该对于驱动的开发有了一个基本的了解,一个驱动只要实现了这些接口就能完成增删查改等基本操作了,剩下的就是与相应的数据库进行数据交互等细节问题了,在此不再赘述。
database/sql
database/sql 在 database/sql/driver 提供的接口基础上定义了一些更高阶的方法,用以简化数据库操作,同时内部还建议性地实现一个 conn pool。
type DB struct {
driver driver.Driver
dsn string
mu sync.Mutex // protects freeConn and closed
freeConn []driver.Conn
closed bool
}
我们可以看到 Open 函数返回的是 DB 对象,里面有一个 freeConn,它就是那个简易的连接池。它的实现相当简单或者说简陋,就是当执行 db.prepare -> db.prepareDC 的时候会 defer dc.releaseConn,然后调用 db.putConn,也就是把这个连接放入连接池,每次调用 db.conn 的时候会先判断 freeConn 的长度是否大于 0,大于 0 说明有可以复用的 conn,直接拿出来用就是了,如果不大于 0,则创建一个 conn,然后再返回之。
网友评论