数据库

mongo 基本操作

mgo 连接池

  1. package main
  2. import (
  3. "gopkg.in/mgo.v2"
  4. "gopkg.in/mgo.v2/bson"
  5. )
  6. var (
  7. globalSess *mgo.Session
  8. mongoURL string
  9. )
  10. func init() {
  11. // init mongoURL
  12. // ...
  13. var err error
  14. // 不要使用 := 否则全局 globalSess 无法初始化
  15. globalSess, err = GetDBSession()
  16. if err != nil {
  17. panic(err)
  18. }
  19. }
  20. // GetSession get the db session
  21. func GetDBSession() (*mgo.Session, error) {
  22. globalMgoSession, err := mgo.DialWithTimeout(mongoURL, 10*time.Second)
  23. if err != nil {
  24. return nil, err
  25. }
  26. globalMgoSession.SetMode(mgo.Monotonic, true)
  27. //default is 4096
  28. globalMgoSession.SetPoolLimit(1000)
  29. return globalMgoSession, nil
  30. }
  31. func GetCloneSess() *mgo.Session {
  32. return globalSess.Clone()
  33. }
  34. func GetCopySess() *mgo.Session {
  35. return globalSess.Copy()
  36. }

mgo 基本操作: 增删改查、聚合

  1. // mgotest project main.go
  2. package main
  3. import (
  4. "fmt"
  5. "time"
  6. "gopkg.in/mgo.v2"
  7. "gopkg.in/mgo.v2/bson"
  8. )
  9. type User struct {
  10. Id bson.ObjectId `bson:"_id"`
  11. Username string `bson:"name"`
  12. Pass string `bson:"pass"`
  13. Regtime int64 `bson:"regtime"`
  14. Interests []string `bson:"interests"`
  15. }
  16. const URL string = "127.0.0.1:27017"
  17. var c *mgo.Collection
  18. var session *mgo.Session
  19. func (user User) ToString() string {
  20. return fmt.Sprintf("%#v", user)
  21. }
  22. func init() {
  23. session, _ = mgo.Dial(URL)
  24. // 切换到数据库
  25. db := session.DB("blog")
  26. // 切换到collection
  27. c = db.C("mgotest")
  28. }
  29. // 新增数据
  30. func add() {
  31. // defer session.Close()
  32. stu1 := new(User)
  33. stu1.Id = bson.NewObjectId()
  34. stu1.Username = "stu1_name"
  35. stu1.Pass = "stu1_pass"
  36. stu1.Regtime = time.Now().Unix()
  37. stu1.Interests = []string{"象棋", "游泳", "跑步"}
  38. err := c.Insert(stu1)
  39. if err == nil {
  40. fmt.Println("插入成功")
  41. } else {
  42. fmt.Println(err.Error())
  43. defer panic(err)
  44. }
  45. }
  46. //查询
  47. func find() {
  48. // defer session.Close()
  49. var users []User
  50. // c.Find(nil).All(&users)
  51. c.Find(bson.M{"name": "stu1_name"}).All(&users)
  52. for _, value := range users {
  53. fmt.Println(value.ToString())
  54. }
  55. // 根据ObjectId进行查询
  56. idStr := "577fb2d1cde67307e819133d"
  57. objectId := bson.ObjectIdHex(idStr)
  58. user := new(User)
  59. c.Find(bson.M{"_id": objectId}).One(user)
  60. fmt.Println(user)
  61. }
  62. // 根据id进行修改
  63. func update() {
  64. interests := []string{"象棋", "游泳", "跑步"}
  65. err := c.Update(bson.M{"_id": bson.ObjectIdHex("577fb2d1cde67307e819133d")}, bson.M{"$set": bson.M{
  66. "name": "修改后的name",
  67. "pass": "修改后的pass",
  68. "regtime": time.Now().Unix(),
  69. "interests": interests,
  70. }})
  71. if err != nil {
  72. fmt.Println("修改失败")
  73. } else {
  74. fmt.Println("修改成功")
  75. }
  76. }
  77. // 删除
  78. func del() {
  79. err := c.Remove(bson.M{"_id": bson.ObjectIdHex("577fb2d1cde67307e819133d")})
  80. if err != nil {
  81. fmt.Println("删除失败" + err.Error())
  82. } else {
  83. fmt.Println("删除成功")
  84. }
  85. }
  86. // 聚合
  87. func pipe() {
  88. pipe := c.Pipe([]bson.M{
  89. bson.M{
  90. "$group": bson.M{
  91. "_id": "null",
  92. "user_num": bson.M{
  93. "$sum": 1,
  94. },
  95. },
  96. }})
  97. res := bson.M{}
  98. err := pipe.One(&res)
  99. if err != nil {
  100. fmt.Println(err)
  101. }
  102. fmt.Println(res)
  103. }
  104. func main() {
  105. add()
  106. find()
  107. update()
  108. del()
  109. pipe()
  110. }

