Go语言基础之17--Redis基本操作
一、介绍与连接
1.1 介绍
使用第三方的redis库, github.com/garyburd/redigo/redis
github地址:https://github.com/gomodule/redigo
下载:
go get github.com/garyburd/redigo
1.2 连接redis
package main import (
"fmt" "github.com/garyburd/redigo/redis"
) func initRedis() (conn redis.Conn, err error) { //连接redis函数
conn, err = redis.Dial("tcp", "127.0.0.1:6379") //传递协议、ip、端口
if err != nil {
fmt.Printf("conn redis failed, err:%v\n", err)
return
}
fmt.Printf("connect redis successful!!!\n")
return
} func main() {
conn, err := initRedis()
if err != nil {
return
}
defer conn.Close() //关闭连接
}
执行结果:

二、redis开发
2.1 set操作
package main import (
"fmt" "github.com/garyburd/redigo/redis"
) func initRedis() (conn redis.Conn, err error) { //连接redis函数
conn, err = redis.Dial("tcp", "127.0.0.1:6379") //传递协议、ip、端口
if err != nil {
fmt.Printf("conn redis failed, err:%v\n", err)
return
}
fmt.Printf("connect redis successful!!!\n")
return
} func testSetGet(conn redis.Conn) {
key := "abc"
_, err := conn.Do("set", key, "this is a test") //用do函数来进行redis命令操作
if err != nil {
fmt.Printf("set failed:%s\n", err)
return
} //reply, err := conn.Do("get", "abc") //get返回的是1个空接口,我们不知道里面内容到底什么类型,所以要做一次转换
data, err := redis.String(conn.Do("get", key)) //因为我们知道存的是string,所以转换时是redis.string,如果存的是int,那就是redis.int
if err != nil {
fmt.Printf("get failed, err:%v\n", err)
return
} fmt.Printf("key:%s value:%s\n", key, data)
} func main() {
conn, err := initRedis()
if err != nil {
return
}
defer conn.Close() //关闭连接 testSetGet(conn)
}
执行结果:

2.2 hash表操作
hash表是把一类的数据聚合在一块。比如books表存的都是书籍相关的数据
package main import (
"fmt" "github.com/garyburd/redigo/redis"
) func initRedis() (conn redis.Conn, err error) { //连接redis函数
conn, err = redis.Dial("tcp", "127.0.0.1:6379") //传递协议、ip、端口
if err != nil {
fmt.Printf("conn redis failed, err:%v\n", err)
return
}
fmt.Printf("connect redis successful!!!\n")
return
} func testHSetGet(conn redis.Conn) {
key := "abc"
_, err := conn.Do("hset", "books", key, "this is a test") //books是哈希表名 其中存的是一条条key-value
if err != nil {
fmt.Printf("set failed:%s\n", err)
return
} //reply, err := conn.Do("get", "abc")
data, err := redis.String(conn.Do("hget", "books", key))
if err != nil {
fmt.Printf("get failed, err:%v\n", err)
return
} fmt.Printf("key:%s value:%s\n", key, data)
} func main() {
conn, err := initRedis()
if err != nil {
return
}
defer conn.Close() //关闭连接 testHSetGet(conn)
}
执行结果:

2.3 mset操作
并发批量操作
package main import (
"fmt" "github.com/garyburd/redigo/redis"
) func initRedis() (conn redis.Conn, err error) { //连接redis函数
conn, err = redis.Dial("tcp", "127.0.0.1:6379") //传递协议、ip、端口
if err != nil {
fmt.Printf("conn redis failed, err:%v\n", err)
return
}
fmt.Printf("connect redis successful!!!\n")
return
} func testMSetGet(conn redis.Conn) {
key := "abc"
key1 := "efg"
_, err := conn.Do("mset", key, "this is a test", key1, "ksksksksks") //一次设置多个key
if err != nil {
fmt.Printf("set failed:%s\n", err)
return
} //reply, err := conn.Do("get", "abc")
data, err := redis.Strings(conn.Do("mget", key, key1)) //一次读取多个 。返回的data是1个切片,这里用strings函数
if err != nil {
fmt.Printf("get failed, err:%v\n", err)
return
}
for _, val := range data { //遍历出来
fmt.Printf(" value:%s\n", val)
}
} func main() {
conn, err := initRedis()
if err != nil {
return
}
defer conn.Close() //关闭连接 testMSetGet(conn)
}
执行结果:

