package main
import (
"database/sql"
"errors"
"fmt"
"net"
"sync/atomic"
"time"
"github.com/go-sql-driver/mysql"
)
func main() {}
//新建mysql连接,connstr为mysql连接串"root:123456@tcp(172.18.80.211:3306)/workstacks?charset=utf8"
//maxopen为最大连接数
func NewMysql(connstr string, maxopen int) (*_mysql, error) {
m := &_mysql{connstr: connstr, maxopen: maxopen}
err := m.dial()
return m, err
}
var UnavailableError = errors.New("Status Unavailable")
type _mysql struct {
connstr string
maxopen int
db *sql.DB
status uint32
}
//初始化连接串
func (s *_mysql) init() error {
db, err := sql.Open("mysql", s.connstr)
if err != nil {
return err
}
if s.maxopen <= 0 {
db.SetMaxOpenConns(20)
} else {
db.SetMaxOpenConns(s.maxopen)
}
s.db = db
return nil
}
//连接数据库,当网络不可达的时候会循环连接,知道连接成功,每次连接等待时间会递增,最大等待时间为120s
func (s *_mysql) dial() error {
if s.db == nil {
err := s.init()
if err != nil {
return err
}
}
var rtime time.Duration = 10
redial:
err := s.db.Ping()
if err != nil {
if _, ok := err.(*mysql.MySQLError); ok {
return err
}
if isNetError(err) {
<-time.After(rtime * time.Second)
if rtime < 120 {
rtime += 10
}
fmt.Println(err)
goto redial
}
return err
}
s.SetStatus(1)
return nil
}
//重置数据库连接信息
func (s *_mysql) Reset(connstr string, maxopen int) error {
db, err := sql.Open("mysql", connstr)
if err != nil {
return err
}
if maxopen <= 0 {
db.SetMaxOpenConns(20)
} else {
db.SetMaxOpenConns(maxopen)
}
err = db.Ping()
if err != nil {
return err
}
s.connstr = connstr
s.maxopen = maxopen
tmpdb := s.db
s.db = db
tmpdb.Close()
return nil
}
//执行SQL语句,insert,update,delete等
func (s *_mysql) Exec(query string, args ...interface{}) (sql.Result, error) {
if s.Status() {
result, err := s.db.Exec(query, args...)
if err != nil {
if isNetError(err) {
s.SetStatus(0)
if err = s.dial(); err == nil {
return s.Exec(query, args...)
}
return nil, err
}
}
return result, err
}
return nil, UnavailableError
}
//执行SQL查询
func (s *_mysql) Query(query string, args ...interface{}) (*sql.Rows, error) {
if s.Status() {
rows, err := s.db.Query(query, args...)
if err != nil {
if isNetError(err) {
s.SetStatus(0)
if err = s.dial(); err == nil {
return s.Query(query, args...)
}
return nil, err
}
}
return rows, err
}
return nil, UnavailableError
}
//查看当前状态是否可用,返回true表示可用
func (s *_mysql) Status() bool {
return atomic.LoadUint32(&s.status) != 0
}
//设置状态,0表示状态不可用,1表示状态可用
func (s *_mysql) SetStatus(status uint32) {
atomic.StoreUint32(&s.status, status)
}
//关闭数据库连接
func (s *_mysql) Close() {
if s.db != nil {
s.db.Close()
}
}
func isNetError(err error) bool {
_, ok := err.(*net.OpError)
return ok
}
Golang1.7.4标准库sql使用
最新推荐文章于 2024-04-28 21:48:01 发布