Golang1.7.4标准库sql使用

来源:互联网 发布:c语言volatile的作用 编辑:程序博客网 时间:2024/05/17 05:09
package mainimport (    "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}//连接数据库,当网络不可达的时候会循环连接,知道连接成功,每次连接等待时间会递增,最大等待时间为120sfunc (s *_mysql) dial() error {    if s.db == nil {        err := s.init()        if err != nil {            return err        }    }    var rtime time.Duration = 10redial:    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}
1 0