beego 操作redis(第三篇)

model目录下新建redis.go

var Pool *redis.Pool //创建redis连接池

func init()  {
	Pool = &redis.Pool{ //实例化一个连接池
		MaxIdle:16,    //最初的连接数量
		MaxActive:0,    //连接池最大连接数量,不确定可以用0(0表示自动定义),按需分配
		IdleTimeout:300,    //连接关闭时间 300秒 (300秒不使用自动关闭)
		Dial: func() (redis.Conn ,error){     //要连接的redis数据库
			return redis.Dial("tcp","127.0.0.1:6379", redis.DialPassword(""), redis.DialDatabase(1))
		},
	}
	c := Pool.Get()
	defer c.Close()
}
一.String: 字符串

1.set

	c := models.Pool.Get()
	_, err := c.Do("SET", "name", "name")
	if err != nil {
		fmt.Println("redis set failed:", err)
	}

2.get

	username, err := redis.String(c.Do("GET", "name"))
	if err != nil {
		fmt.Println("redis get failed:", err)
	} else {
		fmt.Printf("Get mykey: %v \n", username)
	}

3.批量set

	_, err = c.Do("MSET", "name", "ljp","sex","male")
	if err != nil {
		fmt.Println("redis set failed:", err)
	}

4.批量get

	reply, err := redis.Values(c.Do("MGET", "name", "sex"))
	if err != nil {
		fmt.Printf("patch get name & sex error \n。")
	} else {
		var name string
		var sex string
		_, err := redis.Scan(reply, &name, &sex);
		if err != nil {
			fmt.Printf("Scan error \n。")
		} else {
			fmt.Printf("The name is %v, sex is %v \n", name, sex)
		}
	}

5.判断key是否存在

	is_key_exit, err := redis.Bool(c.Do("EXISTS", "name"))
	if err != nil {
		fmt.Println("error:", err)
	} else {
		fmt.Printf("Is name key exists ? : %v \n", is_key_exit)
	}

6.读写json到redis转换

 key := "profile"
    imap := map[string]string{"name": "duncanwang", "sex": "male","mobile":"13671927788"}
    value, _ := json.Marshal(imap)

    n, err := c.Do("SETNX", key, value)
    if err != nil {
        fmt.Println(err)
    }
    if n == int64(1) {
        fmt.Println("set Json key success。")
    }

    var imapGet map[string]string

    valueGet, err := redis.Bytes(c.Do("GET", key))
    if err != nil {
        fmt.Println(err)
    }

    errShal := json.Unmarshal(valueGet, &imapGet)
    if errShal != nil {
        fmt.Println(err)
    }
    fmt.Println(imapGet["name"])
    fmt.Println(imapGet["sex"])
    fmt.Println(imapGet["mobile"])
}
二.Hash: 散列
hash常见命令
hset(key, field, value):向名称为key的hash中添加元素field
hget(key, field):返回名称为key的hash中field对应的value
hmget(key, (fields)):返回名称为key的hash中field i对应的value
hmset(key, (fields)):向名称为key的hash中添加元素field
hincrby(key, field, integer):将名称为key的hash中field的value增加integer
hexists(key, field):名称为key的hash中是否存在键为field的域
hdel(key, field):删除名称为key的hash中键为field的域
hlen(key):返回名称为key的hash中元素个数
hkeys(key):返回名称为key的hash中所有键
hvals(key):返回名称为key的hash中所有键对应的value
hgetall(key):返回名称为key的hash中所有的键(field)及其对应的value

hset示例

_, err = c.Do("hset", "myhash", "bike1", "mobike")
if err != nil {
    fmt.Println("haset failed", err.Error())
}

hget示例

res, err := c.Do("hget", "myhash", "bike1")
fmt.Println(reflect.TypeOf(res))
if err != nil {
    fmt.Println("hget failed", err.Error())
} else {
    fmt.Printf("hget value :%s\n", res.([]byte))
}

hmset/hmget

_, err = c.Do("hmset", "myhash", "bike2", "bluegogo", "bike3", "xiaoming", "bike4", "xiaolan")
if err != nil {
    fmt.Println("hmset error", err.Error())
} else {
    value, err := redis.Values(c.Do("hmget", "myhash", "bike1", "bike2", "bike3", "bike4"))
    if err != nil {
        fmt.Println("hmget failed", err.Error())
    } else {
        fmt.Printf("hmget myhash's element :")
        for _, v := range value {
            fmt.Printf("%s ", v.([]byte))
        }
        fmt.Printf("\n")
    }
}

