Go核心开发学习笔记(三十一) —— Golang操作Redis

Redis安装和基本原理请查阅相关资料学习。

Redis基础知识和开发使用:

1. 0 - 15 共计16个库。
2. 典型的KV存储方式。
3. 常用操作命令:
(1) 添加kv: set
(2) 查找所有key: keys <pattern正则>
(3) 查找key对应的value: get
(4) 切换数据库: select <num 0-15>
(5) 查看key-value数量: dbsize (无参数为当前库)
(6) 清空数据库: flushdb(当前库) ; flushall(所有库)
4. 五种数据类型: String,hash(类字典,多对kv),list,set,zset(有序集合):

  • (1) String:
    redis最基本类型,kv对;
    二进制存放,除了字符串还能放图片等数据,程序读出来没有问题,二进制保存中文。
    字符串value最大值512MB;
    setex(set with expire): setex <keyname> <n seconds> <value> //多少秒过后,这个value就被销毁了; mset(多个kv对设置): mset <k1> <v1> <k2> <k2> //如何获得: mget <k1> <k2>。

  • (2) Hash:
    键值对集合,类似字典,var golang map[string]string;
    特别适合用于存储对象,也就是golang中的结构体;
    hset cxk hobby sing ; hset cxk name caixukun // hget cxk name 就能取到name对应的value。 hmset cxk name caixk age 20 song "鸡你太美" // hmget cxk name age song 一次取到设置并取多个字段的values。 hlen cxk //查看Hash元素有多少个。 hexists cxk song //查看cxk这个hash中是否有song这个字段。

  • (3) List:
    简单的字符串列表,按照插入顺序进行排序,可以添加一个元素到列表头部或者尾部;
    List本质是一个链表,List的元素是有序的(List[n]),元素值可以重复;
    注意lpop/rpop用法很常见;lpush类似压栈,rpush类似队列。

  • (4) Set (Zset同理):
    Set是string类型的无序集合;
    底层是Hashtable数据结构,存放很多字符串元素,字符串元素是无序的,而且元素值不能重复,适合存放例如员工ID号,电子邮件,电话号码,QQ号等唯一不重复的内容;
    sadd emails [email protected] [email protected] //创建并添加集合的k名和v的内容; smembers emails //遍历所有集合中的内容; sismenber emails damn //检查集合中是否存在damn,有返回1,没有就返回0; srem emails [email protected] //删除集合中指定值;

5. 数据类型与CRUD:
(1) String:
CU: set <keyname> <valuename> //set的key没有就创建,有就修改
D:del <keyname>
R:get <keyname>
(2) Hash:
CU: hset <hashname> <keyname> <valuename>
R: hget <hashname> <keyname> ; hgetall
D: hdel <hashname>
(3) List:
CU: lpush/rpush <listname> value1 value2 value3 … // left right 分别插入数据
lpop/rpop <listname> // 左取/右取 各一个元素
R: lrange <listname> [起始数字] [结束数字] // 只有左边开始显示从起始0到末尾-1中的一段数据
lindex <listname> <index> // 通过下标拿到list中对应的元素值
llen <listname> // 查看元素个数
D: del <listname>
(4) Set:
CU: sadd <keyname> <value1> <value2>
R: smembers <keyname> //遍历所有值;
sismember <keyname> <dest-value> //是否存在x,存在1,不存在0;
D: srem <keyname> <dest-value> //删除成功返回1,不成功返回0;

通过Golang如何操作redis

  1. 保证系统中安装了git
  2. 切换至GOPATH目录下: “go get github.com\garyburd\redigo\redis” 中可以下载相关的redis包到src下,从而import redis包,使用相关的属性和方法。

案例1:Golang操作redis,以string字符串说明,其余数据类型传递参数与redis命令行一模一样:

package main

import (
	"fmt"
"github.com/garyburd/redigo/redis"
)

