一、介绍与连接

1.1 介绍

使用第三方的redis库, github.com/garyburd/redigo/redis

github地址:https://github.com/gomodule/redigo

下载:

  1. go get github.com/garyburd/redigo

1.2 连接redis

  1. package main
  2.  
  3. import (
  4. "fmt"
  5.  
  6. "github.com/garyburd/redigo/redis"
  7. )
  8.  
  9. func initRedis() (conn redis.Conn, err error) { //连接redis函数
  10. conn, err = redis.Dial("tcp", "127.0.0.1:6379") //传递协议、ip、端口
  11. if err != nil {
  12. fmt.Printf("conn redis failed, err:%v\n", err)
  13. return
  14. }
  15. fmt.Printf("connect redis successful!!!\n")
  16. return
  17. }
  18.  
  19. func main() {
  20. conn, err := initRedis()
  21. if err != nil {
  22. return
  23. }
  24. defer conn.Close() //关闭连接
  25. }

执行结果:

二、redis开发

2.1 set操作

  1. package main
  2.  
  3. import (
  4. "fmt"
  5.  
  6. "github.com/garyburd/redigo/redis"
  7. )
  8.  
  9. func initRedis() (conn redis.Conn, err error) { //连接redis函数
  10. conn, err = redis.Dial("tcp", "127.0.0.1:6379") //传递协议、ip、端口
  11. if err != nil {
  12. fmt.Printf("conn redis failed, err:%v\n", err)
  13. return
  14. }
  15. fmt.Printf("connect redis successful!!!\n")
  16. return
  17. }
  18.  
  19. func testSetGet(conn redis.Conn) {
  20. key := "abc"
  21. _, err := conn.Do("set", key, "this is a test") //用do函数来进行redis命令操作
  22. if err != nil {
  23. fmt.Printf("set failed:%s\n", err)
  24. return
  25. }
  26.  
  27. //reply, err := conn.Do("get", "abc") //get返回的是1个空接口,我们不知道里面内容到底什么类型,所以要做一次转换
  28. data, err := redis.String(conn.Do("get", key)) //因为我们知道存的是string,所以转换时是redis.string,如果存的是int,那就是redis.int
  29. if err != nil {
  30. fmt.Printf("get failed, err:%v\n", err)
  31. return
  32. }
  33.  
  34. fmt.Printf("key:%s value:%s\n", key, data)
  35. }
  36.  
  37. func main() {
  38. conn, err := initRedis()
  39. if err != nil {
  40. return
  41. }
  42. defer conn.Close() //关闭连接
  43.  
  44. testSetGet(conn)
  45. }

执行结果:

2.2 hash表操作

hash表是把一类的数据聚合在一块。比如books表存的都是书籍相关的数据

  1. package main
  2.  
  3. import (
  4. "fmt"
  5.  
  6. "github.com/garyburd/redigo/redis"
  7. )
  8.  
  9. func initRedis() (conn redis.Conn, err error) { //连接redis函数
  10. conn, err = redis.Dial("tcp", "127.0.0.1:6379") //传递协议、ip、端口
  11. if err != nil {
  12. fmt.Printf("conn redis failed, err:%v\n", err)
  13. return
  14. }
  15. fmt.Printf("connect redis successful!!!\n")
  16. return
  17. }
  18.  
  19. func testHSetGet(conn redis.Conn) {
  20. key := "abc"
  21. _, err := conn.Do("hset", "books", key, "this is a test") //books是哈希表名 其中存的是一条条key-value
  22. if err != nil {
  23. fmt.Printf("set failed:%s\n", err)
  24. return
  25. }
  26.  
  27. //reply, err := conn.Do("get", "abc")
  28. data, err := redis.String(conn.Do("hget", "books", key))
  29. if err != nil {
  30. fmt.Printf("get failed, err:%v\n", err)
  31. return
  32. }
  33.  
  34. fmt.Printf("key:%s value:%s\n", key, data)
  35. }
  36.  
  37. func main() {
  38. conn, err := initRedis()
  39. if err != nil {
  40. return
  41. }
  42. defer conn.Close() //关闭连接
  43.  
  44. testHSetGet(conn)
  45. }

执行结果:

2.3 mset操作

