golang:闲谈数据库操作

前端之家收集整理的这篇文章主要介绍了golang:闲谈数据库操作前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

@H_404_3@今天简单看了下database/sql包,稍微总结下关于golang的数据库操作的一些东西,如有错误的地方,欢迎指出。@H_404_3@

@H_404_3@@H_404_3@@H_404_3@

import (@H_404_3@
"database/sql"@H_404_3@
 
_ "github.com/go-sql-driver/MysqL"@H_404_3@
)@H_404_3@

@H_404_3@首先在使用的时候要把这个包引入,同时还需要引入一个github.com/go-sql-driver/MysqL 前面用了一个"_@H_404_3@",@H_404_3@操作其实是引入该包,而不使用包里面的函数,不理解的话可以看下图:@H_404_3@@H_404_3@


@H_404_3@@H_404_3@

@H_404_3@引入包中的init函数会被执行,这样使得sql.Register完成注册。@H_404_3@@H_404_3@@H_404_3@

@H_404_3@接下来我们创建一个数据库操作句柄(DB):@H_404_3@

DB,err = sql.Open("MysqL","root:root@/test?charset=utf8")@H_404_3@
根据官网文档的说明,Open打开一个dirverName指定的数据库,dataSourceName指定数据源,简单的说就是第一个参数你跟着填“MysqL”,第二个格式则是:“用户名:密码@/数据库名称”(本地);用户名:密码@@H_404_3@@H_404_3@tcp(IP:端口)/@H_404_3@数据库名称”@H_404_3@@H_404_3@

@H_404_3@在执行Open函数的时候,并不能获取连接的有效性,当执行数据库操作的时候才会去连接数据库,当我们需要在Open之后就知道连接的有效性的时候,可以通过Ping()来进行。这里需要提一提的是,通常情况下,我们open之后再函数结束都会用一个close去关闭连接,但是@H_404_3@但是sql.DB是被设计成长期有效的类型,意思就是说如果我们需要频繁的操作数据库进行插入,更新,删除,查找操作的话,建议可以声明一个全局的DB,在每次操作时就不需要@H_404_3@频繁的Open和Close。官方文档的说明是这样的:@H_404_3@@H_404_3@@H_404_3@

DB是一个数据库(操作)句柄,代表一个具有零到多个底层连接的连接池。它可以安全的被多个go程同时使用。@H_404_3@

sql包会自动创建和释放连接;它也会维护一个闲置连接的连接池。如果数据库具有单连接状态的概念,该状态只有在事务中被观察时才可信。一旦调用了BD.Begin,返回的Tx会绑定到单个连接。当调用事务Tx的Commit或Rollback后,该事务使用的连接会归还到DB的闲置连接池中。@H_404_3@

@H_404_3@对于增删改操作,我们可以使用db.Prepare()Prepare该函数创建一个准备好的状态用于之后的查询和命令。返回值可以同时执行多个查询和命令,举个栗子:@H_404_3@@H_404_3@

stmt,err := DB.Prepare("insert test set name=?,age=?")
if err != nil {
log.Println(err)
}
defer stmt.Close()
res,err:=stmt.Exec(“小明””,18)
if err != nil {
log.Println(err)
}@H_404_3@@H_404_3@

@H_404_3@至于查询操作的话,有两种,一种是查询单挑记录,找到第一个后,后面不管还有没有,直接返回这条,后面的丢弃,一种是一般的查询,先说单条查询:@H_404_3@@H_404_3@

err = db.QueryRow("select name from test where id = ?",1).Scan(&“小明”)
@H_404_3@@H_404_3@

QueryRow方法返回Row,代表单行查询结果,Scan将该行查询结果各列分别保存进dest参数指定的值中。如果该查询匹配多行,Scan会使用第一行结果并丢弃其余各行。如果没有匹配查询的行,Scan会返回ErrNoRows。@H_404_3@@H_404_3@@H_404_3@@H_404_3@@H_404_3@

另一种:@H_404_3@

rows,err := db.Query("select name,age from test where id = ? ",1)
@H_404_3@if err != nil {
@H_404_3@fmt.Println(err)
@H_404_3@}
@H_404_3@defer rows.Close()
@H_404_3@for rows.Next() {
@H_404_3@err := rows.Scan(&name,&age)
@H_404_3@if err != nil {
@H_404_3@fmt.Println(err)
@H_404_3@}
@H_404_3@}
@H_404_3@

事务:@H_404_3@type@H_404_3@Tx@H_404_3@

@H_404_3@@H_404_3@@H_404_3@

type Tx struct {
    // 内含隐藏或非导出字段@H_404_3@
}@H_404_3@
@H_404_3@@H_404_3@

一次事务必须以对Commit或Rollback的调用结束。@H_404_3@

调用Commit或Rollback后,所有对事务的操作都会失败并返回错误值ErrTxDone。再来看个栗子:@H_404_3@

@H_404_3@tx,err := Db.Begin()
@H_404_3@if err != nil {
@H_404_3@fmt.Println(err)
@H_404_3@return 0,err
@H_404_3@}
@H_404_3@stmt,err := Db.Prepare("insert test set name=?,age=?")
@H_404_3@if err != nil {
@H_404_3@fmt.Println(err)
@H_404_3@return 0,err
@H_404_3@}
@H_404_3@defer stmt.Close()
@H_404_3@res,_ := stmt.Exec("小明",20)@H_404_3@

@H_404_3@if err != nil {@H_404_3@
@H_404_3@fmt.Println(err)@H_404_3@
return 0,err@H_404_3@
}@H_404_3@
@H_404_3@defer tx.Rollback()
@H_404_3@tx.Commit()
@H_404_3@

感觉有这些已经够用了,具体用的时候自己变通下,要是还不是很理解的话建议动手试试,不清楚的可以查官方文档,里面写的都挺清楚的。@H_404_3@

原文链接:https://www.f2er.com/go/189085.html

猜你在找的Go相关文章