goredis常见基础命令

基本操作

//删除键
exists,err:= rdb.Exists(ctx,"key").Result()
if err!=nil{panic(err)
}
if exists>0{err = rdb.Del(ctx,"key").Err()if err!=nil{panic(err)}
}

string类型

//设置一个键值对
//0表示没有过期时间
err:=rdb.Set(ctx,"key1","value1",0).Err()//根据key获取value
value,err:=rdb.Get(ctx,"key1").Result()//设置一个key的值,并返回这个key的旧值
oldVal,err:=rdb.GetSet(ctx,"key1","newVal").Result()//如果key不存在,则设置这个key的值
err:=rdb.setNX(ctx,"key2","value2",0).Err()//批量查询key的值
vals,err:=rdb.MGet(ctx,"key1","key2").Result()//批量设置key的值
err := rdb.MSet(ctx,"key1","value1","key2","value2").Err()//针对一个key的数值进行递增操作,每次加1
val,err:=rdb.Incr(ctx,"key").Result()//IncrBy函数,可以指定每次递增多少
valBy,err:=rdb.IncrBy(ctx,"key",2).Result()//IncrByFloat函数,可以指定每次增长多少,加的是浮点数
valFloat,err := rdb.IncrByFloat(ctx,"key1",2.2).Result()//递减1
val,err := rdb.Decr(ctx,"key",2).Result()//递减指定的值
valBy,err:=rdb.DecrBy(ctx,"key",2).Result()//删除key
rdb.Del(ctx,"key")//删除多个key
err:=rdb.Del(ctx,"key1","key2","key3").Err()//设置过期时间
rdb.Expire(ctx,"key",2*time.Second)

Hash类型

//设置字段值
//添加重复的字段不会报错,只会覆盖
err:=rdb.HSet(ctx,"user_1","username","zhang").Err()//查询字段值
username,err:=rdb.HGet(ctx,"user_1","username").Result()//查询全部字段和值
data,err:=rdb.HGetAll(ctx,"user_1").Result()
//data是一个map类型,使用循环迭代输出
for field,val:=range data{fmt.Println(filed,val)
}//根据key和field字段,累加字段的数值
count, err := rdb.HIncrBy(ctx, "user_1", "count", 2).Result()
if err != nil {panic(err)
}
fmt.Println(count)//返回字段所有字段名
//keys是一个string数组
keys, err := rdb.HKeys(ctx, "user_1").Result()
if err != nil {panic(err)
}
fmt.Println(keys)//查询字段数量
size, err := rdb.HLen(ctx, "user_1").Result()
if err != nil {panic(err)
}
fmt.Println(size)//查询多个字段值
//vals是一个数组
vals, err := rdb.HMGet(ctx, "user_1", "username", "count").Result()
if err != nil {panic(err)
}
fmt.Println(vals)//批量设置字段值
data := make(map[string]interface{})
data["id"] = 1
data["username"] = "li"
//一次性保存多个hash字段值
err := rdb.HMSet(ctx, "key", data).Err()
if err != nil {panic(err)
}//如果field字段不存在,则设置hash的值
err := rdb.HSetNX(ctx, "key", "id", 100).Err()
if err != nil {panic(err)
}//删除字段
//删除不存在的字段不会报错
rdb.HDel(ctx, "key", "id")
//删除多个字段
rdb.HDel(ctx, "key", "id", "username")//检测字段名是否存在
f, err := rdb.HExists(ctx, "key", "id").Result()
if err != nil {panic(err)
}
if f {fmt.Println("存在")
} else {fmt.Println("不存在")
}

List

//插入一个数据
rdb.LPush(ctx, "key", "data1")//LPush支持一次插入任意个数据
err := rdb.LPush(ctx, "key", 1, 2, 3, 4, 5).Err()//当列表存在时才从左边插入插入
err := rdb.LPushX(ctx, "key", "sss").Err()//从列表的右边删除第一个数据,并返回删除的数据
val, err := rdb.RPop(ctx, "key").Result()
fmt.Println(val)//从右边插入数据
rdb.RPush(ctx, "key", "data1")//一次插入多个数据
err := rdb.RPush(ctx, "key", 1, 2, 3, 4, 5).Err()//当列表存在时从右边插入数据
err := rdb.RPushX(ctx, "key", "rVal").Err()//从列表的左边删除第一个数据,并返回
val, err := rdb.LPop(ctx, "key").Result()
fmt.Println(val)//返回列表的长度
val, err := rdb.LLen(ctx, "key").Result()
fmt.Println(val)//返回列表一个范围内的数据
//0到-1就是全部
vals, err := rdb.LRange(ctx, "key", 0, -1).Result()
fmt.Println(vals)//从列表的左边开始,删除第一个100
del, err := rdb.LRem(ctx, "key", 1, 100).Result()
fmt.Println(del)//如果有多个100,则从左边开始,删除前两个100
rdb.LRem(ctx, "key", 2, 100)//如果存在多个100,则从右边开始删除2个100
//第二个参数表示从右边开始删除几个等于100得元素
rdb.LRem(ctx, "key", -2, 100)//如果存在多个100,第二个参数为0,表示删除所有元素等于100得数据
rdb.LRem(ctx, "key", 0, 100)//根据索引查找对应元素,索引从0开始
val, err := rdb.LIndex(ctx, "key", 5).Result()//在列表中元素为5的前边加入4
err := rdb.LInsert(ctx, "Key", "before", 5, 4).Err()//只留下索引是0到2的
rdb.LTrim(ctx, "key1", 0, 2)