hincrby

_, err = c.Do("hmset", "myhash", "bike2", "bluegogo", "bike3", "xiaoming", "bike4", "xiaolan")
if err != nil {
    fmt.Println("hmset error", err.Error())
} else {
    value, err := redis.Values(c.Do("hmget", "myhash", "bike1", "bike2", "bike3", "bike4"))
    if err != nil {
        fmt.Println("hmget failed", err.Error())
    } else {
        fmt.Printf("hmget myhash's element :")
        for _, v := range value {
            fmt.Printf("%s ", v.([]byte))
        }
        fmt.Printf("\n")
    }
}

hexists

isExist, err := c.Do("hexists", "myhash", "tmpnum")
if err != nil {
    fmt.Println("hexist failed", err.Error())
} else {
    fmt.Println("exist or not:", isExist)
}

hlen

ilen, err := c.Do("hlen", "myhash")
if err != nil {
    fmt.Println("hlen failed", err.Error())
} else {
    fmt.Println("myhash's len is :", ilen)
}

hkeys

resKeys, err := redis.Values(c.Do("hkeys", "myhash"))
if err != nil {
    fmt.Println("hkeys failed", err.Error())
} else {
    fmt.Printf("myhash's keys is :")
    for _, v := range resKeys {
        fmt.Printf("%s ", v.([]byte))
    }
    fmt.Println()
}

hvals

resValues, err := redis.Values(c.Do("hvals", "myhash"))
if err != nil {
    fmt.Println("hvals failed", err.Error())
} else {
    fmt.Printf("myhash's values is:")
    for _, v := range resValues {
        fmt.Printf("%s ", v.([]byte))
    }
    fmt.Println()
}

hdel

_, err = c.Do("HDEL", "myhash", "tmpnum")
if err != nil {
    fmt.Println("hdel failed", err.Error())
}

hgetall

result, err := redis.Values(c.Do("hgetall", "myhash"))
if err != nil {
    fmt.Println("hgetall failed", err.Error())
} else {
    fmt.Printf("all keys and values are:")
    for _, v := range result {
        fmt.Printf("%s ", v.([]byte))
    }
    fmt.Println()
}
三.List: 列表

list类型常见操作

rpush(key, value):在名称为key的list尾添加一个值为value的元素
lpush(key, value):在名称为key的list头添加一个值为value的 元素
llen(key):返回名称为key的list的长度
lrange(key, start, end):返回名称为key的list中start至end之间的元素
ltrim(key, start, end):截取名称为key的list
lindex(key, index):返回名称为key的list中index位置的元素
lset(key, index, value):给名称为key的list中index位置的元素赋值
lrem(key, count, value):删除count个key的list中值为value的元素
lpop(key):返回并删除名称为key的list中的首元素
rpop(key):返回并删除名称为key的list中的尾元素
blpop(key1, key2,… key N, timeout):lpop命令的block版本。
brpop(key1, key2,… key N, timeout):rpop的block版本。
rpoplpush(srckey, dstkey):返回并删除名称为srckey的list的尾元素,并将该元素添加到名称为dstkey的list的头部

lpush

_,err = c.Do("lpush","mylist","ofo","mobike","foo")
if err != nil   {
    fmt.Println("redis lpush failed",err.Error())
}

rpush

_,err = c.Do("rpush","mylist","bluegogo","xiaolan","xiaoming")
if err != nil{
    fmt.Println("redis rpush failed",err.Error())
}

llen

num,err := c.Do("llen","mylist")
if err != nil{
    fmt.Println("mylist get len err",err.Error())
}else{
    fmt.Println("mylist's len is ",num)
}

lrange

values,err := redis.Values(c.Do("lrange","mylist",0,10))
if err != nil{
    fmt.Println("lrange err",err.Error())
}
fmt.Printf("mylist is:")
for _,v := range values{
    fmt.Printf(" %s ",v.([]byte))
}
fmt.Println()

ltrim

