database的用法|青训营笔记

233 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第5篇笔记。

借鉴segmentfault.com/a/119000000… 对其中的一些内容进行了补充。

关于database/sql 与 driver 包

简单来说 "database/sql"提供了一个抽象的数据库接口,并没有实现具体的数据库类型。仅仅是实现标准化即在golang中对数据库操作的统一操作格式。 "github.com/go-sql-driver/mysql" 是一个MySQL的驱动,他接收database/sql 传入的命令然后直接作用的MySQL数据库进行操作。

sql.DB不是一个连接,它是数据库的抽象接口。它可以根据driver打开关闭数据库连接,管理连接池。正在使用的连接被标记为繁忙,用完后回到连接池等待下次使用。所以,如果你没有把连接释放回连接池,会导致过多连接使系统资源耗尽。

连接DB
/get a link from SQL
//root is mysql user's name 123456 is password tcp is connection method  test01 is the DB name
db, err := sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/test01")
if err != nil {
   log.Fatal(err)
}
defer db.Close()
查询
var (
    id int
    name string
)
rows, err := db.Query("select id, name from users where id = ?", 1)
if err != nil {
    log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
    err := rows.Scan(&id, &name)
    if err != nil {
        log.Fatal(err)
    }
    log.Println(id, name)
}
err = rows.Err()
if err != nil {
    log.Fatal(err)
}

上面代码的过程为:db.Query()表示向数据库发送一个query,defer rows.Close()非常重要,遍历rows使用rows.Next(), 把遍历到的数据存入变量使用rows.Scan(), 遍历完成后检查error。有几点需要注意:

  1. 检查遍历是否有error
  2. 结果集(rows)未关闭前,底层的连接处于繁忙状态。当遍历读到最后一条记录时,会发生一个内部EOF错误,自动调用rows.Close(),但是如果提前退出循环,rows不会关闭,连接不会回到连接池中,连接也不会关闭。所以手动关闭非常重要。rows.Close()可以多次调用,是无害操作。
单行Query
var name string
err = db.QueryRow("select name from users where id = ?", 1).Scan(&name)
if err != nil {
    log.Fatal(err)
}
fmt.Println(name)
result,err:=Db.Exec("INSERT INTO member(username,money,birthday,created_at)VALUES (?,?,?,?)","test","10",nil,time.Now().Unix())
	if err!=nil {
		fmt.Println(err);return
	}
	//获取修改的行数
	id,err:=result.LastInsertId()
	if err != nil {
		fmt.Println(err); return
	}
	fmt.Println(id)
result,err:=Db.Exec("DELETE FROM member WHERE id=?",3)
	if err!=nil {
		fmt.Println(err);return
	}
	//获取删除的行数
	rows,err:=result.RowsAffected()
	if err != nil {
		fmt.Println(err); return
	}
	fmt.Println(rows)
result,err:=Db.Exec("UPDATE member set money=money+10 WHERE id=?",1)
	if err!=nil {
		fmt.Println(err);return
	}
	//获取修改的行数
	rows,err:=result.RowsAffected()
	if err != nil {
		fmt.Println(err); return
	}
	fmt.Println(rows)
        ```