Set

无序集合元素不能重复

//添加100到集合中
err := rdb.SAdd(ctx, "key", 100).Err()
if err != nil {panic(err)
}//将100,200,300添加到集合中
//向集合中添加已经存在的元素将会报错
rdb.SAdd(ctx, "key", 100, 200, 300)//获取大小
size, err := rdb.SCard(ctx, "key").Result()
if err != nil {panic(err)
}
fmt.Println(size)//判断元素是否存在
ok, _ := rdb.SIsMember(ctx, "key", 100).Result()
if ok {fmt.Println("存在")
}//获取所有元素
es, _ := rdb.SMembers(ctx, "key").Result()
fmt.Println(es)//删除集合元素
//删除不存在的元素不会报错
rdb.SRem(ctx, "key", 100)//删除多个
rdb.SRem(ctx, "key", 200, 300)//随机返回集合中的元素,并删除
//val是随机删除的元素
val, _ := rdb.SPop(ctx, "key").Result()
fmt.Println(val)//随机删除多个
vals, _ := rdb.SPopN(ctx, "key", 3).Result()
fmt.Println(vals)

sorted set/zset

它为每个成员关联了一个分数(score),这个分数被用来对集合中的成员进行排序。虽然成员必须是唯一的,但是分数可以重复

l1 := redis.Z{Score:  1.0,Member: "zhang",
}
//添加元素,如果元素存在,则更新分数
err := rdb.ZAdd(ctx, "key", l1).Err()
if err != nil {panic(err)
}
err = rdb.ZAdd(ctx, "key", redis.Z{3.8, "zhang"}).Err()
if err != nil {panic(err)
}//返回元素个数
size, err := rdb.ZCard(ctx, "key").Result()
if err != nil {panic(err)
}
fmt.Println(size)//统计某个范围的元素个数
//范围[1,5]
size, err = rdb.ZCount(ctx, "key", "1", "5").Result()
if err != nil {panic(err)
}
fmt.Println(size)// 如果加上( 则表示大于或者小于,相当于去掉了等于关系。
size, err = rdb.ZCount(ctx, "key", "(1", "5").Result()
if err != nil {panic(err)
}
fmt.Println(size)//增加元素分数
rdb.ZIncrBy(ctx, "key", 2, "zhang")//返回全部数据
//元素按分数从小到大
vals, err := rdb.ZRange(ctx, "key", 0, -1).Result()
if err != nil {panic(err)
}
for _, val := range vals {fmt.Println(val)
}//ZRevRange的结果是按分数从大到小排序
//根据分数范围返回集合元素,元素根据分数从小到大排序,支持分页
//初始化查询条件
op := redis.ZRangeBy{"1","10",0, // 类似sql的limit, 表示开始偏移量5, // 一次返回多少数据
}
vals, err = rdb.ZRangeByScore(ctx, "key", &op).Result()
if err != nil {panic(err)
}
for _, val := range vals {fmt.Println(val)
}// ZRevRangeByScore用法类似ZRangeByScore,区别是元素根据分数从大到小排序。//返回元素和分数
vals, err = rdb.ZRangeByScoreWithScores(ctx, "key", &op).Result()
if err != nil {panic(err)
}
for _, val := range vals {fmt.Println(val.Member)fmt.Println(val.Score)
}//删除集合元素
rdb.ZRem(ctx, "key", "zhang")//删除多个
rdb.ZRem(ctx, "key", "li", "wang")//根据索引范围删除元素
//删除第零个到第一个
rdb.ZRemRangeByRank(ctx, "key", 0, 1)//根据范围删除元素,"("和")"可以使用
rdb.ZRemRangeByScore(ctx, "key", "2", "5")//查询元素对应的分数
score, _ := rdb.ZScore(ctx, "key", "zhang").Result()
fmt.Println(score)//根据元素名,查询集合元素在集合中的排名,从0开始,从小到大
rk, _ := rdb.ZRank(ctx, "key", "zhang").Result()
fmt.Println(rk)
//ZRevRank是按分数从大到小排序