redis

redisgo 连接池以及基本操作封装

  1. package main
  2. import (
  3. "github.com/garyburd/redigo/redis"
  4. )
  5. // redis controller
  6. type RedisDBCntlr struct {
  7. conn redis.Conn
  8. }
  9. var globalRedisPool *redis.Pool
  10. var redisURL string
  11. var redisPW string
  12. func init() {
  13. // init redisURL and redisPW
  14. // ...
  15. globalRedisPool = GetRedisPool()
  16. }
  17. // GetRedisPool get the client pool of redis
  18. func GetRedisPool() *redis.Pool {
  19. pool := &redis.Pool{ // 实例化一个连接池
  20. MaxIdle: 16, // 最初的连接数量
  21. // MaxActive:1000000, //最大连接数量
  22. MaxActive: 0, // 连接池最大连接数量,不确定可以用0(0表示自动定义),按需分配
  23. IdleTimeout: 300, // 连接关闭时间 300秒 (300秒不使用自动关闭)
  24. Dial: func() (redis.Conn, error) { // 要连接的redis数据库
  25. conn, err := redis.Dial("tcp", redisURL)
  26. if err != nil {
  27. return nil, err
  28. }
  29. if redisPW != "" {
  30. _, err = conn.Do("AUTH", redisPW)
  31. }
  32. return conn, err
  33. },
  34. }
  35. return pool
  36. }
  37. /********************************************* RedisDBCntlr *******************************************/
  38. func NewRedisDBCntlr() *RedisDBCntlr {
  39. return &RedisDBCntlr{
  40. conn: globalRedisPool.Get(),
  41. }
  42. }
  43. func (this *RedisDBCntlr) Close() {
  44. this.conn.Close()
  45. }
  46. func (this *RedisDBCntlr) Send(commandName string, args ...interface{}) error {
  47. return this.conn.Send(commandName, args)
  48. }
  49. func (this *RedisDBCntlr) Do(commandName string, args ...interface{}) (interface{}, error) {
  50. return this.conn.Do(commandName, args)
  51. }
  52. func (this *RedisDBCntlr) GET(key string) (string, error) {
  53. return redis.String(this.conn.Do("GET", key))
  54. }
  55. func (this *RedisDBCntlr) SET(key, value string) (interface{}, error) {
  56. return this.conn.Do("SET", key, value)
  57. }
  58. func (this *RedisDBCntlr) SETEX(key string, expire int64, value string) (interface{}, error) {
  59. return this.conn.Do("SETEX", key, expire, value)
  60. }
  61. func (this *RedisDBCntlr) INCR(key string) (interface{}, error) {
  62. return this.conn.Do("INCR", key)
  63. }
  64. func (this *RedisDBCntlr) INCRBY(key string, num int) (interface{}, error) {
  65. return this.conn.Do("INCRBY", key, num)
  66. }
  67. func (this *RedisDBCntlr) KEYS(keyPattern string) ([]string, error) {
  68. return redis.Strings(this.conn.Do("KEYS", keyPattern))
  69. }
  70. func (this *RedisDBCntlr) DEL(keys ...interface{}) (interface{}, error) {
  71. return this.conn.Do("DEL", keys...)
  72. }
  73. func (this *RedisDBCntlr) HGETALL(key string) (map[string]string, error) {
  74. return redis.StringMap(this.conn.Do("HGETALL", key))
  75. }
  76. func (this *RedisDBCntlr) HMGET(key string, fields ...interface{}) (map[string]string, error) {
  77. args := []interface{}{key}
  78. args = append(args, fields...)
  79. return redis.StringMap(this.conn.Do("HMGET", args...))
  80. }
  81. func (this *RedisDBCntlr) HMSET(key string, fields ...interface{}) (map[string]string, error) {
  82. args := []interface{}{key}
  83. args = append(args, fields...)
  84. return redis.StringMap(this.conn.Do("HMSET", args...))
  85. }
  86. func (this *RedisDBCntlr) SISMEMBER(key, value string) (bool, error) {
  87. return redis.Bool(this.conn.Do("SISMEMBER", key, value))
  88. }
  89. func (this *RedisDBCntlr) SMEMBERS(key string) ([]string, error) {
  90. return redis.Strings(this.conn.Do("SMEMBERS", key))
  91. }
  92. func (this *RedisDBCntlr) SADD(key string, members ...interface{}) (interface{}, error) {
  93. args := []interface{}{key}
  94. args = append(args, members...)
  95. return this.conn.Do("SADD", args)
  96. }
  97. func (this *RedisDBCntlr) SCARD(key string) (int, error) {
  98. return redis.Int(this.conn.Do("SCARD", key))
  99. }
  100. func (this *RedisDBCntlr) LRANGE(key string, start, end int) ([]string, error) {
  101. return redis.Strings(this.conn.Do("LRANGE", key, start, end))
  102. }
  103. func (this *RedisDBCntlr) RPUSH(key string, params ...interface{}) (interface{}, error) {
  104. args := []interface{}{key}
  105. args = append(args, params...)
  106. return this.conn.Do("RPUSH", args...)
  107. }
  108. func (this *RedisDBCntlr) LTRIM(key string, start, end int) (interface{}, error) {
  109. return this.conn.Do("LTRIM", key, start, end)
  110. }
  111. func (this *RedisDBCntlr) ZREMRANGEBYRANK(key string, start, end int) (interface{}, error) {
  112. return this.conn.Do("ZREMRANGEBYRANK", key, start, end)
  113. }
  114. func (this RedisDBCntlr) ZINCRBY(key string, increment int, member string) (interface{}, error) {
  115. return this.conn.Do("ZINCRBY", key, increment, member)
  116. }
  117. func (this RedisDBCntlr) ZRANGE(key string, params ...interface{}) (map[string]string, error) {
  118. args := []interface{}{key}
  119. args = append(args, params...)
  120. return redis.StringMap(this.conn.Do("ZRANGE", args...))
  121. }
  122. func (this RedisDBCntlr) ZADD(key string, params ...interface{}) (interface{}, error) {
  123. args := []interface{}{key}
  124. args = append(args, params...)
  125. return this.conn.Do("ZADD", args...)
  126. }
  127. func (this RedisDBCntlr) EXPIRE(key string, seconds int64) (interface{}, error) {
  128. return this.conn.Do("EXPIRE", key, seconds)
  129. }

