这是我参与「第五届青训营」伴学笔记创作活动的第 13天。
前言
本文学习database/sql的基础语法,设计原理及基础概念
基础语法
实现import driver
import (
"database/sqL"
_"github com/go-sql-driver/mysql"
)
使用driver+DSN初始化DB连接,并执行一条SQL,通过rows取回返回的数据
处理完毕后,需要释放链接:
func main() {
db, err := sql.Open("mysqL","user: password@tcp(127.0.0.1:3306)/hello")
rows, err := db.Query("select id, name from users where id = ?", 1)
if err!=nil{
// xxx
}
defer rows.Close()
数据、错误处理:
var users User
for rows.Next() {
var user User
err := rows.Scan(&user.ID, &user.Name)
if err!=nil{
// ...
}
users = append(users, user)
}
处理错误:
if rows.Err() != nil {
// ...
}
设计原理
- 连接池
- 连接池配置
func (db *DB) SetConnMaxIdleTime(d time.Duration)
func (db *DB) SetConnMaxLifetime(d time.Duration)
func (db *DB) SetMaxIdleConns(n int)
func (db *DB) SetMaxOpenConns(n int)
- 连接池状态
func(db *DB) Stats() DBStats
- 操作过程伪实现
for i := 0; i < maxBadConnRetries; i++ {
//从连接池获取连接或通过driver新建连接
dc, err := db. conn(ctx, strategy)
//有空闲连接-> reuse -> max life time
//新建连接-> max open...
//将连接放回连接池
defer dc.db.putConn(dc, err,true)
// validateConnection 有无错误
// max life time, max idle conns 检查
//连接实现driver . Queryer, driver, Execer 等interface
if err == nil {
err = dc.ci.Query(sql, args...)
}
isBadConn = errors.Is(err, driver.ErrBadConn)
if !isBadConn {
break
}
}
- Driver连接端口
//注册全局driver
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
}
// Driver接口
type Driver interface {
// Open returns a new connection to the database .
Open(name string) (Conn, error)
}
- DB连接的几种类型
- 直接连接/ Conn
- 预编译/ Stmt
- 事务/ Tx
- 处理返回数据的几种方式
- Exec / ExecContext > Result
- Query / QueryContext -> Rows (Columns)
- QueryRow / QueryRowContext -> Row (Rows简化)
总结
Go使用SQL与类SQL数据库的惯例是通过标准库database/sql。这是一个对关系型数据库的通用抽象,它提供了标准的、轻量的、面向行的接口。不过database/sql的包文档只讲它做了什么,却对如何使用只字未提。快速指南远比堆砌事实有用,本文讲述了database/sql的使用方法及其注意事项。
Go使用SQL与类SQL数据库的惯例是通过标准库database/sql。这是一个对关系型数据库的通用抽象,它提供了标准的、轻量的、面向行的接口。不过database/sql的包文档只讲它做了什么,却对如何使用只字未提。快速指南远比堆砌事实有用,本文讲述了database/sql的使用方法及其注意事项。