標籤:雜湊表 eth ima query result pst eal select gets
分享一下 golang 實現的 redis 和 mysql 串連池,可以在項目中直接引用串連池控制代碼,調用對應的方法。
舉個栗子:
1 mysql 串連池的使用
(1) 在項目子目錄放置 mysql.go
(2)在需要調用的地方匯入串連池控制代碼 DB
(3)調用 DB.Query()
2 redis 串連池的使用
(1)在項目子目錄放置 redis.go
(2)在需要調用的地方匯入串連池控制代碼 Cache
(3)調用 Cache.SetString (“test_key”, “test_value”)
最新代碼地址:
https://github.com/hopehook/golang-db
PS:
歡迎交流指正,好用就點亮 star 吧 :)
附件:
1 mysql 串連池代碼
package libimport ("database/sql""fmt""strconv""github.com/arnehormann/sqlinternals/mysqlinternals"_ "github.com/go-sql-driver/mysql")var MYSQL map[string]string = map[string]string{"host": "127.0.0.1:3306","database": "","user": "","password": "","maxOpenConns": "0","maxIdleConns": "0",}type SqlConnPool struct {DriverName stringDataSourceName stringMaxOpenConns int64MaxIdleConns int64SqlDB *sql.DB // 串連池}var DB *SqlConnPoolfunc init() {dataSourceName := fmt.Sprintf("%s:%[email protected](%s)/%s", MYSQL["user"], MYSQL["password"], MYSQL["host"], MYSQL["database"])maxOpenConns, _ := strconv.ParseInt(MYSQL["maxOpenConns"], 10, 64)maxIdleConns, _ := strconv.ParseInt(MYSQL["maxIdleConns"], 10, 64)DB = &SqlConnPool{DriverName: "mysql",DataSourceName: dataSourceName,MaxOpenConns: maxOpenConns,MaxIdleConns: maxIdleConns,}if err := DB.open(); err != nil {panic("init db failed")}}// 封裝的串連池的方法func (p *SqlConnPool) open() error {var err errorp.SqlDB, err = sql.Open(p.DriverName, p.DataSourceName)p.SqlDB.SetMaxOpenConns(int(p.MaxOpenConns))p.SqlDB.SetMaxIdleConns(int(p.MaxIdleConns))return err}func (p *SqlConnPool) Close() error {return p.SqlDB.Close()}func (p *SqlConnPool) Query(queryStr string, args ...interface{}) ([]map[string]interface{}, error) {rows, err := p.SqlDB.Query(queryStr, args...)defer rows.Close()if err != nil {return []map[string]interface{}{}, err}// 返回屬性字典columns, err := mysqlinternals.Columns(rows)// 擷取欄位類型scanArgs := make([]interface{}, len(columns))values := make([]sql.RawBytes, len(columns))for i, _ := range values {scanArgs[i] = &values[i]}rowsMap := make([]map[string]interface{}, 0, 10)for rows.Next() {rows.Scan(scanArgs...)rowMap := make(map[string]interface{})for i, value := range values {rowMap[columns[i].Name()] = bytes2RealType(value, columns[i].MysqlType())}rowsMap = append(rowsMap, rowMap)}if err = rows.Err(); err != nil {return []map[string]interface{}{}, err}return rowsMap, nil}func (p *SqlConnPool) execute(sqlStr string, args ...interface{}) (sql.Result, error) {return p.SqlDB.Exec(sqlStr, args...)}func (p *SqlConnPool) Update(updateStr string, args ...interface{}) (int64, error) {result, err := p.execute(updateStr, args...)if err != nil {return 0, err}affect, err := result.RowsAffected()return affect, err}func (p *SqlConnPool) Insert(insertStr string, args ...interface{}) (int64, error) {result, err := p.execute(insertStr, args...)if err != nil {return 0, err}lastid, err := result.LastInsertId()return lastid, err}func (p *SqlConnPool) Delete(deleteStr string, args ...interface{}) (int64, error) {result, err := p.execute(deleteStr, args...)if err != nil {return 0, err}affect, err := result.RowsAffected()return affect, err}type SqlConnTransaction struct {SqlTx *sql.Tx // 單個事務串連}//// 開啟一個事務func (p *SqlConnPool) Begin() (*SqlConnTransaction, error) {var oneSqlConnTransaction = &SqlConnTransaction{}var err errorif pingErr := p.SqlDB.Ping(); pingErr == nil {oneSqlConnTransaction.SqlTx, err = p.SqlDB.Begin()}return oneSqlConnTransaction, err}// 封裝的單個事務串連的方法func (t *SqlConnTransaction) Rollback() error {return t.SqlTx.Rollback()}func (t *SqlConnTransaction) Commit() error {return t.SqlTx.Commit()}func (t *SqlConnTransaction) Query(queryStr string, args ...interface{}) ([]map[string]interface{}, error) {rows, err := t.SqlTx.Query(queryStr, args...)defer rows.Close()if err != nil {return []map[string]interface{}{}, err}// 返回屬性字典columns, err := mysqlinternals.Columns(rows)// 擷取欄位類型scanArgs := make([]interface{}, len(columns))values := make([]sql.RawBytes, len(columns))for i, _ := range values {scanArgs[i] = &values[i]}rowsMap := make([]map[string]interface{}, 0, 10)for rows.Next() {rows.Scan(scanArgs...)rowMap := make(map[string]interface{})for i, value := range values {rowMap[columns[i].Name()] = bytes2RealType(value, columns[i].MysqlType())}rowsMap = append(rowsMap, rowMap)}if err = rows.Err(); err != nil {return []map[string]interface{}{}, err}return rowsMap, nil}func (t *SqlConnTransaction) execute(sqlStr string, args ...interface{}) (sql.Result, error) {return t.SqlTx.Exec(sqlStr, args...)}func (t *SqlConnTransaction) Update(updateStr string, args ...interface{}) (int64, error) {result, err := t.execute(updateStr, args...)if err != nil {return 0, err}affect, err := result.RowsAffected()return affect, err}func (t *SqlConnTransaction) Insert(insertStr string, args ...interface{}) (int64, error) {result, err := t.execute(insertStr, args...)if err != nil {return 0, err}lastid, err := result.LastInsertId()return lastid, err}func (t *SqlConnTransaction) Delete(deleteStr string, args ...interface{}) (int64, error) {result, err := t.execute(deleteStr, args...)if err != nil {return 0, err}affect, err := result.RowsAffected()return affect, err}// othersfunc bytes2RealType(src []byte, columnType string) interface{} {srcStr := string(src)var result interface{}switch columnType {case "TINYINT":fallthroughcase "SMALLINT":fallthroughcase "INT":fallthroughcase "BIGINT":result, _ = strconv.ParseInt(srcStr, 10, 64)case "CHAR":fallthroughcase "VARCHAR":fallthroughcase "BLOB":fallthroughcase "TIMESTAMP":fallthroughcase "DATETIME":result = srcStrcase "FLOAT":fallthroughcase "DOUBLE":fallthroughcase "DECIMAL":result, _ = strconv.ParseFloat(srcStr, 64)default:result = nil}return result}
2 redis 串連池代碼
package libimport ("strconv""time""github.com/garyburd/redigo/redis")var REDIS map[string]string = map[string]string{"host": "127.0.0.1:6379","database": "0","password": "","maxOpenConns": "0","maxIdleConns": "0",}var Cache *RedisConnPooltype RedisConnPool struct {redisPool *redis.Pool}func init() {Cache = &RedisConnPool{}maxOpenConns, _ := strconv.ParseInt(REDIS["maxOpenConns"], 10, 64)maxIdleConns, _ := strconv.ParseInt(REDIS["maxIdleConns"], 10, 64)database, _ := strconv.ParseInt(REDIS["database"], 10, 64)Cache.redisPool = newPool(REDIS["host"], REDIS["password"], int(database), int(maxOpenConns), int(maxIdleConns))if Cache.redisPool == nil {panic("init redis failed!")}}func newPool(server, password string, database, maxOpenConns, maxIdleConns int) *redis.Pool {return &redis.Pool{MaxActive: maxOpenConns, // max number of connectionsMaxIdle: maxIdleConns,IdleTimeout: 10 * time.Second,Dial: func() (redis.Conn, error) {c, err := redis.Dial("tcp", server)if err != nil {return nil, err}if _, err := c.Do("AUTH", password); err != nil {c.Close()return nil, err}if _, err := c.Do("select", database); err != nil {c.Close()return nil, err}return c, err},TestOnBorrow: func(c redis.Conn, t time.Time) error {_, err := c.Do("PING")return err},}}// 關閉串連池func (p *RedisConnPool) Close() error {err := p.redisPool.Close()return err}// 當前某一個資料庫,執行命令func (p *RedisConnPool) Do(command string, args ...interface{}) (interface{}, error) {conn := p.redisPool.Get()defer conn.Close()return conn.Do(command, args...)}//// String(字串)func (p *RedisConnPool) SetString(key string, value interface{}) (interface{}, error) {conn := p.redisPool.Get()defer conn.Close()return conn.Do("SET", key, value)}func (p *RedisConnPool) GetString(key string) (string, error) {// 從串連池裡面獲得一個串連conn := p.redisPool.Get()// 串連完關閉,其實沒有關閉,是放回池裡,也就是隊列裡面,等待下一個重用defer conn.Close()return redis.String(conn.Do("GET", key))}func (p *RedisConnPool) GetBytes(key string) ([]byte, error) {conn := p.redisPool.Get()defer conn.Close()return redis.Bytes(conn.Do("GET", key))}func (p *RedisConnPool) GetInt(key string) (int, error) {conn := p.redisPool.Get()defer conn.Close()return redis.Int(conn.Do("GET", key))}func (p *RedisConnPool) GetInt64(key string) (int64, error) {conn := p.redisPool.Get()defer conn.Close()return redis.Int64(conn.Do("GET", key))}//// Key(鍵)func (p *RedisConnPool) DelKey(key string) (interface{}, error) {conn := p.redisPool.Get()defer conn.Close()return conn.Do("DEL", key)}func (p *RedisConnPool) ExpireKey(key string, seconds int64) (interface{}, error) {conn := p.redisPool.Get()defer conn.Close()return conn.Do("EXPIRE", key, seconds)}func (p *RedisConnPool) Keys(pattern string) ([]string, error) {conn := p.redisPool.Get()defer conn.Close()return redis.Strings(conn.Do("KEYS", pattern))}func (p *RedisConnPool) KeysByteSlices(pattern string) ([][]byte, error) {conn := p.redisPool.Get()defer conn.Close()return redis.ByteSlices(conn.Do("KEYS", pattern))}//// Hash(雜湊表)func (p *RedisConnPool) SetHashMap(key string, fieldValue map[string]interface{}) (interface{}, error) {conn := p.redisPool.Get()defer conn.Close()return conn.Do("HMSET", redis.Args{}.Add(key).AddFlat(fieldValue)...)}func (p *RedisConnPool) GetHashMapString(key string) (map[string]string, error) {conn := p.redisPool.Get()defer conn.Close()return redis.StringMap(conn.Do("HGETALL", key))}func (p *RedisConnPool) GetHashMapInt(key string) (map[string]int, error) {conn := p.redisPool.Get()defer conn.Close()return redis.IntMap(conn.Do("HGETALL", key))}func (p *RedisConnPool) GetHashMapInt64(key string) (map[string]int64, error) {conn := p.redisPool.Get()defer conn.Close()return redis.Int64Map(conn.Do("HGETALL", key))}
redis mysql 串連池 之 golang 實現