为了账号安全,请及时绑定邮箱和手机立即绑定

[Go菜牛系列]理解database/sql

标签:
Go

​关于数据库访问,Golang中提供了标准库database/sql。不过它不是针对某种具体数据库的逻辑实现,而是一套统一抽象的接口。
其中真正与数据库打交道的,是各个数据库对应的驱动Driver;在使用时需要先注册对应的驱动库,然后就能通过标准库sql中定义的接口来统一操作数据库。

  • 创建sql.DB连接池

​我们来看一下如何创建sdl.DB连接池,以MySQL为例:

import (
  "log"
  "os"
  "database/sql"
  // 手动注册mysql的driver
  _ "github.com/go-sql-driver/mysql"
)func main() {
  db, err := sql.Open("mysql",
    "user:pwd@tcp(127.0.0.1:3306)/testdb")
  if err != nil {
    log.Fatal(err)
    os.Exit(1)
  }
  defer db.Close()
  
  err = db.Ping()
  if err != nil {
     // TODO do something
  }
  // ...
}

创建数据库连接是一种比较耗资源的操作,先要完成TCP三次握手,其后连接到数据库时需要进行鉴权和分配连接资源,因此建议使用长连接来避免频繁进行此类操作。在我们的Go应用中,sql.DB自身是会管理连接池的,一般实现为全局的连接池,不用频繁的创建/销毁连接(open/close)。

  • CRUD接口
// 1. 返回多行数据,手动关闭结果集 (defer rows.Close())
db.Query()
// 2. 返回单行数据,不须手动关闭结果集
db.QueryRow()
// 3. 预先将一条连接(conn)与一条sql语句绑定起来,供重复使用
stmt, err := db.Prepare(sql)
stmt.Query(args)
// 4. 适用于执行增/删/更新等操作(不需要返回结果集)
db.Exec()
  • 结果集合

Query()方法会返回结果集合,需要通过rows.Next(), rows.Scan()方法来遍历结果集合。

  • 事务
// 开始事务
tx := db.Begin()
// 执行事务
db.Exec()
// ...
// 提交事务
tx.Commit()
// 如果失败的话,回滚
tx.Rollback()
  • 小结

    用户层面所执行的sql语句,在库底层会将sql语句编码后,传输到数据库服务器端再执行,因此可以看作是C/S架构。

    对于如何访问不同的数据库,Go的做法是抽离出具体代码逻辑,将数据库操作分为database/sql和driver两层。database/sql负责提供统一的用户接口,以及一些不涉及操作具体数据库的逻辑(如连接池管理);而Driver层则负责与实际的数据库进行通信(moxiaomomo)。

点击查看更多内容
2人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消