Golang之redis中间件框架——go-redis的使用

写在前面

      本文主要介绍操作redis数据库的框架go-redis,因此下面涉及到redis中的命令本文不做详解,下文通过使用go-redis实现go语言代码操作redis,对应命令的作用及说明请看这篇文章,里面介绍了redis各数据类型常用的一些命令。

go-redis简介

      go-redisgo语言操作redis数据库的框架,从框架中的关于redis操作的方法名可以看出其对应的redis操作。与redigo不同,redigo整体一个Do方法,通过参数决定执行什么redis操作,而go-redis中的方法已经决定了执行何种操作。

go-redis安装

      下载安装:go get github.com/go-redis/redis
      文档地址:https://godoc.org/github.com/go-redis/redis

go-redis使用

连接至redis服务端

//连接redis服务端
func goRedisConnect(){
	client = redis.NewClient(&redis.Options{
		Addr:"127.0.0.1:6379",
		DB:0,	//redis默认有0-15共16个数据库,这里设置操作索引为0的数据库
	})

	pong,err := client.Ping().Result()

	if err != nil {
		log.Fatal(err)
	}

	if pong != "PONG" {
		log.Fatal("客户端连接redis服务端失败")
	}else {
		fmt.Println("客户端已成功连接至redis服务端")
	}
}

string类型数据操作

//string类型数据操作
//redis命令:set key val
func set(key,val string){
	//有效期为0表示不设置有效期,非0表示经过该时间后键值对失效
	result,err := client.Set(key,val,0).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(result)
}
//redis命令:get key
func get(key string){
	val,err := client.Get(key).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(val)
}
//redis命令:mset key1 val1 key2 val2 key3 val3 ...
func mset(key1,val1,key2,val2,key3,val3 string){
	//以下三种方式都可以,习惯于对象操作的我优先选择第三种
	//result,err := client.MSet(key1,val1,key2,val2,key3,val3).Result()
	//result,err := client.MSet([]string{key1,val1,key2,val2,key3,val3}).Result()
	result,err := client.MSet(map[string]interface{}{key1:val1,key2:val2,key3:val3}).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(result)
}
//redis命令:mget key1 key2 key3 ...
func mget(key1,key2,key3 string){
	vals,err := client.MGet(key1,key2,key3).Result()

	if err != nil {
		log.Fatal(err)
	}

	for k,v := range vals {
		fmt.Printf("k = %v v = %s\n",k,v)
	}
}
//redis命令:del key1 key2 key3 ...
func del(key1,key2,key3 string){
	result,err := client.Del(key1,key2,key3).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(result)
}
//redis命令:getrange key start end
func getrange(key string,start,end int64){
	val,err := client.GetRange(key,start,end).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(val)
}
//redis命令:strlen key
func strlen(key string){
	len,err := client.StrLen(key).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(len)
}
//redis命令:setex key time val
func setex(key,val string,expire int){
	//time.Duration其实也是int64,不过是int64的别名罢了,但这里如果expire使用int64也无法与time.Second运算,
	//因为int64和Duration虽然本质一样,但表面上属于不同类型,go语言中不同类型是无法做运算的
	result,err := client.Set(key,val,time.Duration(expire) * time.Second).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(result)
}
//redis命令:append key val
func append(key,val string){
	//将val插入key对应值的末尾,并返回新串长度
	len,err := client.Append(key,val).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(len)
}
//redis命令:exists key
func exists(key string){
	//返回1表示存在,0表示不存在
	isExists,err := client.Exists(key).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(isExists)
}

hash类型数据操作