redisgo 基本操作

  1. package main
  2. import (
  3. "fmt"
  4. "github.com/garyburd/redigo/redis"
  5. )
  6. func main() {
  7. conn, err := redis.Dial("tcp", "127.0.0.1:6379")
  8. if err != nil {
  9. return
  10. }
  11. defer conn.Close()
  12. // 如果设置了密码的话
  13. conn.Do("AUTH", "your password")
  14. allCommentNum, _ := redis.Int(conn.Do("GET", "shop/comment/all_num"))
  15. fmt.Println(allCommentNum)
  16. // 事务开始
  17. conn.Send("MULTI")
  18. // ...
  19. c.Send("INCR", "foo")
  20. c.Send("INCR", "bar")
  21. // 事务结束
  22. conn.Do("EXEC")
  23. }

Go 基本库

strconv

  1. i, err := strconv.Atoi("-42")
  2. s := strconv.Itoa(-42)
  3. b, err := strconv.ParseBool("true")
  4. f, err := strconv.ParseFloat("3.1415", 64)
  5. i, err := strconv.ParseInt("-42", 10, 64)
  6. u, err := strconv.ParseUint("42", 10, 64)
  7. s := "2147483647" // biggest int32
  8. i64, err := strconv.ParseInt(s, 10, 32)
  9. i := int32(i64)
  10. s := strconv.FormatBool(true)
  11. s := strconv.FormatFloat(3.1415, 'E', -1, 64)
  12. s := strconv.FormatInt(-42, 16)
  13. s := strconv.FormatUint(42, 16)
  14. q := Quote("Hello, 世界")
  15. // "Hello, 世界"
  16. q := QuoteToASCII("Hello, 世界")
  17. // "Hello, \u4e16\u754c"