func main() {
	//连接数据库
	conn, err := redis.Dial("tcp","127.0.0.1:6379")
	if err != nil {
		fmt.Println("连接失败,错误为:",err)
		return
	}
	defer conn.Close()

	//添加一对键值对,我们所需要的仅仅是添加结果成功就可以,无需返回值
	_, err = conn.Do("set", "email", "damn")      //conn.Do()用的是最多的,把命令行中的args一个个写进去
	if err != nil {
		fmt.Println("设置kv失败,错误原因为:",err)
		return
	}

	_, err = conn.Do("setex", "email1", 10,"shit")      //conn.Do()用的是最多的,把命令行中的args一个个写进去
	if err != nil {
		fmt.Println("设置kv失败,错误原因为:",err)
		return
	}

	//取得一个键对应的一个值,判断获取的值得类型为xx
	//get返回时空接口类型,使用断言报错,直接使用redis提供的转换方法即可
	res, err := redis.String(conn.Do("get","email"))
	if err != nil {
		fmt.Println("获取key失败,错误原因为:",err)
		return
	}
	fmt.Println(res)
}

案例2:Golang操作redis,hash字符串的使用

package main

import (
	"fmt"
"github.com/garyburd/redigo/redis"
)

func main() {
	//连接数据库
	conn, err := redis.Dial("tcp","127.0.0.1:6379")
	if err != nil {
		fmt.Println("连接失败,错误为:",err)
		return
	}
	defer conn.Close()

	//添加一个hash
	_, err = conn.Do("hmset", "hhash", "name","damn","age",27)
	if err != nil {
		fmt.Println("设置kv失败,错误原因为:",err)
		return
	}
	//取得一个键对应的一个值,判断获取的值得类型为xx
	//get返回时空接口类型,使用断言报错,直接使用redis提供的转换方法即可
	res, err := redis.Strings(conn.Do("hmget","hhash","name","age"))  //注意这里变为Strings
	if err != nil {
		fmt.Println("获取key失败,错误原因为:",err)
		return
	}
	for i, v := range res {  //res应该是集合类数据,在golang中也应该是数组切片之类的。
		fmt.Println(v)      //遍历的方式,也可以带上索引或者不带
	}
}

Redis连接池

  1. 实现初始化一定数量的链接,放入链接池;
  2. Go需要操作redis时,直接从链接池取出链接即可;
  3. 这样可以节省临时获取redis链接的时间,从而提高效率。

案例:init()创立redis链接池,后面代码直接从链接池中取得链接资源并进行读写

package main

import (
	"fmt"
	"github.com/garyburd/redigo/redis"
)

var pool *redis.Pool
/*
	type Pool struct {
		Dial func() (Conn, error)
		// Maximum number of idle connections in the pool.
		MaxIdle 8       //最大空闲数为8
		MaxActive 0      //0表示无限制链接,支持最高并发数
		IdleTimeout 100 //time.Duration
	}
*/

func init() {      //初始化函数,执行main之前优先创建链接池,链接池的意义在于迅速响应go链接,不用从头开始建立tcp链接

	pool =  &redis.Pool{

		Dial: func() (redis.Conn, error){
			return redis.Dial("tcp","127.0.0.1:6379")
			},
		MaxIdle: 8,       //最大空闲数为8
		MaxActive: 0,      //0表示无限制链接,支持最高并发数
		IdleTimeout: 100, //time.Duration
		}
}

func main() {
	//从创建好的链接池中取出一个链接
	/*
	func (p *Pool) Get() Conn {
		pc, err := p.get(nil)
		if err != nil {
			return errorConn{err}
		}
		return &activeConn{p: p, pc: pc}
	}
	 */
	conn := pool.Get()   //从redis链接池中取出一个链接,和之前redis.Dial是一个意思
	defer conn.Close()   //开销类资源一定要使用defer关闭,如果要取值一定要保证链接池开启,关闭后 get on closed pool报错

	//链接redis,创建添加一个kv,并查询kv
	_, err := conn.Do("Set","cxk","鸡你太美")
	if err != nil {
		fmt.Println("SET 添加字段有误,错误为:",err)
		return
	}

	ret, err1 := redis.String(conn.Do("Get","cxk"))
	if err1 != nil {
		fmt.Println("GET 读取字段有误,错误为:",err1)
		return
	}
	fmt.Println("Get 取值为:",ret)    //Get 取值为: 鸡你太美
}
发布了49 篇原创文章 · 获赞 18 · 访问量 3994

猜你喜欢

转载自blog.csdn.net/weixin_41047549/article/details/90701111