import (
"strconv"
"database/sql"
{
import (
"context"
"database/sql/driver" // 文件 "database/sql/driver/driver.go" 定义接口 type Driver interface { ... }
"errors"
"fmt"
"io"
"reflect"
"runtime"
"sort"
"sync"
"sync/atomic"
"time"
)
}
_ "github.com/go-sql-driver/mysql"
// 文件 "github.com/go-sql-driver/mysql/driver.go"
{
import (
"database/sql"
"database/sql/driver"
"net"
"sync"
)
// ...
func init() {
// 文件 "database/sql/sql.go"
sql.Register("mysql", &MySQLDriver{}) // !!! ---------- 注册了驱动
{
func Register(name string, driver driver.Driver) {
driversMu.Lock()
defer driversMu.Unlock()
if driver == nil {
panic("sql: Register driver is nil")
}
if _, dup := drivers[name]; dup {
panic("sql: Register called twice for driver " + name)
}
drivers[name] = driver // 注入了驱动
}
}
}
}
"fmt"
"time"
"log"
)
db,_ = sql.Open("mysql", "super:Aa123456@tcp(127.0.0.1:3306)/test?charset=utf8")
{
// 文件 "database/sql/sql.go"
func Open(driverName, dataSourceName string) (*DB, error) {
driversMu.RLock()
driveri, ok := drivers[driverName] // !!! ---------- 获取驱动
driversMu.RUnlock()
if !ok {
return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName)
}
// driveri === &MySQLDriver{}
if driverCtx, ok := driveri.(driver.DriverContext); ok {
connector, err := driverCtx.OpenConnector(dataSourceName)
if err != nil {
return nil, err
}
return OpenDB(connector), nil
}
// !!! ---------- 使用驱动
return OpenDB(dsnConnector{dsn: dataSourceName, driver: driveri}), nil
{
// 文件 "database/sql/sql.go"
func OpenDB(c driver.Connector) *DB {
ctx, cancel := context.WithCancel(context.Background())
db := &DB{
connector: c,
openerCh: make(chan struct{}, connectionRequestQueueSize),
resetterCh: make(chan *driverConn, 50),
lastPut: make(map[*driverConn]string),
connRequests: make(map[uint64]chan connRequest),
stop: cancel,
}
go db.connectionOpener(ctx) // 例程
go db.connectionResetter(ctx) // 例程
return db
}
}
}
}