_, err = c.Do("ltrim", "mylist", 0, 4)
if err != nil {
    fmt.Println("ltrim error", err.Error())
} else {
    values, err = redis.Values(c.Do("lrange", "mylist", 0, 4))
    if err != nil {
        fmt.Println("ltrim failed:", err.Error())
    }
    fmt.Printf("ltrim mylist is:")
    for _, v := range values {
        fmt.Printf("%s ", v.([]byte))
    }
    fmt.Printf("\n")
}

lindex

val, err := c.Do("lindex", "mylist", 2)
if err != nil {
    fmt.Println("lindex error:", err.Error())
} else {
    fmt.Printf("lindex get result :%s\n", val)
}

rpoplpush

_, err = c.Do("rpoplpush", "mylist", "mybike")
if err != nil {
    fmt.Println("rpoplpush failed:", err.Error())
} else {
    values, err = redis.Values(c.Do("lrange", "mylist", 0, 10))
    if err != nil {
        fmt.Println("lrange failed:", err.Error())
    }
    for _, v := range values {
        fmt.Printf("rpoplpush %s\n", v.([]byte))
    }

    values, err = redis.Values(c.Do("lrange", "mybike", 0, 10))
    if err != nil {
        fmt.Println("lrange failed:", err.Error())
    }
    for _, v := range values {
        //fmt.Println(string(v.([]byte)))
        fmt.Printf("rpoplpush %s\n", v.([]byte))
    }
}

lset

_, err = c.Do("lset", "mylist", 2, "mysql")
if err != nil {
    fmt.Println("lset error:", err.Error())
}
val, err = c.Do("lindex", "mylist", 2)
if err != nil {
    fmt.Println("lset error:", err.Error())
} else {
    fmt.Printf("lset get result:%s\n", val)
}

lrem

_, err = c.Do("lrem", "mylist", 1, "mysql")
if err != nil {
    fmt.Println("lrem error", err.Error())
} else {
    values, err = redis.Values(c.Do("lrange", "mylist", 0, 10))
    if err != nil {
        fmt.Println("ltrim failed:", err.Error())
    }
    for _, v := range values {
        fmt.Printf("lrem mylist: %s", v.([]byte))
    }
    fmt.Printf("\n")
}

lpop

_, err = c.Do("lpop", "mylist")
if err != nil {
    fmt.Println("lpop failed:", err.Error())
} else {
    values, err = redis.Values(c.Do("lrange", "mylist", 0, 10))
    if err != nil {
        fmt.Println("lpop failed:", err.Error())
    }
    fmt.Printf("lpop mylist :")
    for _, v := range values {
        fmt.Printf("lpop mylist %s", v.([]byte))
    }
    fmt.Printf("\n")
}

rpop

_, err = c.Do("rpop", "mylist")
if err != nil {
    fmt.Println("rpop failed", err.Error())
} else {
    values, err = redis.Values(c.Do("lrange", "mylist", 0, 10))
    if err != nil {
        fmt.Println("rpop failed:", err.Error())
    }
    fmt.Printf("rpop mylist :")
    for _, v := range values {
        //fmt.Println(string(v.([]byte)))
        fmt.Printf("lpop mylist %s", v.([]byte))
    }
    fmt.Printf("\n")
}

blpop

res, err := c.Do("blpop", "mylist", 10)
if err != nil {
    fmt.Println("blpop error")
} else {
    fmt.Printf("blpop from mylist get:%s\n", res)
}

res, err = c.Do("blpop", "tmpbike", 10)
if err != nil {
    fmt.Println("blpop time out")
} else {
    fmt.Println("blpop from tmpbike get:", res)
}

brpop

res, err = c.Do("brpop", "tmpbike", 10)
if err != nil {
    fmt.Println("brpop error")
} else {
    fmt.Printf("brpop from tmpbike get :%s\n", res)
}

res, err = c.Do("brpop", "mybike", 10)
if err != nil {
    fmt.Println("brpop time out")
} else {
    fmt.Printf("brpop from mybike get:%s ", res)

}
四.Set: 集合

set类型常见操作