发布订阅

可用于消息的传输

三个部分:发布者,订阅者,Channel(频道)

在这里插入图片描述

发布者和订阅者是redis客户端,channel是redis服务端,发布者将消息发送到某个频道,订阅这个频道的订阅者就能接收到这条消息

Subscribe

订阅channel

// 订阅channel1这个channel
sub := rdb.Subscribe(ctx, "channel1")
// sub.Channel() 返回go channel,可以循环读取redis服务器发过来的消息
for msg := range sub.Channel() {// 打印收到的消息fmt.Println(msg.Channel)fmt.Println(msg.Payload)
}
//或者
for {msg, err := sub.ReceiveMessage(ctx)if err != nil {panic(err)}fmt.Println(msg.Channel, msg.Payload)
}

publish

将消息发送给指定的channel

rdb.Publish(ctx,"channel1","message")

PSubscribe

用法跟Subscribe一样,区别是PSubscribe订阅通道(channel)支持模式匹配。

// 订阅channel1这个channel
sub := rdb.PSubscribe(ctx,"ch_user_*")
// 可以匹配ch_user_开头的任意channel

Unsubscribe

取消订阅

// 订阅channel1这个channel
sub := rdb.Subscribe(ctx,"channel1")
// 取消订阅
sub.Unsubscribe(ctx,"channel1")

PubSubNumSub

查询指定的channel有多少个订阅者

// 查询channel_1通道的订阅者数量chs, _ := rdb.PubSubNumSub(ctx, "channel_1").Result()for ch, count := range chs {fmt.Println(ch)    // channel名字fmt.Println(count) // channel的订阅者数量}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/22985.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务环境搭建架构介绍(附超清图解源代码)

微服务介绍 系统架构演变 随着互联网的发展,网站应用的规模也在不断的扩大,进而导致系统架构也在不断的进行变化。 从互联网早起到现在,系统架构大体经历了下面几个过程: 单体应用架构--->垂直应用架构--->分布 式架构--->SOA架构…

Java-01-源码篇-04集合-05-ConcurrentHashMap(1)

1.1 加载因子 加载因子(Load Factor)是用来决定什么时候需要扩容的一个参数。具体来说,加载因子 当前元素数量 / 桶的数量,当某个桶的元素个数超过了 桶的数量 加载因子 时,就会触发扩容。 我们都知道 ConcurrentHas…

一文详解U盘启动Legacy/UEFI方式以及GPT/MBR关系

对于装系统的老手而说一直想研究一下装系统的原理,以及面对一些问题时的解决思路,故对以前的方法进行原理上的解释,主要想理解其底层原理。 引导模式 MBR分区可以同时支持UEFI和Legacy引导,我们可以看一下微pe制作的启动盘&#…

【多线程-第三天-NSOperation的练习-tableView异步下载网络图片-下载操作缓存池 Objective-C语言】

一、下载操作缓存池 1.下面我们来看操作缓存池,我们先演示一下问题,看看为什么要加这么一个操作缓存池,什么是操作缓存池,不用管呢,我们先来看啊,首先有什么问题, 看这个问题之前,我这儿写一个touch,点击屏幕的时候调用, 额,不能点击屏幕啊,因为现在屏幕点不着,我…

Windows 中的启动项如何打开?管理电脑启动程序的三种方法

在日常使用电脑时,我们经常会发现一些应用程序在开机时自动启动,这不仅会拖慢系统的启动速度,还可能占用不必要的系统资源。幸运的是,通过几个简单的步骤,你可以轻松管理这些开机自启的应用程序。接下来,我…

具备智能广告拦截、个性化定制的便捷网页浏览器

软件介绍 今天要给大家介绍一款源自俄罗斯的国民级软件,它来自俄罗斯最大互联网公司之一的 Yandex。这家公司不仅有搜索引擎业务,还打造出诸多热门软件,其中就有我们要讲的这款网页浏览器。它由 Yandex 公司依托 Chromium 开源项目开发&…

LangChain-基础(prompts、序列化、流式输出、自定义输出)

