golang:闲谈数据库操作

来源:互联网 发布:苹果6s有数据快捷键 编辑:程序博客网 时间:2024/04/29 07:40

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

import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
)

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


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

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

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

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

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

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

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

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)
}

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

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

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

另一种:

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

事务:type Tx

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

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

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

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

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

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





0 0
原创粉丝点击