首页 > Go学习 > go语言中的数据库操作
2021
10-23

go语言中的数据库操作

在go语言中,标准库"database/sql"提供了保证SQL或类SQL数据库的泛用接口,使用前需要注入对应的数据库驱动,go标准库中没有提供任何一个数据库驱动,需要我们通过其他方式安装驱动

常用的支持"database/sql"通用接口的数据库驱动包地址:

    sqlite3:github.com/mattn/go-sqlite3(注册的数据库驱动名称"sqlite3")
    mysql:github.com/go-sql-driver/mysql(注册的数据库驱动名称"mysql")
    postgresDB:github.com/lib/pq(注册的数据库驱动名称"postgres")
    
    import (
        "database/sql"
        _ "github.com/mattn/go-sqlite3"
    )

标准库"database/sql"的使用

type Result interface {
    LastInsertId() (int64, error)
    // 返回一个数据库生成的回应命令的整数
    // 当插入新行时,一般来自一个"自增"列
    // 不是所有的数据库都支持该功能,该状态的语法也各有不同。
    RowsAffected() (int64, error)
    // 返回被update、insert或delete命令影响的行数
    // 不是所有的数据库都支持该功能。
}

Register(name string, driver driver.Driver)
    注册并命名一个数据库,可以在Open函数中使用该命名启用该驱动
    当我们引入数据库驱动时都会通过init方法注册,无需我们再去注册

type DB struct {}
    DB是一个数据库(操作)句柄,代表一个具有零到多个底层连接的连接池。
    可以安全的被多个go程同时使用,sql包会自动创建和释放连接;
    它也会维护一个闲置连接的连接池。
    如果数据库具有单连接状态的概念,该状态只有在事务中被观察时才可信。
    一旦调用了BD.Begin,返回的Tx会绑定到单个连接。
    当调用事务Tx的Commit或Rollback后,该事务使用的连接会归还到DB的闲置连接池中。
    连接池的大小可以用SetMaxIdleConns方法控制。

Open(driverName, dataSourceName string) (*DB, error)
    打开一个dirverName指定的数据库
    dataSourceName指定数据源,指定数据库名和连接信息
    该函数可能只是验证其参数,而不创建与数据库的连接
    调用返回值的Ping方法检查数据源的名称是否合法
    返回的DB可以安全的被多个go程同时使用,并会维护自身的闲置连接池。
    sqlite3只需传入数据库文件即可
        db,err := sql.Open("sqlite3","/path/db_file.db")
    mysql:
        db,err := sql.Open("mysql","username:password@tcp(ip:port)/database?charset=utf8")

Open函数返回的*DB的方法

    Driver() driver.Driver:返回数据库下层驱动
    Ping() error:检查与数据库的连接是否仍有效,如果需要会创建连接
    Close() error:关闭数据库,释放任何打开的资源
    SetMaxOpenConns(n int):设置与数据库建立连接的最大数目
        如果n <= 0,不会限制最大开启连接数,默认为0
    SetMaxIdleConns(n int):设置连接池中的最大闲置连接数
        如果n大于最大连接数,则最大闲置连接数会设置为最大连接数
        如果n <= 0,不会保留闲置连接
    Exec(query string, args ...interface{}) (Result, error)
        执行一次命令,args表示query中的占位参数
    Query(query string, args ...interface{}) (*Rows, error)
        执行一次查询,返回所有结果(Rows),args表示query中的占位参数
    QueryRow(query string, args ...interface{}) *Row
        执行一次查询,并仅返回一行结果(即Row)
        总是返回非nil的值,直到返回值的Scan方法被调用时,才会返回可能的错误
    占位符(字符串占位符不能使用单引号包含)
        ?:后面参数按照问号的顺序依次提供
        $n:第一个为$1,第二个为$2,以此类推
    Prepare(query string) (*Stmt, error)
        创建一个准备好的状态用于之后的查询和命令
        stmt,err := db.Prepare("insert into info (name,age) values (?,?)")
    Begin() (*Tx, error):Begin开始一个事务。隔离水平由数据库驱动决定

type Row struct {}:表示单行查询结果

    Scan(dest ...interface{}) error
        将该行查询结果各列分别保存进dest参数指定的值中
        如果没有匹配查询的行,会返回ErrNoRows

type Rows struct {}:表示多行查询结果集

    它的游标默认指向结果集的第零行
    
    Columns() ([]string, error):返回所有列的名称
    Scan(dest ...interface{}) error:将当前游标所在行各列结果填充进dest指定的各个值中
    Next() bool:将当前游标向下移动一行。如果没有下一行或者出现错误会返回false
    Close() error:Close关闭Rows,如果Next方法返回假,Rows会自动关闭
    Err() error:返回可能的、在迭代时出现的错误
    使用示例:
    req,err := db.Query("select id,name,age from info")
    for req.Next(){
         var id int
         var name string
         var age int
         err = req.Scan(&id,&name,&age)
         checkErr(err)
         fmt.Println(id,name,age)

type Stmt struct {}:表示准备好的状态,可以安全的被多个go程同时使用

    Exec(args ...interface{}) (Result, error)
    Query(args ...interface{}) (*Rows, error)
    QueryRow(args ...interface{}) *Row
    Close() error:关闭状态
    使用示例:
    stmt,err := db.Prepare("insert into info (name,age) values (?,?)")
        name为字符串,age为数字,但是创建Stmt时的sql语句value中name不需要添加单引号
    req,err := stmt.Exec("三千",30)
        按照创建Stmt时的问号顺序依次传入值即可

type Tx struct {}:代表一个进行中的数据库事务

    一次事务必须以对Commit或Rollback的调用结束。
    调用Commit或Rollback后,所有对事务的操作都会失败并返回错误值ErrTxDone
    
    Exec(query string, args ...interface{}) (Result, error)
    Query(query string, args ...interface{}) (*Rows, error)
    QueryRow(query string, args ...interface{}) *Row
    Prepare(query string) (*Stmt, error)
        准备一个专用于该事务的状态
        返回的该事务专属状态操作在Tx递交会回滚后不能再使用
    Stmt(stmt *Stmt) *Stmt
        使用已存在的状态生成一个该事务特定的状态
    Commit() error:递交事务
    Rollback() error:放弃并回滚事务
最后编辑:
作者:qingheluo
这个作者貌似有点懒,什么都没有留下。

留下一个回复

你的email不会被公开。