了解golang接口模式
/* 定义接口 */
type interface_name interface {
method_name1 [return_type]
method_name2 [return_type]
method_name3 [return_type]
...
method_namen [return_type]
}
/* 定义结构体 */
type struct_name struct {
/* variables */
}
/* 实现接口方法 */
func (struct_name_variable struct_name) method_name1() [return_type] {
/* 方法实现 */
}
...
func (struct_name_variable struct_name) method_namen() [return_type] {
/* 方法实现*/
}
了解Redis4种数据类型的操作
1. String 类型常见操作
- set(key, value):给数据库中名称为key的string赋予值value
- get(key):返回数据库中名称为key的string的value
- getset(key,value):给名称为key的string赋予上一次的value
- mget(key1, key2,…, key N):返回库中多个string的value
- setnx(key, value):添加string,名称为key,值为value
- setex(key, time, value):向库中添加string,设定过期时间time
- mset(key N, value N):批量设置多个string的值
- msetnx(key N, value N):如果所有名称为key i的string都不存在
- incr(key):名称为key的string增1操作
- incrby(key, integer):名称为key的string增加integer
- decr(key):名称为key的string减1操作
- decrby(key, integer):名称为key的string减少integer
- append(key, value):名称为key的string的值附加value
- substr(key, start, end):返回名称为key的string的value的子串
2. 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
3. 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的一个元素
4. 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的头部
依赖Package
golang redis 包
github.com/garyburd/redigo/redis
Redis 连接池
const (
RedisURL ="redis://127.0.0.1:6379"
redisMaxIdle = 25 //最大空闲连接数
redisMaxActive = 100 //最大的激活连接数
redisIdleTimeoutSec = 240 //最大空闲连接时间
//RedisPassword = ""
)
/*
* Redis 连接池
* NewRedisPool 返回redis连接池
* 参数: redisURL redis服务; Database redisDB;
* 返回: redis 连接
*/
func NewRedisPool(redisURL string, Database int) *redis.Pool {
return &redis.Pool{
MaxIdle: redisMaxIdle,
MaxActive: redisMaxActive,
IdleTimeout: redisIdleTimeoutSec * time.Second,
Dial: func() (redis.Conn, error) {
// redis://127.0.0.1:6379/0
URLs := strings.Join([]string{redisURL, strconv.Itoa(Database)}, "/")
fmt.Println(URLs)
c, err := redis.DialURL(URLs)
//c, err := redis.Dial("tcp",redisURL,redis.DialDatabase(5))
if err != nil {
return nil, fmt.Errorf("redis connection error: %s", err)
}
/*//验证redis密码
if _, authErr := c.Do("AUTH", RedisPassword); authErr != nil {
return nil, fmt.Errorf("redis auth password error: %s", authErr)
}
*/
return c, err
},
TestOnBorrow: func(c redis.Conn, t time.Time) error {
_, err := c.Do("PING")
if err != nil {
return fmt.Errorf("ping redis error: %s", err)
}
return nil
},
}
}
——————————————————————————————————
设计接口
1. 以key为对象添加数据整合一起组成接口
2. 以批量操作整合一起组成接口
3. 以发布订阅整合一起组成接口
代码实现
package main
import (
"encoding/json"
_ "errors"
"fmt"
"time"
_ "reflect"
"strings"
"strconv"
"github.com/garyburd/redigo/redis"
)
const (
RedisURL ="redis://127.0.0.1:6379"
redisMaxIdle = 25 //最大空闲连接数
redisMaxActive = 100 //最大的激活连接数
redisIdleTimeoutSec = 240 //最大空闲连接时间
//RedisPassword = ""
)
/*
* Redis 连接池
* NewRedisPool 返回redis连接池
* 参数: redisURL redis服务; Database redisDB;
* 返回: redis 连接
*/
func NewRedisPool(redisURL string, Database int) *redis.Pool {
return &redis.Pool{
MaxIdle: redisMaxIdle,
MaxActive: redisMaxActive,
IdleTimeout: redisIdleTimeoutSec * time.Second,
Dial: func() (redis.Conn, error) {
// redis://127.0.0.1:6379/0
URLs := strings.Join([]string{redisURL, strconv.Itoa(Database)}, "/")
fmt.Println(URLs)
c, err := redis.DialURL(URLs)
//c, err := redis.Dial("tcp",redisURL,redis.DialDatabase(5))
if err != nil {
return nil, fmt.Errorf("redis connection error: %s", err)
}
/*//验证redis密码
if _, authErr := c.Do("AUTH", RedisPassword); authErr != nil {
return nil, fmt.Errorf("redis auth password error: %s", authErr)
}
*/
return c, err
},
TestOnBorrow: func(c redis.Conn, t time.Time) error {
_, err := c.Do("PING")
if err != nil {
return fmt.Errorf("ping redis error: %s", err)
}
return nil
},
}
}
/*
* 1. 以key为对象进行操作整合一起组成接口
*/
type ManRedisKey interface {
Strset(value interface{})
Strget() string
Strgetset(value interface{}) string
ExpireKey(extime int)
CheckKey() bool
DelKey() error
StrsetJson(value interface{})
StrgetJson() interface{}
}
type RKey struct {
key string
}
/*
* set(key, value):给数据库中名称为key的string赋予值value
*/
func (manrk *RKey) Strset(value interface{}) {
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
_, err := c.Do("SET", manrk.key, value)
if err != nil {
fmt.Println("set error", err.Error())
}else{
fmt.Println("set ok.")
}
}
/*
* set(key, value):给数据库中名称为key的string赋予值value
*/
func (manrk *RKey) StrsetEX(value interface{}, extime int) {
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
_, err := c.Do("SET", manrk.key, value, "EX", extime)
if err != nil {
fmt.Println("set error", err.Error())
}else{
fmt.Println("set ok.")
}
}
/*
* get(key):返回数据库中名称为key的string的value
*/
func (manrk *RKey) Strget() string {
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
res, err := redis.String(c.Do("GET", manrk.key))
if err != nil {
fmt.Println("GET error", err.Error())
return ""
}else{
return res
}
}
/*
* getset(key, value):给名称为key的string赋予上一次的value
*/
func (manrk *RKey) Strgetset(v interface{}) string {
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
res, err := redis.String(c.Do("GETSET", manrk.key, v))
if err != nil {
fmt.Println("GETSET error", err.Error())
return ""
}else{
fmt.Println("GETSET ok.")
return res
}
}
/*
* 给keys 设置时间
*/
func (manrk *RKey) ExpireKey(extime int) {
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
_, err := c.Do("EXPIRE", manrk.key, extime)
if err != nil {
fmt.Println("set error", err.Error())
}
}
/*
* 判断是否存在
*/
func (manrk *RKey) CheckKey() bool {
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
exist, err := redis.Bool(c.Do("EXISTS", manrk.key))
if err != nil {
fmt.Println(err)
return false
} else {
return exist
}
}
/*
* 删除key
*/
func (manrk *RKey) DelKey() error {
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
_, err := c.Do("DEL", manrk.key)
if err != nil {
fmt.Println(err)
return err
}
return nil
}
/*
* 存入json数据
*/
func (manrk *RKey) StrsetJson(value interface{}) {
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
datas, _ := json.Marshal(value)
_, err := c.Do("SET", manrk.key, datas)
if err != nil {
fmt.Println("set error", err.Error())
}else{
fmt.Println("set ok.")
}
}
/*
* 获取json数据
*/
func (manrk *RKey) StrgetJson() interface{}{
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
var getdatas map[string]string
valueget, err := redis.Bytes(c.Do("GET", manrk.key))
if err != nil {
fmt.Println(err)
return 0
}
errshal := json.Unmarshal(valueget, &getdatas)
if errshal != nil {
return 0
}
return getdatas
}
/*
* 2. 以批量操作数据整合一起组成接口
*/
type ManRedisBatch interface {
Strmset()
Strmget() ([]string)
}
type BatchDatas struct {
datas interface{}
}
/*
* mset(key N, value N):批量设置多个string的值
*/
func (manrb *BatchDatas) Strmset() {
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
_, err := c.Do("mset", redis.Args{}.AddFlat(manrb.datas)...)
if err != nil {
fmt.Println("mset error", err.Error())
} else {
fmt.Println("ok")
}
}
/*
* mget(key1, key2,…, key N):返回库中多个string的value
*/
func (manrb *BatchDatas) Strmget() ([]string) {
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
list := []string {}
res, err := redis.Values( c.Do("mget", redis.Args{}.AddFlat(manrb.datas)...))
if err != nil {
fmt.Println("mset error", err.Error())
return list
} else {
for _, v := range res {
fmt.Println(string(v.([]byte)))
list = append(list, string(v.([]byte)))
}
return list
}
}
func test() {
keys := "test1"
var test1 ManRedisKey = &RKey{key:keys}
test1.Strset("aaa1")
fmt.Println(test1.Strget())
fmt.Println(test1.Strgetset("aaa2"))
test1.ExpireKey(100)
fmt.Println(test1.CheckKey())
test1.DelKey()
datas1 := map[string]string{"username": "666", "phonenumber": "888"}
var test2 ManRedisBatch = &BatchDatas{datas:datas1}
test2.Strmset()
var test3 ManRedisBatch = &BatchDatas{datas:[]string{"username","phonenumber"}}
fmt.Println(test3.Strmget())
var test4 ManRedisKey = &RKey{key:"test4"}
test4.StrsetJson(map[string]string{"aa1": "111", "aa2": "222"})
fmt.Println(test4.StrgetJson())
fmt.Println(test4.Strget())
}
/*
* 管道 按照队列先进先出的原则进行send,receive操作
*/
func sendr() {
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
c.Send("SET", "userId", "DF123")
c.Send("GET", "userId")
c.Flush()
c.Receive() // reply from SET
valueGet, errr := c.Receive() // reply from GET
fmt.Println(redis.String(valueGet,errr))
}
/*
* 发布/订阅
*/
func Subs() { //订阅者
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
psc := redis.PubSubConn{c}
psc.Subscribe("channel1") //订阅channel1频道
for {
switch v := psc.Receive().(type) {
case redis.Message:
fmt.Printf("%s: message: %s\n", v.Channel, v.Data)
case redis.Subscription:
fmt.Printf("%s: %s %d\n", v.Channel, v.Kind, v.Count)
case error:
fmt.Println(v)
return
}
}
}
func Push(message string) { //发布者
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
_,err1 := c.Do("PUBLISH", "channel1", message)
if err1 != nil {
fmt.Println("pub err: ", err1)
return
}
}
func main() {
test()
sendr()
//发布/订阅
go Subs()
go Push("mange *******...")
}
运行结果
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
*/
/*
* 设置值数据类型为 Hash
*
*/
func addto_Hash(k string, f string, v string) {
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
_, err := c.Do("hset", k, f, v)
if err != nil {
fmt.Println("hset error", err.Error())
}else{
fmt.Println("hset ok")
}
}
//查询数据 - Hash
//result,err := redis.Values(c.Do("hgetall","key"))
func getdata_Hash(k, f string) string {
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
res, err := redis.String(c.Do("hget", k, f))
fmt.Println(reflect.TypeOf(res))
if err != nil {
fmt.Println("hget failed", err.Error())
return "-1"
} else {
fmt.Printf("hget value :%s\n", res)
return res
}
}
//判断key是否存在
//存在返回 1
//不存在返回 0
//异常返回 -1
func judgekey_Hash(k, f string) int {
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
res, err := redis.Int((c.Do("hexists", k, f)))
if err != nil {
fmt.Println("hexist failed", err.Error())
return -1
} else {
//fmt.Println("exist or not:", res)
//fmt.Println(reflect.TypeOf(res))
return res
}
}
//批量添加数据到redis Hash
func addarr_Hash(k string, f interface{}) {
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
_, err := c.Do("hmset", redis.Args{}.Add(k).AddFlat(f)...)
if err != nil {
fmt.Println("hmset error", err.Error())
} else {
fmt.Println("ok")
}
}
// 返回名称为key的hash中元素个数
func getlen_datas(k string) int {
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
res, err := redis.Int((c.Do("hlen", k)))
if err != nil {
fmt.Println("hexist failed", err.Error())
return -1
} else {
//fmt.Println("exist or not:", res)
//fmt.Println(reflect.TypeOf(res))
return res
}
}
//hkeys(key):返回名称为key的hash中所有键
//返回值为数组
func getall_keys(k string) []string {
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
res, err := redis.Values((c.Do("hkeys", k)))
if err != nil {
fmt.Println("hexist failed", err.Error())
return []string {}
} else {
list := []string {}
for _, v := range res {
list = append(list, string(v.([]byte)))
}
fmt.Println(list)
return list
}
}
//hvals(key):返回名称为key的hash中所有键对应的value
func getall_vals(k string) []string {
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
res, err := redis.Values((c.Do("hvals", k)))
if err != nil {
fmt.Println("hexist failed", err.Error())
return []string {}
} else {
list := []string {}
for _, v := range res {
list = append(list, string(v.([]byte)))
}
fmt.Println(list)
return list
}
}
//hgetall(key):返回名称为key的hash中所有的键(field)及其对应的value
//返回 map
func getall_datas(k string) map[string]string {
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
res, err := redis.StringMap((c.Do("hgetall", k)))
if err != nil {
fmt.Println("hexist failed", err.Error())
return make(map[string]string)
} else {
//转为json
result, err := json.Marshal(res)
if err != nil {
fmt.Println("result is null")
}
fmt.Println("result = ", string(result))
return res
}
}
//hdel(key, field):删除名称为key的hash中键为field的域
func del_datas(k, f string) {
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
_, err := c.Do("HDEL", k, f)
if err != nil {
fmt.Println("hdel failed", err.Error())
} else {
fmt.Println("hdel ok")
}
}
//hincrby(key, field, integer):将名称为key的hash中field的value增加integer
func hincrby_test() {
c := NewRedisPool(RedisURL,1).Get()
defer c.Close()
_, err := c.Do("hincrby", "a", "dd", 1)
if err != nil {
fmt.Println("hmset error", err.Error())
} else {
fmt.Println("ok")
}
}