sadd(key, member):向名称为key的set中添加元素member
srem(key, member) :删除名称为key的set中的元素member
spop(key) :随机返回并删除名称为key的set中一个元素
smove(srckey, dstkey, member) :移到集合元素
scard(key) :返回名称为key的set的基数
sismember(key, member) :member是否是名称为key的set的元素
sinter(key1, key2,…key N) :求交集
sinterstore(dstkey, (keys)) :求交集并将交集保存到dstkey的集合
sunion(key1, (keys)) :求并集
sunionstore(dstkey, (keys)) :求并集并将并集保存到dstkey的集合
sdiff(key1, (keys)) :求差集
sdiffstore(dstkey, (keys)) :求差集并将差集保存到dstkey的集合
smembers(key) :返回名称为key的set的所有元素
srandmember(key) :随机返回名称为key的set的一个元素

sadd/smembers

_, err = c.Do("sadd", "myset", "mobike", "foo", "ofo", "bluegogo")
if err != nil {
    fmt.Println("set add failed", err.Error())
}
value, err := redis.Values(c.Do("smembers", "myset"))
if err != nil {
    fmt.Println("set get members failed", err.Error())
} else {
    fmt.Printf("myset members :")
    for _, v := range value {
        fmt.Printf("%s ", v.([]byte))
    }
    fmt.Printf("\n")
}

srandmember

ret, err := c.Do("srandmember", "myset")
if err != nil {
    fmt.Println("srandmember get failed")
} else {
    fmt.Printf("srandmember get value is:%s\n", ret)
}

srem

_, err = c.Do("srem", "myset", "bluegogo")
if err != nil {
    fmt.Println("srem myset error", err.Error())
} else {
    value, err = redis.Values(c.Do("smembers", "myset"))
    if err != nil {
        fmt.Println("set get members failed", err.Error())
    } else {
        fmt.Printf("myset members :")
        for _, v := range value {
            fmt.Printf("%s ", v.([]byte))
        }
        fmt.Printf("\n")
    }
}

smove

_, err = c.Do("smove", "myset", "dbset", "mobike")
if err != nil {
    fmt.Println("smove failed", err.Error())
} else {
    value, err = redis.Values(c.Do("smembers", "dbset"))
    if err != nil {
        fmt.Println("get new dbset members failed", err.Error())
    } else {
        fmt.Printf("get new dbset members :")
        for _, v := range value {
            fmt.Printf("%s ", v.([]byte))
        }
        fmt.Printf("\n")
    }
}

scard

num, err := c.Do("scard", "myset")
if err != nil {
    fmt.Println("scard error", err.Error())
} else {
    fmt.Println("scard get num :", num)
}

sismember

isMember, err := c.Do("sismember", "myset", "foo")
if err != nil {
    fmt.Println("sismember get failed", err.Error())
} else {
    fmt.Println("foo is or not myset's member", isMember)
}

sinter

_, err = c.Do("sadd", "dbset", "foo", "ofo", "xiaolan")
if err != nil {
    fmt.Println("set add failed", err.Error())
}
inner, err := redis.Values(c.Do("sinter", "myset", "dbset"))
if err != nil {
    fmt.Println("sinter error", err.Error())
} else {
    fmt.Printf("two set inter is:")
    for _, v := range inner {
        fmt.Printf(" %s ", v.([]byte))
    }
    fmt.Printf("\n")
}

sinterstore

_, err = c.Do("sinterstore", "newset", "dbset", "myset")
if err != nil {
    fmt.Println("sinterstore between myset and dbset error", err.Error())
} else {
    value, err := redis.Values(c.Do("smembers", "newset"))
    if err != nil {
        fmt.Println("set get members failed", err.Error())
    } else {
        fmt.Printf("newset members :")
        for _, v := range value {
            fmt.Printf("%s ", v.([]byte))
        }
        fmt.Printf("\n")
    }
}

sunion

unino, err := redis.Values(c.Do("sunion", "myset", "dbset"))
if err != nil {
    fmt.Println("sunion err", err.Error())
} else {
    fmt.Printf("two set union is:")
    for _, v := range unino {
        fmt.Printf(" %s ", v.([]byte))
    }
    fmt.Printf("\n")
}

sunionstore

_, err = c.Do("sunionstore", "unewset", "myset", "dbset")
if err != nil {
    fmt.Println("sunionstore failed", err.Error())
} else {
    value, err := redis.Values(c.Do("smembers", "unewset"))
    if err != nil {
        fmt.Println("set get members failed", err.Error())
    } else {
        fmt.Printf("unewset members :")
        for _, v := range value {
            fmt.Printf("%s ", v.([]byte))
        }
        fmt.Printf("\n")
    }
}