并发批量操作

  1. package main
  2.  
  3. import (
  4. "fmt"
  5.  
  6. "github.com/garyburd/redigo/redis"
  7. )
  8.  
  9. func initRedis() (conn redis.Conn, err error) { //连接redis函数
  10. conn, err = redis.Dial("tcp", "127.0.0.1:6379") //传递协议、ip、端口
  11. if err != nil {
  12. fmt.Printf("conn redis failed, err:%v\n", err)
  13. return
  14. }
  15. fmt.Printf("connect redis successful!!!\n")
  16. return
  17. }
  18.  
  19. func testMSetGet(conn redis.Conn) {
  20. key := "abc"
  21. key1 := "efg"
  22. _, err := conn.Do("mset", key, "this is a test", key1, "ksksksksks") //一次设置多个key
  23. if err != nil {
  24. fmt.Printf("set failed:%s\n", err)
  25. return
  26. }
  27.  
  28. //reply, err := conn.Do("get", "abc")
  29. data, err := redis.Strings(conn.Do("mget", key, key1)) //一次读取多个 。返回的data是1个切片,这里用strings函数
  30. if err != nil {
  31. fmt.Printf("get failed, err:%v\n", err)
  32. return
  33. }
  34. for _, val := range data { //遍历出来
  35. fmt.Printf(" value:%s\n", val)
  36. }
  37. }
  38.  
  39. func main() {
  40. conn, err := initRedis()
  41. if err != nil {
  42. return
  43. }
  44. defer conn.Close() //关闭连接
  45.  
  46. testMSetGet(conn)
  47. }

执行结果:

2.4 设置过期时间

  1. package main
  2.  
  3. import (
  4. "fmt"
  5.  
  6. "github.com/garyburd/redigo/redis"
  7. )
  8.  
  9. func initRedis() (conn redis.Conn, err error) { //连接redis函数
  10. conn, err = redis.Dial("tcp", "127.0.0.1:6379") //传递协议、ip、端口
  11. if err != nil {
  12. fmt.Printf("conn redis failed, err:%v\n", err)
  13. return
  14. }
  15. fmt.Printf("connect redis successful!!!\n")
  16. return
  17. }
  18.  
  19. func testExpire(conn redis.Conn) {
  20. _, err := conn.Do("expire", "abc", ) //设置key为abc的过期时间为20s
  21. if err != nil {
  22. fmt.Println(err)
  23. return
  24. }
  25. }
  26.  
  27. func main() {
  28. conn, err := initRedis()
  29. if err != nil {
  30. return
  31. }
  32. defer conn.Close() //关闭连接
  33.  
  34. testExpire(conn)
  35. }

执行结果:

2.5 队列和栈操作

有4个方法:

lpush:左入队

rpush:右入队

lpop:左出队

rpop:右出队

队列:先进先出

栈:先进后出

队列实例:

  1. package main
  2.  
  3. import (
  4. "fmt"
  5.  
  6. "github.com/garyburd/redigo/redis"
  7. )
  8.  
  9. func initRedis() (conn redis.Conn, err error) { //连接redis函数
  10. conn, err = redis.Dial("tcp", "127.0.0.1:6379") //传递协议、ip、端口
  11. if err != nil {
  12. fmt.Printf("conn redis failed, err:%v\n", err)
  13. return
  14. }
  15. fmt.Printf("connect redis successful!!!\n")
  16. return
  17. }
  18.  
  19. func testList(conn redis.Conn) {
  20.  
  21. _, err := conn.Do("lpush", "book_list", "this is a test", "ksksksksks") //左边进 第二个参数book_lsit是队列名
  22. if err != nil {
  23. fmt.Printf("set failed:%s\n", err)
  24. return
  25. }
  26.  
  27. //reply, err := conn.Do("get", "abc")
  28. data, err := redis.String(conn.Do("rpop", "book_list")) //右边出,一次只能出队一个元素
  29. if err != nil {
  30. fmt.Printf("get failed, err:%v\n", err)
  31. return
  32. }
  33.  
  34. fmt.Printf(" value:%s\n", data)
  35. }
  36.  
  37. func main() {
  38. conn, err := initRedis()
  39. if err != nil {
  40. return
  41. }
  42. defer conn.Close() //关闭连接
  43.  
  44. testList(conn)
  45. }

执行结果:

栈操作实例:

  1. package main
  2.  
  3. import (
  4. "fmt"
  5.  
  6. "github.com/garyburd/redigo/redis"
  7. )
  8.  
  9. func initRedis() (conn redis.Conn, err error) { //连接redis函数
  10. conn, err = redis.Dial("tcp", "127.0.0.1:6379") //传递协议、ip、端口
  11. if err != nil {
  12. fmt.Printf("conn redis failed, err:%v\n", err)
  13. return
  14. }
  15. fmt.Printf("connect redis successful!!!\n")
  16. return
  17. }
  18.  
  19. func testList(conn redis.Conn) {
  20.  
  21. _, err := conn.Do("lpush", "book_stack", "this is a test", "ksksksksks") //左边进 第二个参数book_lsit是队列名
  22. if err != nil {
  23. fmt.Printf("set failed:%s\n", err)
  24. return
  25. }
  26.  
  27. //reply, err := conn.Do("get", "abc")
  28. data, err := redis.String(conn.Do("lpop", "book_list")) //左边出,一次只能出队一个元素
  29. if err != nil {
  30. fmt.Printf("get failed, err:%v\n", err)
  31. return
  32. }
  33.  
  34. fmt.Printf(" value:%s\n", data)
  35. }
  36.  
  37. func main() {
  38. conn, err := initRedis()
  39. if err != nil {
  40. return
  41. }
  42. defer conn.Close() //关闭连接
  43.  
  44. testList(conn)
  45. }

