Database/sql
一、基本用法
1.使用driver+DSN初始化DB连接
2.数据、错误处理
{ ...
var user User
err :=rows.Scan(&user.ID,&user,Name)
if err !=nil{
//...
}
users=append(users,user)
}
我们可以用这样的方式来返回错误:
defer func(){
err=rows.Close()
}
处理错误
if rows.Err !=nil{
//...
}
二、设计原理
应用程序通过操作接口连接database/sql,再通过连接接口和操作接口连接我们的数据库。\
1.操作过程伪实现
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]
}
2.driver 连接接口
//Driver 接口
type Driver interface{
//Open returns a new connection to the database
Open(name string) (Con,error)
]
对注册一个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
}
3.DB连接的几种类型
- 直接连接/Conn
- 预编译/Stmt
- 事务/Tx
4.处理返回数据的几种方式
- Exec/ExecContext->Result
- Query/QueryContext->Rows(Columns)
- QueryRow/QueryRowContext->Row(Rows简化)
第一种可以获取接口失败或成功的信息,第二和三种会把数据库请求之后的结果以行的形式返回数据。
三、GORM基础使用
基本用法
//更新某个字段
db.Model(&product).Update("Price",2000)
db.Model(&product).UpdateColumn("Price",2000)
//更新多个字段
db.Model(&product).Updates(Product{Price:2000,Code:"L1212"})
//批量更新
db.Model(&Product{}).Where("Price<?",2000).Updates(map[string]interface{}{"Price":2000})
//删除
db.Delete(&Product)
关联操作-CRUD
关联操作支持一个批量操作
Preload/Joins预加载
查询用户时会先加载它的信息
关联操作-级联删除
1.使用数据库的约束自动删除
2.使用Select实现级联删除,不依赖数据库约束及软删除
可删除Select查询的相关信息。
收获
在本节内容中,理解了Database以及SQL,学习了它们的一个基本用法和设计原理,知道怎样进行数据处理和错误处理,学习了DB的连接类型,知道了处理返回数据的三种方式,明白了它们之间处理的一个区别。同时简单了解了GROM的一个背景介绍和基础知识和它的关联操作。