/hash类型数据操作
//redis命令:hset hashTable key val
func hset(hashTable,key,val string){
	isSetSuccessful,err := client.HSet(hashTable,key,val).Result()

	if err != nil {
		log.Fatal(err)
	}
	//如果键存在这返回false,如果键不存在则返回true
	fmt.Println(isSetSuccessful)
}
//redis命令:hget hashTable key
func hget(hashTable,key string){
	val,err := client.HGet(hashTable,key).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(val)
}
//redis命令:hmset hashTable key1 val1 key2 val2 key3 val3 ...
//该函数本身有问题,只插入一个键值对的话相当于hset,可以成功
//如果插入一个以上的键值对则会报错:ERR wrong number of arguments for 'hset' command
//且go-redis官方本身也不推荐是用该函数
//func hmset(hashTable,key1,val1,key2,val2,key3,val3 string){
//	_,err := client.HMSet(hashTable,key1,val1,key2,val2,key3,val3).Result()
//
//	if err != nil {
//		log.Fatal(err)
//	}
//}
//redis命令:hmget hashTable key1 key2 key3 ...
func hmget(hashTable,key1,key2,key3 string){
	vals,err := client.HMGet(hashTable,key1,key2,key3).Result()

	if err != nil {
		log.Fatal(err)
	}

	for k,v := range vals {
		fmt.Printf("k = %v v = %s\n",k,v)
	}
}
//redis命令:hdel hashTable key1 key2 key3 ...
func hdel(hashTable,key1,key2,key3 string){
	//返回1表示删除成功,返回0表示删除失败
	//只要至少有一个被删除则返回1(不存在的键不管),一个都没删除则返回0(不存在的则也算没删除)
	n,err := client.Del(hashTable,key1,key2,key3).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(n)
}
//redis命令:hgetall hashTable
func hgetall(hashTable string){
	vals,err := client.HGetAll(hashTable).Result()

	if err != nil {
		log.Fatal(err)
	}

	for k,v := range vals {
		fmt.Printf("k = %v v = %s\n",k,v)
	}
}
//redis命令:hexists hashTable key
func hexists(hashTable,key string){
	isExists,err := client.HExists(hashTable,key).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(isExists)
}
//redis命令:hlen hashTable
func hlen(hashTable string){
	len,err := client.HLen(hashTable).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(len)
}
//redis命令:hkeys hashTable
func hkeys(hashTable string){
	keys,err := client.HKeys(hashTable).Result()

	if err != nil {
		log.Fatal(err)
	}

	for k,v := range keys {
		fmt.Printf("k = %v v = %s\n",k,v)
	}
}
//redis命令:hvals hashTable
func hvals(hashTable string){
	vals,err := client.HVals(hashTable).Result()

	if err != nil {
		log.Fatal(err)
	}

	for k,v := range vals {
		fmt.Printf("k = %v v = %s\n",k,v)
	}
}

list类型数据操作

//list类型数据操作
//redis命令:lpush mylist val1 val2 val3 ...
func lpush(mylist,val1,val2,val3 string){
	//返回列表的总长度(即有多少个元素在列表中)
	n,err := client.LPush(mylist,val1,val2,val3).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(n)
}
//redis命令:rpush mylist val1 val2 val3 ...
func rpush(mylist,val1,val2,val3 string){
	//返回列表的总长度(即有多少个元素在列表中)
	n,err := client.RPush(mylist,val1,val2,val3).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(n)
}
//redis命令:lpop mylist
func lpop(mylist string){
	//返回被删除的值
	val,err := client.LPop(mylist).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(val)
}
//redis命令:rpop mylist
func rpop(mylist string){
	//返回被删除的值
	val,err := client.RPop(mylist).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(val)
}
//redis命令:lrem mylist count val
func lrem(mylist,val string,count int64){
	//返回成功删除的val的数量
	n,err := client.LRem(mylist,count,val).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(n)
}
//redis命令:ltrim mylist start end
func ltrim(mylist string,start,end int64){
	//返回状态(OK)
	status,err := client.LTrim(mylist,start,end).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(status)
}
//redis命令:lset mylist index val
func lset(mylist,val string,index int64){
	status,err := client.LSet(mylist,index,val).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(status)
}
//redis命令:lindex mylist index
func lindex(mylist string,index int64){
	//通过索引查找字符串
	val,err := client.LIndex(mylist,index).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(val)
}
//redis命令:lrange mylist start end
func lrange(mylist string,start,end int64){
	vals,err := client.LRange(mylist,start,end).Result()

	if err != nil {
		log.Fatal(err)
	}

	for k,v := range vals {
		fmt.Printf("k = %v v = %s\n",k,v)
	}
}
//redis命令:llen mylist
func llen(mylist string){
	len,err := client.LLen(mylist).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(len)
}