执行结果:

2.6 redis连接池

之前实例都是单个连接,拿到1个连接,针对连接进行操作,如果是1个并发的程序,1个连接是不够的,并且会有线程安全的问题,但是我们可以用连接池来解决。

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "time"
  6.  
  7. "github.com/garyburd/redigo/redis"
  8. )
  9.  
  10. func initRedis() (conn redis.Conn, err error) { //连接redis函数
  11. conn, err = redis.Dial("tcp", "127.0.0.1:6379") //传递协议、ip、端口
  12. if err != nil {
  13. fmt.Printf("conn redis failed, err:%v\n", err)
  14. return
  15. }
  16. fmt.Printf("connect redis successful!!!\n")
  17. return
  18. }
  19.  
  20. func newPool(serverAddr string, passwd string) (pool *redis.Pool) { //第一个参数是服务的地址,第二个是连接时的密码(就是redis的密码)
  21. return &redis.Pool{ //返回1个结构体的连接池对象
  22. MaxIdle: , //空闲连接数,即使没有连接请求,也会有空闲连接数在连接池中
  23. MaxActive: , //活跃连接数,也就是最大连接数
  24. IdleTimeout: * time.Second, //空闲连接数超时时间,连接数超时了就会被释放掉
  25. Dial: func() (redis.Conn, error) { //匿名函数类型变量,用来连接redis
  26. fmt.Printf("create conn\n")
  27. conn, err := redis.Dial("tcp", serverAddr)
  28. if err != nil {
  29. return nil, err
  30. }
  31.  
  32. if len(passwd) > {
  33. _, err = conn.Do("auth", passwd)
  34. if err != nil {
  35. return nil, err
  36. }
  37. }
  38. return conn, err
  39. },
  40. TestOnBorrow: func(c redis.Conn, t time.Time) error { //匿名函数类型变量,作用:如果从连接池获取连接时,会验证一下这个连接是不是可用的。
  41. fmt.Printf("verify conn\n") //验证连接
  42.  
  43. if time.Since(t) < time.Minute { //如果1分钟之内就不验证了,频繁的ping会影响性能
  44. return nil
  45. }
  46. fmt.Printf("ping conn\n")
  47. _, err := c.Do("ping")
  48. return err
  49. },
  50. }
  51. }
  52.  
  53. func testRedisPool() {
  54. pool := newPool("127.0.0.1:6379", "")
  55.  
  56. conn := pool.Get() //获取1个连接
  57. conn.Do("set", "abc", "")
  58.  
  59. val, err := redis.String(conn.Do("get", "abc"))
  60. fmt.Printf("val:%s err:%v\n", val, err)
  61.  
  62. //把连接归还到连接池,并不是关闭连接
  63. conn.Close()
  64.  
  65. fmt.Printf("==========================\n")
  66. conn = pool.Get()
  67. conn.Do("set", "abc", "")
  68.  
  69. val, err = redis.String(conn.Do("get", "abc"))
  70. fmt.Printf("val:%s err:%v\n", val, err)
  71.  
  72. //把连接归还到连接池
  73. conn.Close()
  74. }
  75.  
  76. func main() {
  77. testRedisPool()
  78. }

执行结果:

解释:

我们可以发现第一次我们get是建立了连接,在使用完之后close(将该连接归还到连接池了),紧接着下面一个请求,get并没有建立新的连接,而是使用了连接池中刚刚归还的连接,并且因为小于我们的设定时间,也没有去ping redis

三、参考网址

https://www.jianshu.com/p/89ca34b84101

https://studygolang.com/articles/6107

