package mysql import ( "MeterService/core/config" "database/sql" "errors" "fmt" "sync" orm "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" ) type MySqlPool struct{} var once sync.Once var err error var db *orm.DB func GetDb() *orm.DB { once.Do(func() { db = openMySqlPool() }) return db } func openMySqlPool() *orm.DB { dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local", config.C.Mysql.Username, config.C.Mysql.Password, config.C.Mysql.Host, config.C.Mysql.Port, config.C.Mysql.Name) db, err := orm.Open("mysql", dsn) if err != nil { panic(errors.New("mysql连接失败。" + err.Error())) } if config.C.Mysql.MaxIdleConns > 0 { db.DB().SetMaxIdleConns(config.C.Mysql.MaxIdleConns) } if config.C.Mysql.MaxOpenConns > 0 { db.DB().SetMaxOpenConns(config.C.Mysql.MaxOpenConns) } if config.C.Mysql.Log { db.LogMode(config.C.Mysql.Log) } return db } func CloseDb(db *orm.DB) { err := db.Close() if err != nil { return } else { panic(err) } } func (pool *MySqlPool) InitPool() (isSuc bool) { dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local", config.C.Mysql.Username, config.C.Mysql.Password, config.C.Mysql.Host, config.C.Mysql.Port, config.C.Mysql.Name) db, err := orm.Open("mysql", dsn) if err != nil { panic(err) return false } // 连接数配置也可以写入配置,在此读取 if config.C.Mysql.MaxIdleConns > 0 { db.DB().SetMaxIdleConns(config.C.Mysql.MaxIdleConns) } if config.C.Mysql.MaxOpenConns > 0 { db.DB().SetMaxOpenConns(config.C.Mysql.MaxOpenConns) } return true } // Exec 增、删、改 func Exec(SQL string, args ...interface{}) (sql.Result, error) { DB := GetDb().DB() ret, err := DB.Exec(SQL, args) if err != nil { return nil, err } return ret, nil } func Query(SQL string, args ...interface{}) ([]map[string]string, bool) { //通用查询 DB := GetDb().DB() rows, err := DB.Query(SQL, args) //执行SQL语句,比如select * from users if err != nil { panic(err) } columns, _ := rows.Columns() //获取列的信息 count := len(columns) //列的数量 var values = make([]interface{}, count) //创建一个与列的数量相当的空接口 for i, _ := range values { var ii interface{} //为空接口分配内存 values[i] = &ii //取得这些内存的指针,因后继的Scan函数只接受指针 } ret := make([]map[string]string, 0) //创建返回值:不定长的map类型切片 for rows.Next() { err := rows.Scan(values...) //开始读行,Scan函数只接受指针变量 m := make(map[string]string) //用于存放1列的 [键/值] 对 if err != nil { panic(err) } for i, colName := range columns { var rawValue = *(values[i].(*interface{})) //读出raw数据,类型为byte b, _ := rawValue.([]byte) v := string(b) //将raw数据转换成字符串 m[colName] = v //colName是键,v是值 } ret = append(ret, m) //将单行所有列的键值对附加在总的返回值上(以行为单位) } defer func(rows *sql.Rows) { _ = rows.Close() }(rows) if len(ret) != 0 { return ret, true } return nil, false }