无序集合set类型数据操作

//无序集合set类型数据操作
//redis命令:sadd myset val1 val2 val3 ...
func sadd(myset,val1,val2,val3 string){
	n,err := client.SAdd(myset,val1,val2,val3).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(n)
}
//redis命令:srem myset val
func srem(myset,val string){
	//删除集合中的值并返回其索引
	index,err := client.SRem(myset,val).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(index)
}
//redis命令:spop myset
func spop(myset string){
	//随机删除一个值并返回
	val,err := client.SPop(myset).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(val)
}
//redis命令:smembers myset
func smembers(myset string){
	vals,err := client.SMembers(myset).Result()

	if err != nil {
		log.Fatal(err)
	}

	for k,v := range vals {
		fmt.Printf("k = %v v = %s\n",k,v)
	}
}
//redis命令:scard myset
func scard(myset string){
	len,err := client.SCard(myset).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(len)
}
//redis命令:sismember myset val
func sismember(myset,val string){
	//判断值是否为集合中的成员
	isMember,err := client.SIsMember(myset,val).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(isMember)
}
//redis命令:srandmember myset count
func srandmembers(myset string,count int64){
	vals,err := client.SRandMemberN(myset,count).Result()

	if err != nil {
		log.Fatal(err)
	}

	for k,v := range vals {
		fmt.Printf("k = %v v = %s\n",k,v)
	}
}
//该函数是上一个函数在只随机取一个元素的情况
func srandmember(myset string){
	val,err := client.SRandMember(myset).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(val)
}
//redis命令:smove myset myset2 val
func smove(myset,myset2,val string){
	isSuccessful,err := client.SMove(myset,myset2,val).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(isSuccessful)
}
//redis命令:sunion myset myset2 ...
func sunion(myset,myset2 string){
	vals,err := client.SUnion(myset,myset2).Result()

	if err != nil {
		log.Fatal(err)
	}

	for k,v := range vals {
		fmt.Printf("k = %v v = %s\n",k,v)
	}
}
//redis命令:sunionstore desset myset myset2 ...
func sunionstore(desset,myset,myset2 string){
	//返回新集合的长度
	n,err := client.SUnionStore(desset,myset,myset2).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(n)
}
//redis命令:sinter myset myset2 ...
func sinter(myset,myset2 string){
	vals,err := client.SInter(myset,myset2).Result()

	if err != nil {
		log.Fatal(err)
	}

	for k,v := range vals {
		fmt.Printf("k = %v v = %s\n",k,v)
	}
}
//redis命令:sinterstore desset myset myset2 ...
func sinterstore(desset,myset,myset2 string){
	n,err := client.SInterStore(desset,myset,myset2).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(n)
}
//redis命令:sdiff myset myset2 ...
func sdiff(myset,myset2 string){
	vals,err := client.SDiff(myset,myset2).Result()

	if err != nil {
		log.Fatal(err)
	}

	for k,v := range vals {
		fmt.Printf("k = %v v = %s\n",k,v)
	}
}
//redis命令:sdiffstore desset myset myset2 ...
func sdiffstore(desset,myset,myset2 string){
	n,err := client.SDiffStore(desset,myset,myset2).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(n)
}

有序集合zset类型数据操作