Go语言基础之17--Redis基本操作的更多相关文章

  1. Go语言基础之15--文件基本操作

    一.文件读写 1.1 os.File os.File封装所有文件相关操作, 是一个自定义的struct. a. 打开一个文件进行读操作: os.Open(name string) (*File, er ...

  2. Go语言基础之操作Redis

    Go语言操作Redis 在项目开发中redis的使用也比较频繁,本文介绍了Go语言如何操作Redis. Redis介绍 Redis是一个开源的内存数据库,Redis提供了5种不同类型的数据结构,很多业 ...

  3. GO学习-(17) Go语言基础之反射

    Go语言基础之反射 本文介绍了Go语言反射的意义和基本使用. 变量的内在机制 Go语言中的变量是分为两部分的: 类型信息:预先定义好的元信息. 值信息:程序运行过程中可动态变化的. 反射介绍 反射是指 ...

  4. Redis基本操作——List

    Redis基本操作——List(原理篇) 学习过数据结构的同学,一定对链表(Linked List)十分的熟悉.相信我们自己也曾经使用过这种数据结构. 链表分为很多种:单向链表,双向链表,循环链表,块 ...

  5. 三、Redis基本操作——List

    小喵的唠叨话:前面我们介绍了Redis的string的数据结构的原理和操作.当时我们提到Redis的键值对不仅仅是字符串.而这次我们就要介绍Redis的第二个数据结构了,List(链表).由于List ...

  6. 二、Redis基本操作——String(实战篇)

    小喵万万没想到,上一篇博客,居然已经被阅读600次了!!!让小喵感觉压力颇大.万一有写错的地方,岂不是会误导很多筒子们.所以,恳请大家,如果看到小喵的博客有什么不对的地方,请尽快指正!谢谢! 小喵的唠 ...

  7. Redis基本操作-20150608

    Redis基本操作-20150608 [http://my.oschina.net/u/241255/blog/206991]   Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存 ...

  8. 单片机教程4.C语言基础以及流水灯的实现

    单片机教程4.C语言基础以及流水灯的实现 C语言,没接触过计算机编程语言的人会把它看的很神秘,感觉非常的难,而在我看来,C语言的逻辑和运算,就是小学水平,所以大家不要怕它,我尽可能的从小学数学逻辑方式 ...

  9. Python语言基础与应用 (P16)上机练习:基本数据类型

    本文是笔者在学习MOOC课程<Python语言基础与应用> (北京大学-陈斌)中根据上机课时的要求写下在代码 课程总链接: 中国大学MOOC B站 本节课链接 数值基本运算: 33和7+, ...

  10. C 语言基础,来喽!

    前言 C 语言是一门抽象的.面向过程的语言,C 语言广泛应用于底层开发,C 语言在计算机体系中占据着不可替代的作用,可以说 C 语言是编程的基础,也就是说,不管你学习任何语言,都应该把 C 语言放在首 ...

随机推荐

  1. cookie禁用后重定向跳转时session的跟踪

  2. 每天一道算法题(12)——和为n的连续正数序列或者随机数

    题目:输入一个正数n,输出所有和为n 连续正数序列.例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以输出3 个连续序列1-5.4-6 和7-8. 1.思路 尊崇以下策略: (1)对 ...

  3. 【总结整理】WebGIS学习-thinkGIS(地理常识):

    ##地图知识 ###地图定义 地图是按照一定的法则,有选择地以二维或多维形式与手段在平面或球面上表示地球(或其它星球)若干现象的图形或图像,它具有严格的数学基础.符号系统.文字注记,并能用地图概括原则 ...

  4. Java元注解,简单案例

    [注解] 程序中有 注释 和注解 * 注释:给开发人员. * 注解:给计算机看的. 注解使用:学习框架支持注解开发. [JDK提供的注解] @Override :描述方法的重写. @SuppressW ...

  5. NSWindow上添加NSView

    DBSCustomView *view = [[DBSCustomView alloc] initWithFrame:NSMakeRect(100, 100, 100, 100)]; [self.wi ...

  6. ZROI2018提高day5t2

    传送门 分析 考场上傻了,写了个树剖还莫名weila...... 实际就是按顺序考虑每个点,然后从他往上找,一边走一边将走过的边染色,如果走到以前染过色的边就停下.对于每一个a[i]的答案就是之前走过 ...

  7. Entity Framework Tutorial Basics(23):Add Single Entity

    Add New Entity using DBContext in Disconnected Scenario: In this chapter you will learn how to add n ...

  8. Entity Framework Code-First(23):Entity Framework Power Tools

    Entity Framework Power Tools: Entity Framework Power Tools (currently in beta 3) has been released. ...

  9. delete请求,删除不成功?

    因为,在数据库底层,其实并没有删除该数据,只是将数据的标识设置为is_deleted.因此,最后即使删除了,查询的时候还是会显示在界面. 故,需要重写get请求.

  10. asp 控件定时器 局部刷新

    <asp:ScriptManager ID="ScriptManager1" runat="server" /> <asp:UpdatePan ...