LangChain-基础 我们现在使用的大模型训练数据都是基于历史数据训练出来的,它们都无法处理一些实时性的问题或者一些在训练时为训练到的一些问题,解决这个问题有2种解决方案 基于现有的大模型上进行微调,使得它能适应这些问题(本…

119. 杨辉三角 II

给定一个非负索引 rowIndex,返回「杨辉三角」的第 rowIndex 行。 在「杨辉三角」中,每个数是它左上方和右上方的数的和。 示例 1: 输入: rowIndex 3 输出: [1,3,3,1]示例 2: 输入: rowIndex 0 输出: [1]示例 3: 输入: rowIndex 1 输出: [1,1]提示…

Unity Android SDK 升级、安装 build-tools、platform-tools

Unity Android SDK 升级、安装 build-tools、platform-tools 通过 Unity Hub 安装的 Android SDK 需要下载 特定版本的 build-tools、platform-tools 如何操作? 以 Unity 2022.3.26f1 为例,打开安装目录,找到如下目录 2022.3.26f1\Editor\…

网络空间安全(3)web渗透测试学习框架

前言 Web渗透测试是一种安全评估方法,旨在通过模拟黑客攻击来检测Web应用程序中的安全漏洞。 一、学习基础 在学习Web渗透测试之前,需要掌握一些基础知识,包括计算机网络、Web开发技术(如HTML、JavaScript、PHP等)、数…

人工智能之自动驾驶技术体系

自动驾驶技术体系 自动驾驶技术是人工智能在交通领域的重要应用,旨在通过计算机视觉、传感器融合、路径规划等技术实现车辆的自主驾驶。自动驾驶不仅能够提高交通效率,还能减少交通事故和环境污染。本文将深入探讨自动驾驶的技术体系,包括感…

25会计研究生复试面试问题汇总 会计专业知识问题很全! 会计复试全流程攻略 会计考研复试真题汇总

宝子们,会计考研复试快到了,是不是有点慌?别怕!今天学姐给你们支招,手把手教你搞定复试面试,直接冲上岸!快来看看怎么准备吧,时间紧直接背第三部分的面试题! 目录 一、复…

本地化部署 DeepSeek:从零到一的完整指南

本地化部署 DeepSeek:从零到一的完整指南 个人主页:顾漂亮 文章专栏:AI学习 目录 引言什么是 DeepSeek?为什么选择本地化部署?DeepSeek 本地化部署的前期准备 硬件需求软件需求环境配置 DeepSeek 本地化部署步骤 步骤…

【深度学习】Unet的基础介绍

U-Net是一种用于图像分割的深度学习模型,特别适合医学影像和其他需要分割细节的任务。如图: Unet论文原文 为什么叫U-Net? U-Net的结构像字母“U”,所以得名。它的结构由两个主要部分组成: 下采样(编码…

【学习笔记】Cadence电子设计全流程(二)原理图库的创建与设计(8-15)

【学习笔记】Cadence电子设计全流程(二)原理图库的创建与设计(下) 2.8 Cadence 软件自带元件库2.9 原理图元器件关联PCB2.10 原理图元器件库的移植2.11 已有原理图输出元器件库2.12 原理图设计中调用元器件库2.13 原理图元器件库关…

DeepSeek从入门到精通

1_DeepSeek从入门到精通 (1).pdf官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘123云盘为您提供1_DeepSeek从入门到精通 (1).pdf最新版正式版官方版绿色版下载,1_DeepSeek从入门到精通 (1).pdf安卓版手机版apk免费下载安装到手机,支持电脑端一键快捷安装https://www.123…

Comfyui Windows Desktop桌面版便携版安装教程

前段时间Comfyui 的便携包安装写了一篇,最近comfyui发布了新的桌面版本0.4.5,我也试着安装了一下,感觉使用体验比便携包要舒适一点点。 下面是安装指南。 安装地址 官方给了下载包,分为N卡和Mac。地址:Notion – Th…

DeepSeek 提示词:定义、作用、分类与设计原则

🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编…

【Linux网络编程】数据链路层和网络层的几个问题:MTU,校验和,全球网段,路由表

目录 1.MTU 2.CRC校验和 3.全球网段 4.子网掩码 5.路由 1.MTU MTU是以太网的最大传输单位,大小是1500字节,表示IP(网络层传下来的最多只能1500字节)。 如果超过了这个数,就要网络层自己做分包。数据链路层是不帮…

浅谈死锁的原因以及解决方案

目录 1 死锁是什么? 2 死锁的三种典型情况 3 死锁产生的必要条件​编辑 4 如何解决死锁问题 1 死锁是什么? 它是指两个或多个线程因为互相等待对方持有的资源而无法继续执行的情况。换句话说,每个线程都在等待另一个线程释放资源,但没有任何一个…