☃
1. 创建连接池
```go
// 创建连接池
func NewPool(host, user, password, dbName string, maxOpen, maxIdle int) (*Pool, error) {
// 创建连接池
pool := &Pool{
host: host,
user: user,
password: password,
dbName: dbName,
maxOpen: maxOpen,
maxIdle: maxIdle,
conns: make(chan *sql.DB, maxOpen),
}
// 初始化连接池
err := pool.init()
if err != nil {
return nil, err
}
return pool, nil
}
```
2. 初始化连接池
```go
// 初始化连接池
func (p *Pool) init() error {
// 创建连接
for i := 0; i < p.maxOpen; i++ {
conn, err := p.newConn()
if err != nil {
return err
}
p.conns <- conn
}
return nil
}
```
3. 创建连接
```go
// 创建连接
func (p *Pool) newConn() (*sql.DB, error) {
// 连接数据库
conn, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8", p.user, p.password, p.host, p.dbName))
if err != nil {
return nil, err
}
// 设置最大连接数
conn.SetMaxOpenConns(p.maxOpen)
// 设置最大空闲连接数
conn.SetMaxIdleConns(p.maxIdle)
return conn, nil
}
```
4. 获取连接
```go
// 获取连接
func (p *Pool) GetConn() (*sql.DB, error) {
// 从连接池中获取连接
conn := <-p.conns
// 检查连接是否有效
if err := conn.Ping(); err != nil {
// 连接失效,重新创建连接
conn, err = p.newConn()
if err != nil {
return nil, err
}
}
return conn, nil
}
```
5. 释放连接
```go
// 释放连接
func (p *Pool) ReleaseConn(conn *sql.DB) {
// 将连接放回连接池
p.conns <- conn
}
```
6. 关闭连接池
```go
// 关闭连接池
func (p *Pool) Close() {
// 关闭连接池中的所有连接
for conn := range p.conns {
conn.Close()
}
// 关闭连接池
close(p.conns)
}
```
7. 定时自检
```go
// 定时自检
func (p *Pool) Check() {
// 定时自检
ticker := time.NewTicker(time.Second * 10)
for {
select {
case <-ticker.C:
// 检查连接池中的连接是否有效
for conn := range p.conns {
if err := conn.Ping(); err != nil {
// 连接失效,重新创建连接
conn, err := p.newConn()
if err != nil {
continue
}
// 将新连接放回连接池
p.conns <- conn
}
}
}
}
}
```