strings

  1. // 子串substr在s中,返回true
  2. func Contains(s, substr string) bool
  3. // chars中任何一个Unicode代码点在s中,返回true
  4. func ContainsAny(s, chars string) bool
  5. // Unicode代码点r在s中,返回true
  6. func ContainsRune(s string, r rune) bool
  7. //返回子串sep在字符串s中第一次出现的索引值,不在的话返回-1.
  8. func Index(s, sep string) int
  9. //chars中任何一个Unicode代码点在s中首次出现的位置,不存在返回-1
  10. func IndexAny(s, chars string) int
  11. //查找字符 c 在 s 中第一次出现的位置,其中 c 满足 f(c) 返回 true
  12. func IndexFunc(s string, f func(rune) bool) int //rune类型是int32别名,UTF-8字符格式编码。
  13. //返回字符c在s中第一次出现的位置
  14. func IndexByte(s string, c byte) int //byte是字节类型
  15. // Unicode 代码点 r 在 s 中第一次出现的位置
  16. func IndexRune(s string, r rune) int
  17. //查找最后一次出现的位置
  18. func LastIndex(s, sep string) int
  19. func LastIndexByte(s string, c byte) int
  20. func LastIndexAny(s, chars string) int
  21. func LastIndexFunc(s string, f func(rune) bool) int
  22. func Count(s, sep string) int //子串在s字符串中出现的次数
  23. func Split(s, sep string) []string
  24. func SplitAfter(s, sep string) []string
  25. func SplitN(s, sep string, n int) []string
  26. func SplitAfterN(s, sep string, n int) []string
  27. func Join(a []string, sep string) string
  28. // 用 new 替换 s 中的 old,一共替换 n 个。
  29. // 如果 n < 0,则不限制替换次数,即全部替换
  30. func Replace(s, old, new string, n int) string

append 修改原数据问题

看如下代码:
代码功能:删除slice中的一个元素

  1. func main() {
  2. wordList := []string{"a", "b", "c"}
  3. newWordList := append(wordList[:0], wordList[1:]...)
  4. fmt.Println(wordList) // [b c c]
  5. fmt.Println(newWordList) // [b c]
  6. }

会发现 wordList 变为了 [b c c]!
由于 append 会在前一个切片的基础上追加,使用的是前一个切片的地址,也就造成了将原数据覆盖的情况

修正如下:

  1. func main() {
  2. wordList := []string{"a", "b", "c"}
  3. newWordList := append([]string{}, wordList[:0]...)
  4. newWordList = append(newWordList, wordList[1:]...)
  5. fmt.Println(wordList) // [b c c]
  6. fmt.Println(newWordList) // [b c]
  7. }