sdiff

diff, err := redis.Values(c.Do("sdiff", "dbset", "myset"))
if err != nil {
    fmt.Println("sdiff err", err.Error())
} else {
    fmt.Printf("two set diff is:")
    for _, v := range diff {
        fmt.Printf(" %s ", v.([]byte))
    }
    fmt.Printf("\n")
}

sdiffstore

_, err = c.Do("sdiffstore", "dnewset", "dbset", "myset")
if err != nil {
    fmt.Println("sdiffstore failed", err.Error())
} else {
    value, err := redis.Values(c.Do("smembers", "dnewset"))
    if err != nil {
        fmt.Println("set get members failed", err.Error())
    } else {
        fmt.Printf("dnewset members :")
        for _, v := range value {
            fmt.Printf("%s ", v.([]byte))
        }
        fmt.Printf("\n")
    }
}

spop

res, err := c.Do("spop", "myset")
if err != nil {
    fmt.Println("spop failed", err.Error())
} else {
    fmt.Printf("spop element is:%s\n", res)
}
value, err = redis.Values(c.Do("smembers", "myset"))
if err != nil {
    fmt.Println("after spop  get members failed", err.Error())
} else {
    fmt.Printf("after spop myset members :")
    for _, v := range value {
        fmt.Printf("%s ", v.([]byte))
    }
    fmt.Printf("\n")
}
五.Sorted Set: 有序集合

sorted set简单操作

zadd(key, score1,member1,...scoreN,memberN) 向有序结合添加(更新)一个或多个成员
zcard(key):获取有序集合的成员
zcount(key,start,end):计算指定区间的成员数
zincrby(key,increment,member):成员member增加increment
zinterstore(dst,numkey,src1,src2..srcN):求交集,并将结果存储新的结合
zlexcount(key,start,end):计算字典区间成员数(分数都相同,按照字典排序)
zrange(key,start,end):获取索引区间的成员
zrangebylex (key,start,end):通过字典区间返回区间内有序集合成员
zrangebyscore(key,start,end):通过分数返回区间内的有序集合
zrank (key,member):返回有序结合的索引
zrem(key,members1...membersN):删除一个或多个成员
zremrangebylex(key,start,end):移除集合中给定字典区间的成员
zremrangebyrank(key,start,end):移除有序集合中给定的排名区间的所有成员
zremrangebyscore(key,start,end):移除给定分数区间的所有元素
zrevange(key,start,end):通过索引,分数由高到低,返回指定区域的元素
zrevrangebyscore(key,member):分数由高向低返回指定区间的成员数
zrevrank(key,member):分数从小到大,返回指定成员的排名
zscore(key,member):返回有序集中,成员的分数值
zunionstore(dst,numkeys,key1...keyN):返回给定的一个或多个集合的并集,并存储在新的集合中
zscan(key,cursor):迭代有序结合中的元素(包括元素成员和元素分值)

zadd

_, err1 := c.Do("zadd", "curbike", 1, "mobike", 2, "xiaolan", 3, "ofo", 4, "xiaoming")
_, err2 := c.Do("zadd", "tmpdata", 0, "mobike", 0, "xiaolan", 0, "mysql", 0, "redis", 0, "mongo", 0, "xiaoming")
if err1 != nil || err2 != nil {
    fmt.Println("zadd failed", err.Error())
}

zcard

num, err := c.Do("zcard", "curbike")
if err != nil {
    fmt.Println("zcard failed", err.Error())
} else {
    fmt.Printf("curbike's size is %s:", num)
}

zcount

num, err = c.Do("zcount", "curbike", 1, 3)
if err != nil {
    fmt.Println("zcount failed ", err.Error())
} else {
    fmt.Println("zcount num is :", num)
}

zincrby

num, err = c.Do("zincrby", "curbike", 3, "xiaolan")
fmt.Println(reflect.TypeOf(num))
if err != nil {
    fmt.Println("zincrby failed", err.Error())
} else {
    fmt.Println("after zincrby the :", num)
}

zinterstore

_, err = c.Do("zinterstore", "internewset", 2, "curbike", "tmpdata")
if err != nil {
    fmt.Println("zinterstore failed", err.Error())
} else {
    result, err := redis.Values(c.Do("zrange", "internewset", 0, 10))
    if err != nil {
        fmt.Println("interstore failed", err.Error())
    } else {
        fmt.Printf("interstore newset elsements are:")
        for _, v := range result {
            fmt.Printf("%s ", v.([]byte))
        }
        fmt.Println()
    }
}

