golang 在 database 上的存取,建立了一個 sql 抽象介面 database/sql ,接著大家就可以透過這個 interface 去實作裡面相對應的 driver
目前看到比較多人使用的是 go-sql-driver/mysql
install
1
go get github . com / go - sql - driver / mysql
connect to database
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package main
import (
"database/sql"
"fmt"
"strings"
_ "github.com/go-sql-driver/mysql"
)
// db 設定
const (
userName = "root"
password = ""
host = "127.0.0.1"
port = "3306"
dbName = "dbName"
)
func initDB () {
// [username[:password]@][protocol[(address)]]/dbname[?param1=value1&...¶mN=valueN]
// "username:password@tcp(host:port)/數據庫?charset=utf8"
path := strings . Join ([] string { userName , ":" , password , "@tcp(" , host , ":" , port , ")/" , dbName , "?charset=utf8" }, "" )
fmt . Println ( path )
// 第一個是 driverName 第二個則是 database 的設定 path
// 也可以用 var DB *sql.DB
DB , _ := sql . Open ( "mysql" , path )
// 設定 database 最大連接數
DB . SetConnMaxLifetime ( 100 )
//設定上 database 最大閒置連接數
DB . SetMaxIdleConns ( 10 )
// 驗證是否連上 db
if err := DB . Ping (); err != nil {
fmt . Println ( "opon database fail:" , err )
return
}
fmt . Println ( "connnect success" )
}
func main () {
initDB ()
}
query
Exec
1
2
3
4
result , err := db . Exec (
"INSERT INTO users (name) VALUES (?)" ,
"leon" ,
)
QueryRow
1
2
3
4
5
6
7
var id int64
row := DB . QueryRow ( "SELECT id FROM users WHERE name = ?" , "leon" )
err := row . Scan ( & id )
if err != nil {
log . Fatal ( err )
}
fmt . Println ( id )
Query
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
rows , err := DB . Query ( "SELECT * FROM banner" )
if err != nil {
log . Fatal ( err )
}
// 記得要 close
defer rows . Close ()
for rows . Next () {
var id , width , height int64
if err := rows . Scan ( & id , & width , & height ); err != nil {
log . Fatal ( err )
}
fmt . Printf ( "id: %v, width: %v, height: %v\n" , id , width , height )
}
if err := rows . Err (); err != nil {
log . Fatal ( err )
}
Prepare
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
width := 640
stmt , err := DB . Prepare ( "SELECT id FROM banner WHERE width = ?" )
if err != nil {
log . Fatal ( err )
}
rows , err := stmt . Query ( width )
// 記得要 close
defer rows . Close ()
for rows . Next () {
var id int64
if err := rows . Scan ( & id ); err != nil {
log . Fatal ( err )
}
fmt . Printf ( "id: %v\n" , id )
}
Begin (transcation)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 開啟 transaction
tx , err := DB . Begin ()
if err != nil {
fmt . Println ( "tx fail" )
return
}
// 準備 sql 語句
stmt , err := tx . Prepare ( "INSERT INTO banner (`id`, `width`, `height`) VALUES (?, ?, ?)" )
if err != nil {
fmt . Println ( "Prepare fail" )
return
}
// 設定參數以及執行 sql 語句
res , err := stmt . Exec ( 100 , 200 , 300 )
if err != nil {
fmt . Println ( "Exec fail" )
return
}
// 提交 transaction
tx . Commit ()
// 取得最後一個 insert 的 id
fmt . Println ( res . LastInsertId ())
各種方式效率分析
先參照 golang學習之旅:使用go語言操作mysql數據庫 之後有用到再來研究
Reference: