19年底36周:Go database/sql库-Go数据库操作

2019-10-07  本文已影响0人  习惯研究所所长

一、简介

  1. database/sql提供了Go访问和操作SQL数据库的方法。
  2. 在Go语言中,使用sql.DB使用此类型来创建语句和事务,并执行查询以及获取结果。
  3. sql.DB负责的是:
    • 负责通过驱动程序打开和关闭与实际底层数据库的连接;
    • 负责管理连接池(但不负责回收,需要开发者自己回收);

二、数据库操作

  1. 数据库连接:连接仅仅是对数据库抽象,并没有真正连接。需要通过db.Ping()来测试连接。
  2. 不同数据库的查询语句占位符:
    • Mysql:?
    • Postgresql: $N,其中N为数字
    • SQLite:接受上述两者之一
    • Oracle::paramN
  3. 基本命令:
    Open() – creates a DB
    Close() - closes the DB
    Query() - 查询
    QueryRow() -查询行
    Exec() -执行操作,update,insert,delete
    Row - A row is not a hash map, but an abstraction of a cursor
    Next()
    Scan()
    Prepare() - 准备语句
  4. 数据库的基本操作逻辑:准备、执行、关闭
  5. 数据库的操作主要分为两个:Exec(),Query()
  • 如何使用Query()
  1. 使用db.Query()来发送查询到数据库,获取结果集Rows,并检查错误。
  2. 使用rows.Next()作为循环条件,迭代读取结果集。
  3. 使用rows.Scan从结果集中获取一行结果。
  4. 使用rows.Err()在退出迭代后检查错误。
  5. 使用rows.Close()关闭结果集,释放连接。
func dbPrepare(db sql.DB){
    stmt, err := db.Prepare("select id, name from users where id != ?")
    // stmt是一个支持高并发的预备sql, 当stmt关闭后,那么后面的所有使用stmt的都不可以使用
    // 准备、执行、关闭
    if err != nil {
        log.Fatal(err)
    }
    defer stmt.Close()
    rows, err := stmt.Query(1) // 1, stmt.Query() 发送查询到数据库获取结果集
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close() // 5, rows.Close() 延迟关闭结果集,释放连接
    for rows.Next() { // 2, rows.Next() 循环迭代结果集
        err := rows.Scan(&id, &name) // 3, rows.Scan() 读取一行数据,这个是从远程一行行读取的还是本地缓存? 
        processErr(err)
        log.Println(id,name)
    }
    // 4, rows.Err() 在退出迭代后检查错误
    if err = rows.Err(); err != nil {
        log.Fatal(err)
    }
}

  1. 准备语句Prepared Statement

三、使用sql.DB注意事项

  1. 把sql.DB视为长期存在的对象,否则可能会遇到诸如重复使用和连接共享不足;
  2. 使用db.Query(sqlStr, sqlDatas)和db.Prepare(sqlStr).Exec(sqlDatas)的区别:
  • 答:本质上没区别?Prepare once,execute many times,对于批量操作的时候用这个?
  1. 增删改等doesn’t return rows的操作使用 Exec()[并且配套使用prepared statement], 查询使用 Query()。
  • 答:使用Query但不读取返回结果,会导致底层连接永远无法释放。
    [图片上传失败...(image-1c045c-1570439040218)]
  1. 查询时一定要释放连接defer rows.Close()
上一篇下一篇

猜你喜欢

热点阅读