zlexcount

num, err = c.Do("zlexcount", "tmpdata", "[mongo", "[xiaoming")
if err != nil {
    fmt.Println("zlexcount failed", err.Error())
} else {
    fmt.Println("zlexcount in tmpdata is :", num)
}
res, err := redis.Values(c.Do("zrange", "curbike", 0, -1, "withscores"))
if err != nil {
    fmt.Println("zrange in curbike failed", err.Error())
} else {
    fmt.Printf("curbike's element are follow:")
    for _, v := range res {
        fmt.Printf("%s ", v.([]byte))
    }
    fmt.Println()
}

zrangebylex

res, err = redis.Values(c.Do("zrangebylex", "tmpdata", "[mobike", "[redis"))
if err != nil {
    fmt.Println("zrangebylex failed", err.Error())
} else {
    fmt.Printf("zrangebylex in tmpdata:")
    for _, v := range res {
        fmt.Printf("%s ", v.([]byte))
    }
    fmt.Println()
}

zrangebyscore

res, err = redis.Values(c.Do("zrangebyscore", "curbike", "(1", "(5"))
if err != nil {
    fmt.Println("zrangebyscore failed", err.Error())
} else {
    fmt.Printf("zrangebyscore's element:")
    for _, v := range res {
        fmt.Printf("%s ", v.([]byte))
    }
    fmt.Println()
}

zrank

num, err = c.Do("zrank", "internewset", "xiaoming")
if err != nil {
    fmt.Println("zrank failed ", err.Error())
} else {
    fmt.Println("xiaoming's score is ", num)
}

zunionstore

_, err = c.Do("zunionstore", "unewzset", 2, "curbike", "tmpdata")
if err != nil {
    fmt.Println("zunionstore failed", err.Error())
} else {
    res, err = redis.Values(c.Do("zrange", "unewzset", 0, 10))
    if err != nil {
        fmt.Println("zunionstore failed", err.Error())
    } else {
        fmt.Printf("union set are:")
        for _, v := range res {
            fmt.Printf("%s ", v.([]byte))
        }
        fmt.Println()
    }
}

zscore

ret, err := c.Do("zscore", "internewset", "xiaolan")
if err != nil {
    fmt.Println("zscore failed", err.Error())
} else {
    fmt.Printf("curbike 's xiaolan score is:%s\n", ret)
}

zrevrank

num, err = c.Do("zrevrank", "curbike", "ofo")
if err != nil {
    fmt.Println("zrevrank failed", err.Error())
} else {
    fmt.Println("ofo's zrevrank is :", num)
}

zrevrangebyscore

res, err = redis.Values(c.Do("zrevrangebyscore", "unewzset", 10, 2))
if err != nil {
    fmt.Println("zrevrangebyscore failed", err.Error())
} else {
    fmt.Printf("zrevrangebyscore are:")
    for _, v := range res {
        fmt.Printf("%s ", v.([]byte))
    }
    fmt.Println()
}

zrevrange

res, err = redis.Values(c.Do("zrevrange", "unewzset", 0, 10))
 err != nil {
    fmt.Println("zrevrange failed:", err.Error())
} else {
    fmt.Printf("zrevrange element:")
    for _, v := range res {
        fmt.Printf("%s ", v.([]byte))
    }
    fmt.Println()
}

zrem

num, err = c.Do("zrem", "unewzset", "mysql")
if err != nil {
    fmt.Println("zrem failed", err.Error())
} else {
    fmt.Println("zrem result is:", num)
}

zremrangebyrank

num, err = c.Do("zremrangebyrank", "unewzset", 1, 4)
if err != nil {
    fmt.Println("zremrangebyrank failed", err.Error())
} else {
    fmt.Println("zremrangebyrank result:", num)
}

zremrangebyscore

num, err = c.Do("zremrangebyscore", "curbike", 2, 5)
if err != nil {
    fmt.Println("zremrangebyscore failed", err.Error())
} else {
    fmt.Println("zremrangebyscore result:", num)
}

原作者链接: 查看详情

在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会代码的小林

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值