2.4 设置过期时间
package main import (
"fmt" "github.com/garyburd/redigo/redis"
) func initRedis() (conn redis.Conn, err error) { //连接redis函数
conn, err = redis.Dial("tcp", "127.0.0.1:6379") //传递协议、ip、端口
if err != nil {
fmt.Printf("conn redis failed, err:%v\n", err)
return
}
fmt.Printf("connect redis successful!!!\n")
return
} func testExpire(conn redis.Conn) {
_, err := conn.Do("expire", "abc", ) //设置key为abc的过期时间为20s
if err != nil {
fmt.Println(err)
return
}
} func main() {
conn, err := initRedis()
if err != nil {
return
}
defer conn.Close() //关闭连接 testExpire(conn)
}
执行结果:

2.5 队列和栈操作
有4个方法:
lpush:左入队
rpush:右入队
lpop:左出队
rpop:右出队
队列:先进先出
栈:先进后出
队列实例:
package main import (
"fmt" "github.com/garyburd/redigo/redis"
) func initRedis() (conn redis.Conn, err error) { //连接redis函数
conn, err = redis.Dial("tcp", "127.0.0.1:6379") //传递协议、ip、端口
if err != nil {
fmt.Printf("conn redis failed, err:%v\n", err)
return
}
fmt.Printf("connect redis successful!!!\n")
return
} func testList(conn redis.Conn) { _, err := conn.Do("lpush", "book_list", "this is a test", "ksksksksks") //左边进 第二个参数book_lsit是队列名
if err != nil {
fmt.Printf("set failed:%s\n", err)
return
} //reply, err := conn.Do("get", "abc")
data, err := redis.String(conn.Do("rpop", "book_list")) //右边出,一次只能出队一个元素
if err != nil {
fmt.Printf("get failed, err:%v\n", err)
return
} fmt.Printf(" value:%s\n", data)
} func main() {
conn, err := initRedis()
if err != nil {
return
}
defer conn.Close() //关闭连接 testList(conn)
}
执行结果:

栈操作实例:
package main import (
"fmt" "github.com/garyburd/redigo/redis"
) func initRedis() (conn redis.Conn, err error) { //连接redis函数
conn, err = redis.Dial("tcp", "127.0.0.1:6379") //传递协议、ip、端口
if err != nil {
fmt.Printf("conn redis failed, err:%v\n", err)
return
}
fmt.Printf("connect redis successful!!!\n")
return
} func testList(conn redis.Conn) { _, err := conn.Do("lpush", "book_stack", "this is a test", "ksksksksks") //左边进 第二个参数book_lsit是队列名
if err != nil {
fmt.Printf("set failed:%s\n", err)
return
} //reply, err := conn.Do("get", "abc")
data, err := redis.String(conn.Do("lpop", "book_list")) //左边出,一次只能出队一个元素
if err != nil {
fmt.Printf("get failed, err:%v\n", err)
return
} fmt.Printf(" value:%s\n", data)
} func main() {
conn, err := initRedis()
if err != nil {
return
}
defer conn.Close() //关闭连接 testList(conn)
}
执行结果:

2.6 redis连接池
之前实例都是单个连接,拿到1个连接,针对连接进行操作,如果是1个并发的程序,1个连接是不够的,并且会有线程安全的问题,但是我们可以用连接池来解决。
package main import (
"fmt"
"time" "github.com/garyburd/redigo/redis"
) func initRedis() (conn redis.Conn, err error) { //连接redis函数
conn, err = redis.Dial("tcp", "127.0.0.1:6379") //传递协议、ip、端口
if err != nil {
fmt.Printf("conn redis failed, err:%v\n", err)
return
}
fmt.Printf("connect redis successful!!!\n")
return
} func newPool(serverAddr string, passwd string) (pool *redis.Pool) { //第一个参数是服务的地址,第二个是连接时的密码(就是redis的密码)
return &redis.Pool{ //返回1个结构体的连接池对象
MaxIdle: , //空闲连接数,即使没有连接请求,也会有空闲连接数在连接池中
MaxActive: , //活跃连接数,也就是最大连接数
IdleTimeout: * time.Second, //空闲连接数超时时间,连接数超时了就会被释放掉
Dial: func() (redis.Conn, error) { //匿名函数类型变量,用来连接redis
fmt.Printf("create conn\n")
conn, err := redis.Dial("tcp", serverAddr)
if err != nil {
return nil, err
} if len(passwd) > {
_, err = conn.Do("auth", passwd)
if err != nil {
return nil, err
}
}
return conn, err
},
TestOnBorrow: func(c redis.Conn, t time.Time) error { //匿名函数类型变量,作用:如果从连接池获取连接时,会验证一下这个连接是不是可用的。
fmt.Printf("verify conn\n") //验证连接 if time.Since(t) < time.Minute { //如果1分钟之内就不验证了,频繁的ping会影响性能
return nil
}
fmt.Printf("ping conn\n")
_, err := c.Do("ping")
return err
},
}
} func testRedisPool() {
pool := newPool("127.0.0.1:6379", "") conn := pool.Get() //获取1个连接
conn.Do("set", "abc", "") val, err := redis.String(conn.Do("get", "abc"))
fmt.Printf("val:%s err:%v\n", val, err) //把连接归还到连接池,并不是关闭连接
conn.Close() fmt.Printf("==========================\n")
conn = pool.Get()
conn.Do("set", "abc", "") val, err = redis.String(conn.Do("get", "abc"))
fmt.Printf("val:%s err:%v\n", val, err) //把连接归还到连接池
conn.Close()
} func main() {
testRedisPool()
}
执行结果:

解释:
我们可以发现第一次我们get是建立了连接,在使用完之后close(将该连接归还到连接池了),紧接着下面一个请求,get并没有建立新的连接,而是使用了连接池中刚刚归还的连接,并且因为小于我们的设定时间,也没有去ping redis
三、参考网址
https://www.jianshu.com/p/89ca34b84101
https://studygolang.com/articles/6107
Go语言基础之17--Redis基本操作的更多相关文章
- Go语言基础之15--文件基本操作
一.文件读写 1.1 os.File os.File封装所有文件相关操作, 是一个自定义的struct. a. 打开一个文件进行读操作: os.Open(name string) (*File, er ...
- Go语言基础之操作Redis
Go语言操作Redis 在项目开发中redis的使用也比较频繁,本文介绍了Go语言如何操作Redis. Redis介绍 Redis是一个开源的内存数据库,Redis提供了5种不同类型的数据结构,很多业 ...
- GO学习-(17) Go语言基础之反射
Go语言基础之反射 本文介绍了Go语言反射的意义和基本使用. 变量的内在机制 Go语言中的变量是分为两部分的: 类型信息:预先定义好的元信息. 值信息:程序运行过程中可动态变化的. 反射介绍 反射是指 ...
- Redis基本操作——List
Redis基本操作——List(原理篇) 学习过数据结构的同学,一定对链表(Linked List)十分的熟悉.相信我们自己也曾经使用过这种数据结构. 链表分为很多种:单向链表,双向链表,循环链表,块 ...
- 三、Redis基本操作——List
小喵的唠叨话:前面我们介绍了Redis的string的数据结构的原理和操作.当时我们提到Redis的键值对不仅仅是字符串.而这次我们就要介绍Redis的第二个数据结构了,List(链表).由于List ...
- 二、Redis基本操作——String(实战篇)
小喵万万没想到,上一篇博客,居然已经被阅读600次了!!!让小喵感觉压力颇大.万一有写错的地方,岂不是会误导很多筒子们.所以,恳请大家,如果看到小喵的博客有什么不对的地方,请尽快指正!谢谢! 小喵的唠 ...
- Redis基本操作-20150608
Redis基本操作-20150608 [http://my.oschina.net/u/241255/blog/206991] Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存 ...
- 单片机教程4.C语言基础以及流水灯的实现
单片机教程4.C语言基础以及流水灯的实现 C语言,没接触过计算机编程语言的人会把它看的很神秘,感觉非常的难,而在我看来,C语言的逻辑和运算,就是小学水平,所以大家不要怕它,我尽可能的从小学数学逻辑方式 ...
- Python语言基础与应用 (P16)上机练习:基本数据类型
本文是笔者在学习MOOC课程<Python语言基础与应用> (北京大学-陈斌)中根据上机课时的要求写下在代码 课程总链接: 中国大学MOOC B站 本节课链接 数值基本运算: 33和7+, ...
- C 语言基础,来喽!
前言 C 语言是一门抽象的.面向过程的语言,C 语言广泛应用于底层开发,C 语言在计算机体系中占据着不可替代的作用,可以说 C 语言是编程的基础,也就是说,不管你学习任何语言,都应该把 C 语言放在首 ...
随机推荐
- 关于taskaffinity属性的作用
意味着这activity更喜欢哪个TESK,具体见下方说明 当一个包含FLAG_ACTIVITY_NEW_TASK标志的intent启动一个activity时. 一个新的activity,默认地启动到 ...
- Windows版本Apache+php的Xhprof应用__[2]
[计划] “Windows版本Apache+php的Xhprof应用__[1]”中已经解决了下载,配置的问题,所以这里的工作是接着进行的,我们以调试一个 php代码的文件来看看是怎么用xhprof的. ...
- 04 UUID
1 什么是UUID UUID 的目的是让分布式系统中的所有元素,都能有唯一的辨识资讯,而不需要透过中央控制端来做辨识资讯的指定. 2 应用场景 MySQL数据库不能想oracle数据库那样创建序列,就 ...
- .NET回归 HTML----表单元素(1)和一些常用的标记
表单就是-----用于搜集不同类型的用户输入. 表单元素指的是不同类型的 input 元素.复选框.单选按钮.提交按钮等等. 首先将表单元素分为三个类型.文本类,按钮类,选择类. 表单可以嵌套在表中, ...
- Boost中实现线程安全
博客转载自: http://www.cnblogs.com/lvdongjie/p/4447142.html 1 boost原子变量和线程 #include <boost/thread.hpp& ...
- ZROI2018提高day3t2
传送门 分析 我们设A[i]表示点i有几个矿,B[i]表示这之中有几个矿是第一次出现,所以点i的贡献即为 (2^B[i]-1)*(2^(A[i]-B[i])) 注意减一的原因是第一次出现的矿应至少有一 ...
- 1.初学c++,比较困惑的问题。
1.c++是一门实用的语言吗? c++是一个实用的工具,它很有用. 在工业软件世界中,c++被视为坚实和成熟的主流工具.它具有广泛的行业支持和好批. 2.面向对象编程在c++中的作用? 我们要开发一个 ...
- struts学习记录
see also:http://blog.csdn.net/chenggil10/article/details/5965806#_Toc250472631 0.struts2每一个请求,都new一个 ...
- Java50道经典习题-程序41 猴子分桃
题目:海滩上有一堆桃子,五只猴子来分.第一只猴子把这堆桃子凭据分为五份,多了一个,这只猴子把多的一个扔入海中,拿走了一份.第二只猴子把剩下的桃子又平均分成五份,又多了一个,它同样把多的一个扔入海中,拿 ...
- asp 控件定时器 局部刷新
<asp:ScriptManager ID="ScriptManager1" runat="server" /> <asp:UpdatePan ...