数据库
mongo 基本操作
mgo 连接池
package main
import (
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
var (
globalSess *mgo.Session
mongoURL string
)
func init() {
// init mongoURL
// ...
var err error
// 不要使用 := 否则全局 globalSess 无法初始化
globalSess, err = GetDBSession()
if err != nil {
panic(err)
}
}
// GetSession get the db session
func GetDBSession() (*mgo.Session, error) {
globalMgoSession, err := mgo.DialWithTimeout(mongoURL, 10*time.Second)
if err != nil {
return nil, err
}
globalMgoSession.SetMode(mgo.Monotonic, true)
//default is 4096
globalMgoSession.SetPoolLimit(1000)
return globalMgoSession, nil
}
func GetCloneSess() *mgo.Session {
return globalSess.Clone()
}
func GetCopySess() *mgo.Session {
return globalSess.Copy()
}
mgo 基本操作: 增删改查、聚合
// mgotest project main.go
package main
import (
"fmt"
"time"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
type User struct {
Id bson.ObjectId `bson:"_id"`
Username string `bson:"name"`
Pass string `bson:"pass"`
Regtime int64 `bson:"regtime"`
Interests []string `bson:"interests"`
}
const URL string = "127.0.0.1:27017"
var c *mgo.Collection
var session *mgo.Session
func (user User) ToString() string {
return fmt.Sprintf("%#v", user)
}
func init() {
session, _ = mgo.Dial(URL)
// 切换到数据库
db := session.DB("blog")
// 切换到collection
c = db.C("mgotest")
}
// 新增数据
func add() {
// defer session.Close()
stu1 := new(User)
stu1.Id = bson.NewObjectId()
stu1.Username = "stu1_name"
stu1.Pass = "stu1_pass"
stu1.Regtime = time.Now().Unix()
stu1.Interests = []string{"象棋", "游泳", "跑步"}
err := c.Insert(stu1)
if err == nil {
fmt.Println("插入成功")
} else {
fmt.Println(err.Error())
defer panic(err)
}
}
//查询
func find() {
// defer session.Close()
var users []User
// c.Find(nil).All(&users)
c.Find(bson.M{"name": "stu1_name"}).All(&users)
for _, value := range users {
fmt.Println(value.ToString())
}
// 根据ObjectId进行查询
idStr := "577fb2d1cde67307e819133d"
objectId := bson.ObjectIdHex(idStr)
user := new(User)
c.Find(bson.M{"_id": objectId}).One(user)
fmt.Println(user)
}
// 根据id进行修改
func update() {
interests := []string{"象棋", "游泳", "跑步"}
err := c.Update(bson.M{"_id": bson.ObjectIdHex("577fb2d1cde67307e819133d")}, bson.M{"$set": bson.M{
"name": "修改后的name",
"pass": "修改后的pass",
"regtime": time.Now().Unix(),
"interests": interests,
}})
if err != nil {
fmt.Println("修改失败")
} else {
fmt.Println("修改成功")
}
}
// 删除
func del() {
err := c.Remove(bson.M{"_id": bson.ObjectIdHex("577fb2d1cde67307e819133d")})
if err != nil {
fmt.Println("删除失败" + err.Error())
} else {
fmt.Println("删除成功")
}
}
// 聚合
func pipe() {
pipe := c.Pipe([]bson.M{
bson.M{
"$group": bson.M{
"_id": "null",
"user_num": bson.M{
"$sum": 1,
},
},
}})
res := bson.M{}
err := pipe.One(&res)
if err != nil {
fmt.Println(err)
}
fmt.Println(res)
}
func main() {
add()
find()
update()
del()
pipe()
}
redis
redisgo 连接池以及基本操作封装
package main
import (
"github.com/garyburd/redigo/redis"
)
// redis controller
type RedisDBCntlr struct {
conn redis.Conn
}
var globalRedisPool *redis.Pool
var redisURL string
var redisPW string
func init() {
// init redisURL and redisPW
// ...
globalRedisPool = GetRedisPool()
}
// GetRedisPool get the client pool of redis
func GetRedisPool() *redis.Pool {
pool := &redis.Pool{ // 实例化一个连接池
MaxIdle: 16, // 最初的连接数量
// MaxActive:1000000, //最大连接数量
MaxActive: 0, // 连接池最大连接数量,不确定可以用0(0表示自动定义),按需分配
IdleTimeout: 300, // 连接关闭时间 300秒 (300秒不使用自动关闭)
Dial: func() (redis.Conn, error) { // 要连接的redis数据库
conn, err := redis.Dial("tcp", redisURL)
if err != nil {
return nil, err
}
if redisPW != "" {
_, err = conn.Do("AUTH", redisPW)
}
return conn, err
},
}
return pool
}
/********************************************* RedisDBCntlr *******************************************/
func NewRedisDBCntlr() *RedisDBCntlr {
return &RedisDBCntlr{
conn: globalRedisPool.Get(),
}
}
func (this *RedisDBCntlr) Close() {
this.conn.Close()
}
func (this *RedisDBCntlr) Send(commandName string, args ...interface{}) error {
return this.conn.Send(commandName, args)
}
func (this *RedisDBCntlr) Do(commandName string, args ...interface{}) (interface{}, error) {
return this.conn.Do(commandName, args)
}
func (this *RedisDBCntlr) GET(key string) (string, error) {
return redis.String(this.conn.Do("GET", key))
}
func (this *RedisDBCntlr) SET(key, value string) (interface{}, error) {
return this.conn.Do("SET", key, value)
}
func (this *RedisDBCntlr) SETEX(key string, expire int64, value string) (interface{}, error) {
return this.conn.Do("SETEX", key, expire, value)
}
func (this *RedisDBCntlr) INCR(key string) (interface{}, error) {
return this.conn.Do("INCR", key)
}
func (this *RedisDBCntlr) INCRBY(key string, num int) (interface{}, error) {
return this.conn.Do("INCRBY", key, num)
}
func (this *RedisDBCntlr) KEYS(keyPattern string) ([]string, error) {
return redis.Strings(this.conn.Do("KEYS", keyPattern))
}
func (this *RedisDBCntlr) DEL(keys ...interface{}) (interface{}, error) {
return this.conn.Do("DEL", keys...)
}
func (this *RedisDBCntlr) HGETALL(key string) (map[string]string, error) {
return redis.StringMap(this.conn.Do("HGETALL", key))
}
func (this *RedisDBCntlr) HMGET(key string, fields ...interface{}) (map[string]string, error) {
args := []interface{}{key}
args = append(args, fields...)
return redis.StringMap(this.conn.Do("HMGET", args...))
}
func (this *RedisDBCntlr) HMSET(key string, fields ...interface{}) (map[string]string, error) {
args := []interface{}{key}
args = append(args, fields...)
return redis.StringMap(this.conn.Do("HMSET", args...))
}
func (this *RedisDBCntlr) SISMEMBER(key, value string) (bool, error) {
return redis.Bool(this.conn.Do("SISMEMBER", key, value))
}
func (this *RedisDBCntlr) SMEMBERS(key string) ([]string, error) {
return redis.Strings(this.conn.Do("SMEMBERS", key))
}
func (this *RedisDBCntlr) SADD(key string, members ...interface{}) (interface{}, error) {
args := []interface{}{key}
args = append(args, members...)
return this.conn.Do("SADD", args)
}
func (this *RedisDBCntlr) SCARD(key string) (int, error) {
return redis.Int(this.conn.Do("SCARD", key))
}
func (this *RedisDBCntlr) LRANGE(key string, start, end int) ([]string, error) {
return redis.Strings(this.conn.Do("LRANGE", key, start, end))
}
func (this *RedisDBCntlr) RPUSH(key string, params ...interface{}) (interface{}, error) {
args := []interface{}{key}
args = append(args, params...)
return this.conn.Do("RPUSH", args...)
}
func (this *RedisDBCntlr) LTRIM(key string, start, end int) (interface{}, error) {
return this.conn.Do("LTRIM", key, start, end)
}
func (this *RedisDBCntlr) ZREMRANGEBYRANK(key string, start, end int) (interface{}, error) {
return this.conn.Do("ZREMRANGEBYRANK", key, start, end)
}
func (this RedisDBCntlr) ZINCRBY(key string, increment int, member string) (interface{}, error) {
return this.conn.Do("ZINCRBY", key, increment, member)
}
func (this RedisDBCntlr) ZRANGE(key string, params ...interface{}) (map[string]string, error) {
args := []interface{}{key}
args = append(args, params...)
return redis.StringMap(this.conn.Do("ZRANGE", args...))
}
func (this RedisDBCntlr) ZADD(key string, params ...interface{}) (interface{}, error) {
args := []interface{}{key}
args = append(args, params...)
return this.conn.Do("ZADD", args...)
}
func (this RedisDBCntlr) EXPIRE(key string, seconds int64) (interface{}, error) {
return this.conn.Do("EXPIRE", key, seconds)
}
redisgo 基本操作
package main
import (
"fmt"
"github.com/garyburd/redigo/redis"
)
func main() {
conn, err := redis.Dial("tcp", "127.0.0.1:6379")
if err != nil {
return
}
defer conn.Close()
// 如果设置了密码的话
conn.Do("AUTH", "your password")
allCommentNum, _ := redis.Int(conn.Do("GET", "shop/comment/all_num"))
fmt.Println(allCommentNum)
// 事务开始
conn.Send("MULTI")
// ...
c.Send("INCR", "foo")
c.Send("INCR", "bar")
// 事务结束
conn.Do("EXEC")
}
Go 基本库
strconv
i, err := strconv.Atoi("-42")
s := strconv.Itoa(-42)
b, err := strconv.ParseBool("true")
f, err := strconv.ParseFloat("3.1415", 64)
i, err := strconv.ParseInt("-42", 10, 64)
u, err := strconv.ParseUint("42", 10, 64)
s := "2147483647" // biggest int32
i64, err := strconv.ParseInt(s, 10, 32)
i := int32(i64)
s := strconv.FormatBool(true)
s := strconv.FormatFloat(3.1415, 'E', -1, 64)
s := strconv.FormatInt(-42, 16)
s := strconv.FormatUint(42, 16)
q := Quote("Hello, 世界")
// "Hello, 世界"
q := QuoteToASCII("Hello, 世界")
// "Hello, \u4e16\u754c"
strings
// 子串substr在s中,返回true
func Contains(s, substr string) bool
// chars中任何一个Unicode代码点在s中,返回true
func ContainsAny(s, chars string) bool
// Unicode代码点r在s中,返回true
func ContainsRune(s string, r rune) bool
//返回子串sep在字符串s中第一次出现的索引值,不在的话返回-1.
func Index(s, sep string) int
//chars中任何一个Unicode代码点在s中首次出现的位置,不存在返回-1
func IndexAny(s, chars string) int
//查找字符 c 在 s 中第一次出现的位置,其中 c 满足 f(c) 返回 true
func IndexFunc(s string, f func(rune) bool) int //rune类型是int32别名,UTF-8字符格式编码。
//返回字符c在s中第一次出现的位置
func IndexByte(s string, c byte) int //byte是字节类型
// Unicode 代码点 r 在 s 中第一次出现的位置
func IndexRune(s string, r rune) int
//查找最后一次出现的位置
func LastIndex(s, sep string) int
func LastIndexByte(s string, c byte) int
func LastIndexAny(s, chars string) int
func LastIndexFunc(s string, f func(rune) bool) int
func Count(s, sep string) int //子串在s字符串中出现的次数
func Split(s, sep string) []string
func SplitAfter(s, sep string) []string
func SplitN(s, sep string, n int) []string
func SplitAfterN(s, sep string, n int) []string
func Join(a []string, sep string) string
// 用 new 替换 s 中的 old,一共替换 n 个。
// 如果 n < 0,则不限制替换次数,即全部替换
func Replace(s, old, new string, n int) string
坑
append 修改原数据问题
看如下代码:
代码功能:删除slice中的一个元素
func main() {
wordList := []string{"a", "b", "c"}
newWordList := append(wordList[:0], wordList[1:]...)
fmt.Println(wordList) // [b c c]
fmt.Println(newWordList) // [b c]
}
会发现 wordList 变为了 [b c c]!
由于 append 会在前一个切片的基础上追加,使用的是前一个切片的地址,也就造成了将原数据覆盖的情况
修正如下:
func main() {
wordList := []string{"a", "b", "c"}
newWordList := append([]string{}, wordList[:0]...)
newWordList = append(newWordList, wordList[1:]...)
fmt.Println(wordList) // [b c c]
fmt.Println(newWordList) // [b c]
}