golang内部自带了连接池功能,刚开始接触golang的时候不了解这个,还自己搞了一个 sql.Open的对象管理池,真的非常囧啊。
sql.Open函数实际上是返回一个连接池对象,不是单个连接。在open的时候并没有去连接数据库,只有在执行query、exce方法的时候才会去实际连接数据库。在一个应用中同样的库连接只需要保存一个sql.Open之后的db对象就可以了,不需要多次open。
golang中关于mysql的增删改查我在前面的一篇文章中有说明了,不了解的小伙们可以先去了解一下:golang连接mysql操作示例增删改查
因为普通程序执行完毕之后资源就会被释放掉,所以这里尝试使用web服务进行演示。
开启web服务
首页先启动一个web服务监听9090端口,比较简单不多做说明。
1
2
3
4
5
6
7
|
func startHttpServer() {
http.HandleFunc( "/pool" , pool)
err := http.ListenAndServe( ":9090" , nil)
if err != nil {
log.Fatal( "ListenAndServe: " , err)
}
}
|
db对象初始化
声明一个全局的db对象,并进行初始化。
1
2
3
4
5
6
7
8
|
var db *sql.DB
func init() {
db, _ = sql.Open( "mysql" , "root:@tcp(127.0.0.1:3306)/test?charset=utf8" )
db.SetMaxOpenConns( 2000 )
db.SetMaxIdleConns( 1000 )
db.Ping()
}
|
连接池的实现关键在于SetMaxOpenConns和SetMaxIdleConns,其中:
SetMaxOpenConns用于设置最大打开的连接数,默认值为0表示不限制。 SetMaxIdleConns用于设置闲置的连接数。
设置最大的连接数,可以避免并发太高导致连接mysql出现too many connections的错误。设置闲置的连接数则当开启的一个连接使用完成后可以放在池里等候下一次使用。
请求方法
上面开启http请求设置了请求/pool地址的执行方法
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
|
func pool(w http.ResponseWriter, r *http.Request) {
rows, err := db.Query( "SELECT * FROM user limit 1" )
defer rows.Close()
checkErr(err)
columns, _ := rows.Columns()
scanArgs := make([] interface {}, len(columns))
values := make([] interface {}, len(columns))
for j := range values {
scanArgs[j] = &values[j]
}
record := make( map [string]string)
for rows.Next() {
//将行数据保存到record字典
err = rows.Scan(scanArgs...)
for i, col := range values {
if col != nil {
record[columns[i]] = string(col.([]byte))
}
}
}
fmt.Println(record)
fmt.Fprintln(w, "finish" )
}
|
|
请发表评论