//有序集合zset类型数据操作
//redis命令:zadd myzset score1 val1 score2 val2 score3 val3 ...
func zadd(myzset,val1,val2,val3 string,score1,score2,score3 float64){
	member1 := &redis.Z{score1,val1}
	member2 := &redis.Z{score2,val2}
	member3 := &redis.Z{score3,val3}

	n,err := client.ZAdd(myzset,member1,member2,member3).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(n)
}
//redis命令:zrem myzset val1 val2 ...
func zrem(myzset,val1,val2 string){
	n,err := client.ZRem(myzset,val1,val2).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(n)
}
//redis命令:srange myzset start end [withscores]
func zrange(myzset string,start,end,flag int64){

	if flag == 0 {
		//不加withscores
		vals,err := client.ZRange(myzset,start,end).Result()

		if err != nil {
			log.Fatal(err)
		}

		for k,v :=range vals {
			fmt.Printf("k = %v v = %s\n",k,v)
		}
	}else if flag == 1 {
		//加withscores
		svals,err := client.ZRangeWithScores(myzset,start,end).Result()

		if err != nil {
			log.Fatal(err)
		}

		for k,v := range svals {
			fmt.Printf("k = %v v = %s s = %.2f\n",k,v.Member,v.Score)
		}
	}
}
//redis命令:srevrange myzset start end [withscores]
func zrevrange(myzset string,start,end,flag int64){
	if flag == 0 {
		//不加withscores
		vals,err := client.ZRevRange(myzset,start,end).Result()

		if err != nil {
			log.Fatal(err)
		}

		for k,v := range vals {
			fmt.Printf("k = %v v = %s\n",k,v)
		}
	}else if flag == 1 {
		//加withscores
		svals,err := client.ZRevRangeWithScores(myzset,start,end).Result()

		if err != nil {
			log.Fatal(err)
		}

		for k,v := range svals {
			fmt.Printf("k = %v v = %s s = %.2f\n",k,v.Member,v.Score)
		}
	}
}
//redis命令:zrangebyscore myzset start end [withscores]
func zrangebyscore(myzset,start,end string,flag int){
	if flag == 0 {
		//不加withscores
		vals,err := client.ZRangeByScore(myzset,&redis.ZRangeBy{Min:start,Max:end,Count:0}).Result()

		if err != nil {
			log.Fatal(err)
		}

		for k,v := range vals {
			fmt.Printf("k = %v v = %s\n",k,v)
		}
	}else if flag == 1 {
		//加withscores
		svals,err := client.ZRangeByScoreWithScores(myzset,&redis.ZRangeBy{Min:start,Max:end,Count:0}).Result()

		if err != nil {
			log.Fatal(err)
		}

		for k,v := range svals {
			fmt.Printf("k = %v v = %s s = %.2f\n",k,v.Member,v.Score)
		}
	}
}
//redis命令:zcard myzset
func zcard(myzset string){
	len,err := client.ZCard(myzset).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(len)
}
//redis命令:zcount myzset minscore maxscore
func zcount(myzset,minscore,maxscore string,){
	n,err := client.ZCount(myzset,minscore,maxscore).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(n)
}
//redis命令:zrank myzset val
func zrank(myzset,val string){
	index,err := client.ZRank(myzset,val).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(index)
}
//redis命令:zscore myzset val
func zscore(myzset,val string){
	score,err := client.ZScore(myzset,val).Result()

	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(score)
}

      以上就是go-redis框架的简单使用,可以看到除了框架本身已经定义好的redis对应操作的对应方法外,还可以自己定制操作方法,从设计上来看还是比较灵活的。与redigo相比个人觉得比较好的地方除了能够灵活地定制方法外,从该框架内置的如set、get等操作的方法的返回值可直观推断出该操作最终会返回什么结果,即使可能存在不了解redis执行该操作之后会返回什么结果,从操作函数的返回值也可推断出来。且写代码过程中无需像redigo一样需要手动地使用redis.Bool,redis.String,redis.Values一般手动转化结果的类型,而是单一个使用Result()方法即可轻易得到结果,简单来说即无需了解某操作会使redis返回什么结果,单一个Result()足以让开发人员推断出结果是什么(是状态字符串还是数字还是值字符串、还是值字符串切片)。但从使用上来看个人觉得不如redigo来的简单明快,毕竟redigo统一一个Do方法,只要知道命令格式即可轻易地操作redis,而且redis官方本身也比较推荐使用redigo。这里仅代表个人意见,并不是说go-redis比redigo差,至于哪个框架比较好用这个因人而异。

你可能感兴趣的:(Golang)