Redis 入门篇

文章目录

  • Redis简介
    • 关系型数据库:
    • 非关系型数据库
  • Redis应用场景
  • Redis下载和安装
  • Redis 数据类型
  • Redis 常用命令
    • 字符串 string 操作命令
    • 哈希 hash 操作命令
    • 列表 list 操作命令
    • 集合 set 操作命令
    • 有序集合 sorted set 操作命令
    • 通用命令
  • Jedis 快速入门
    • 配置依赖
    • 建立连接 / 操作
  • Jedis 连接池
    • 配置 jedis 连接池
    • 调用 jedis 连接池
  • SpringDataRedis 快速入门
    • 基本操作
    • 引入依赖
    • 配置信息
    • 测试操作 String
    • 自定义序列化器
    • 测试操作 User对象
    • 优化
    • 小结
    • 相关文章

Redis简介


关系型数据库:

  1. Mysql
  2. Oracle
  3. DB2
  4. SQLServer

非关系型数据库

  1. Redis
  2. Mongo db
  3. MemCached

Redis应用场景


  1. 缓存
  2. 任务队列
  3. 消息队列
  4. 分布式锁

Redis下载和安装


相关文章
windows下安装和配置Redis
Linux下安装Redis(超详细教程)_linux安装redis-CSDN博客

Redis 数据类型


Redis存储的是key-value结构的数据
key是字符串类型, value有五种常用数据类型

  1. 字符串 String
  2. 哈希 hash 适合存储对象
  3. 列表 list 按照插入顺序排序 可以有重复元素
  4. 集合 set 无序集合 没有重复元素
  5. 有序集合 sorted set 没有重复元素

Redis 常用命令


字符串 string 操作命令

  • SET key value 设置指定key的值
  • image.png
  • GET key 获取指定key的值
  • image.png
  • SETEX key seconds value 设置指定key的值, 并将key过期时间设置为seconds秒
  • image.png
  • SETNX key value 只有在key不存在时设置key
  • image.png

哈希 hash 操作命令

hash 是一个 string 类型的 field 和 value 的映射表
hash 特别适合用于存储对象
image.png

  • HSET key field value 将哈希表key中字段field的值设为value
  • image.png
  • HGET key field 获取存储在哈希表中指定字段的值
  • image.png
  • HDEL key field 删除存储在哈希表中的指定字段
  • image.png
  • HKEYS key 获取哈希表中所有字段
  • image.png
  • HVALS key 获取哈希表中所有值
  • image.png
  • HGETALL key 获取在哈希表中指定key所有字段和值
  • image.png

列表 list 操作命令

Redis 列表是简单的字符串列表 按照插入顺序排序
image.png

  • LPUSH key value1 [value2] 将一个或多个值插入到列表头部

  • image.png

  • LRANGE key start stop 获取列表指定范围内的元素

  • image.png

  • RPOP key 移除并获取列表最后一个元素

  • image.png

  • LLEN key 获取列表长度

  • image.png

  • BRPOP key1 [key2] timeout 移除并获取列表最后一个元素, 如果列表没有

    元素会阻塞列表知道等待超时或者发现可弹出元素为止

image.png

集合 set 操作命令

Redis set 是 string 类型的无序集合 集合成员是唯一的
image.png

  • SADD key member1 [member2] 向集合中添加一个或多个成员
  • image.png
  • SMEMBERS key 返回集合中的所有成员
  • image.png
  • SCARD key 获取集合的成员数
  • image.png
  • SINTER key1 [key2] 返回给定所有集合的交集
  • image.png
  • SUNION key1 [key2] 返回给定所有集合的并集
  • image.png
  • SDIFF key1 [key2] 返回给定所有集合的差集
  • image.png
  • SREM key member1 [member2] 移除集合中一个或多个成员
  • image.png

有序集合 sorted set 操作命令

Redis sorted set 有序集合是string类型元素的集合
且不允许重复的成员 每个元素都会关联一个double类型的分数.
redis 正是通过分数来为集合中的成员进行从小到大的排序,
有序集合的成员是唯一的, 但分数却可以重复

image.png

  • ZADD key score1 member1 [score2 member2] 添加一个或多个 或更新已存在成员的分数
  • image.png
  • ZRANGE key start stop [WITHSCORES] 通过索引区间返回成员 withscores 分数也返回
  • image.png
  • ZINCRBY key incrrement member 对指定成员的分数上加上增量 increment
  • image.png
  • ZREM key member [member…] 移除一个或多个成员
  • image.png

通用命令

  • KEYS pattern 查找所有符合给定模式(pattern)的key
  • image.png
  • EXISTS key 检查给定 key 是否存在
  • image.png
  • image.png
  • TYPE key 返回 key 所存储的值的类型
  • image.png
  • TTL key 返回给定 key 的剩余生存时间, 以秒为单位
  • image.png
  • DEL key 该命令用于在 key 存在时删除key
  • image.png

Jedis 快速入门


配置依赖

	<!-- jedis -->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>5.0.0</version>
    </dependency>

    <!-- junit单元测试 -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>5.7.0</version>
        <scope>test</scope>
    </dependency>

建立连接 / 操作

private Jedis jedis;

	@BeforeEach
	void setUp(){
		// 1. 建立连接
		jedis = new Jedis("192.168.1.123", 6379);
		// 2. 设置密码
//		jedis.auth("123456");
		// 3. 选择数据库
		jedis.select(4);
	}
	
	@Test
	void testString(){
		// 存入数据
		String result = jedis.set("name", "zhangsan");
		System.out.println(result);
		// 获取数据
		String name = jedis.get("name");
		System.out.println(name);
	}

	@AfterEach
	void testDown(){
		// 关闭连接
		if(jedis != null){
			jedis.close();
		}
	}

image.png

@Test
	void testHash(){
		jedis.hset("user:1", "name", "zhangsan");
		jedis.hset("user:1", "age", "18");
		
		Map<String, String> map = jedis.hgetAll("user:1");
		System.out.println(map);
	}

image.png

Jedis 连接池


配置 jedis 连接池

private static final JedisPool jedisPool;

	static {
		// 配置连接池
		JedisPoolConfig poolConfig = new JedisPoolConfig();
		poolConfig.setMaxTotal(8);
		poolConfig.setMaxIdle(8);
		poolConfig.setMinIdle(0);
		poolConfig.setMaxWaitMillis(1000);
		// 创建连接池对象
		jedisPool = new JedisPool(poolConfig, "192.168.1.123", 6379, 1000);
	}

	public static Jedis getJedis(){
		return jedisPool.getResource();
	}

调用 jedis 连接池

@BeforeEach
	void setUp(){
		// 1. 建立连接
//		jedis = new Jedis("192.168.1.123", 6379);
		jedis = JedisConnectionFactory.getJedis(); // 改成调用~
		// 2. 设置密码
//		jedis.auth("123456");
		// 3. 选择数据库
		jedis.select(4);
	}

SpringDataRedis 快速入门


基本操作

image.png

引入依赖

    	<!--redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--common pool-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

配置信息

spring:
  redis:
    host: 192.168.1.123
    port: 6379
#    password: 123456
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0
        max-wait: 100ms

测试操作 String

	@Autowired
	private RedisTemplate redisTemplate;

	@Test
	void testString() {
		// 写入
		redisTemplate.opsForValue().set("name", "莜莜");
		// 读取
		Object name = redisTemplate.opsForValue().get("name");
		System.out.println(name);
	}

image.png

自定义序列化器

如果不自己定义序列化器 写入redis里的就是下面这种看不懂的玩意

image.png

引入 json 依赖

<!--json依赖-->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>

自定义序列化器

@Configuration
public class RedisConfig {

	/** 自定义序列化器 **/
	@Bean
	public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory){
		// 创建 RedisTemplate 对象
		RedisTemplate<String, Object> template = new RedisTemplate<>();
		// 设置连接工厂
		template.setConnectionFactory(connectionFactory);
		// 创建 JSON 序列化工具
		GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
		// 设置 key 的序列化
		template.setKeySerializer(RedisSerializer.string());
		template.setHashKeySerializer(RedisSerializer.string());
		// 设置 value 的序列化
		template.setValueSerializer(jsonRedisSerializer);
		template.setHashValueSerializer(jsonRedisSerializer);
		// 返回
		return template;
	}
}

再次测试结果如下
image.png

测试操作 User对象

@Test
void testSaveUser(){
	redisTemplate.opsForValue().set("user1", new User("莜莜", 18));
	User user = (User) redisTemplate.opsForValue().get("user1");
	System.out.println(user);
}

image.png

image.png

我们会发现, 写入对象进redis时它会"夹带私货",

存了个对象的类型, 这不是我们需要的, 同时还会加大宝贵的内存开销

优化

直接使用stringRedisTemplate, 省去自定义redisTemplate
增加 手动序列化和反序列化

image.png

使用 stringRedisTemplate String操作

	@Autowired
	private StringRedisTemplate stringRedisTemplate;

	@Test
	void testString() {
		// 写入
		stringRedisTemplate.opsForValue().set("name", "Youovo");
		// 读取
		Object name = stringRedisTemplate.opsForValue().get("name");
		System.out.println(name);
	}

使用 stringRedisTemplate saveUser对象操作

private static final ObjectMapper mapper = new ObjectMapper();
@Test
void testSaveUser() throws JsonProcessingException {
	// 创建对象
	User user = new User("派大星", 18);
	// 手动序列化
	String json = mapper.writeValueAsString(user);
	// 写入redis
	stringRedisTemplate.opsForValue().set("user:100", json);
	// 获取数据
	String jsonUser = stringRedisTemplate.opsForValue().get("user:100");
	// 手动反序列化
	User value = mapper.readValue(jsonUser, User.class);
	System.out.println(value);
}

image.png

image.png

序列化和反序列化的结果均达到~

补充 Hash 操作~

@Test
void testHash(){
	stringRedisTemplate.opsForHash().put("user:20", "name", "海绵宝宝");
	stringRedisTemplate.opsForHash().put("user:20", "age", "18");
	stringRedisTemplate.opsForHash().entries("user:20").forEach((k, v) -> {
		System.out.println(k + " = " + v);
	});
}

image.png

小结

image.png

相关文章

Spring Data Redis操作Redis-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ShareX,屏幕截图、屏幕录制和文件共享,还提供了丰富的高级功能和自定义选项

ShareX是一个免费开源的Windows应用程序&#xff0c;用于屏幕截图、屏幕录制和文件共享。它不仅支持基本的屏幕截图功能&#xff0c;还提供了丰富的高级功能和自定义选项&#xff0c;使其成为提高工作效率和截图体验的利器。以下是ShareX v16.1.0便携版的主要功能和特色&#x…

NeRF从入门到放弃4: NeuRAD-针对自动驾驶场景的优化

NeuRAD: Neural Rendering for Autonomous Driving 非常值得学习的一篇文章&#xff0c;几乎把自动驾驶场景下所有的优化都加上了&#xff0c;并且也开源了。 和Unisim做了对比&#xff0c;指出Unisim使用lidar指导采样的问题是lidar的垂直FOV有限&#xff0c;高处的东西打不…

Vue: Module “vue“ has no exported member xxx

这个问题让我困扰了好一会儿&#xff0c;我询问了 chatgpt 和各种网站社区&#xff0c;尝试了切换依赖的版本&#xff0c;清除缓存等等&#xff0c;依然没有解决 不过算是有心栽花花不开&#xff0c;无心插柳柳成荫&#xff0c;碰巧解决了&#xff0c;也不知道是不是这个原因&a…

java收徒 java辅导 java试用期辅导 java零基础学习

&#x1f497;博主介绍&#xff1a;✌全网粉丝1W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末报名辅导&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;还有大家…

WinMerge v2 (开源的文件比较/合并工具)

前言 WinMerge 是一款运行于Windows系统下的免费开源的文件比较/合并工具&#xff0c;使用它可以非常方便地比较多个文档内容甚至是文件夹与文件夹之间的文件差异。适合程序员或者经常需要撰写文稿的朋友使用。 一、下载地址 下载链接&#xff1a;http://dygod/source 点击搜…

微信小程序-伪类选择器

一.伪类选择器 结构伪类常见书写方式&#xff1a; 第一类&#xff1a;找第几个孩子 1. :first-child 找第一个孩子2. :last-child 找最后一个孩子3. :nth-child()&#xff0c;正着找数字&#xff1a;写数字几就是找第几个孩子&#xff0c;2n或者even:找偶数2n1或者o…

python数据分析案例-信用卡违约预测分析

一、研究背景和意义 信用卡已经成为现代社会中人们日常生活中不可或缺的支付工具&#xff0c;它不仅为消费者提供了便利&#xff0c;还为商家提供了更广泛的销售渠道。然而&#xff0c;随着信用卡的普及和使用量的增加&#xff0c;信用卡违约问题逐渐成为金融机构面临的重要挑…

Java基础的重点知识-03-方法与数组

文章目录 方法数组 方法 定义方法的格式详解 修饰符 返回值类型 方法名(参数列表){//代码省略...return 结果; }修饰符&#xff1a; public static 固定写法返回值类型&#xff1a; 表示方法运行的结果的数据类型&#xff0c;方法执行后将结果返回到调用者参数列表&#xff1…

Pytho字符串的定义与操作

一、字符串的定义 Python 字符串是字符的序列&#xff0c;用于存储文本数据。字符串可以包括字母、数字、符号和空格。在 Python 中&#xff0c;字符串是不可变的&#xff0c;这意味着一旦创建了一个字符串&#xff0c;就不能更改其中的字符。但是&#xff0c;你可以创建新的字…

一文读懂LLM API应用开发基础(万字长文)

前言 Hello&#xff0c;大家好&#xff0c;我是GISer Liu&#x1f601;&#xff0c;一名热爱AI技术的GIS开发者&#xff0c;上一篇文章中我们详细介绍了LLM开发的基本概念&#xff0c;包括LLM的模型、特点能力以及应用&#xff1b;&#x1f632; 在本文中作者将通过&#xff1a…

Flutter ListView详解

文章示例代码 ListView常用构造 ListView 我们可以直接使用ListView 它的实现也是直接返回最简单的列表结构&#xff0c;粗糙没有修饰。 ListView 默认构建 效果 ///默认构建 Widget listViewDefault(List list) { List _list new List(); for (int i 0; i < list.le…

Java学习 - 网络IP协议簇 讲解

IP协议 IP协议全称 Internet Protocol互联网互连协议 IP协议作用 实现数据在网络节点上互相传输 IP协议特点 不面向连接不保证可靠 IP协议数据报结构 组成说明版本目前有IPv4和IPv6两种版本首部长度单位4字节&#xff0c;所以首部长度最大为 15 * 4 60字节区分服务不同…

视觉新纪元:解码LED显示屏的视角、可视角、最佳视角的最终奥秘

在璀璨夺目的LED显示屏世界里&#xff0c;每一个绚烂画面的背后&#xff0c;都离不开三个关键概念&#xff1a;视角、可视角与最佳视角。这些术语不仅是衡量显示效果的重要标尺&#xff0c;也是连接观众与精彩内容的桥梁。让我们一起走进这场视觉盛宴&#xff0c;探索那些让LED…

做Android开发怎么才能不被淘汰?

多学一项技能&#xff0c;可能就会成为你升职加薪的利器。经常混迹于各复杂业务线的人&#xff0c;才能跳出重复工作、不断踩坑的怪圈。而一个成熟的码农在于技术过关后&#xff0c;更突出其他技能对专业技术的附加值。 毋须讳言的是&#xff0c;35岁以后你的一线coding能力一…

使用SPI驱动数码管

代码&#xff1a; 7-seg.c /*《AVR专题精选》随书例程3.通信接口使用技巧项目&#xff1a;改进的延时法实现半双工软件串口文件&#xff1a;7seg.c说明&#xff1a;SPI控制数码管驱动文件作者&#xff1a;邵子扬时间&#xff1a;2012年12月15日*/#include <avr/io.h>ex…

【嵌入式】嵌入式Linux开发实战指南:从交叉编译到触摸屏交互

文章目录 前言&#xff1a;1.简介1.1. 交叉编译工具1.2. 项目开发流程&#xff1a;1.3. ARM开发板的连接方法 2. 开发板连接3. 系统文件 IO4. 设置共享文件夹3.1. 读文件3.2. 写文件3.2. 设置文件偏移量 4. LCD显示屏显示4.1. LCD 显示颜色4.2. 将文件下载到开发板4.2.1. 在CRT…

JDK动态代理

JDK动态代理源码分析 4.1 JDK动态代理的实现 需要动态代理的接口 /**需要动态代理的接口 */ public interface Movie {void player();void speak();需要动态代理的接口的真实实现 /**需要动态代理接口的真实实现 */ public class RealMovie implements Movie {Override publi…

win10 安装openssl并使用openssl创建自签名证书

win10创建自签名证书 下载安装配置openssl 下载地址&#xff1a; https://slproweb.com/download/Win64OpenSSL-3_3_1.exe https://slproweb.com/products/Win32OpenSSL.html 完成后安装&#xff0c;一路next&#xff0c;到达选位置的之后选择安装的位置&#xff0c;我这里选…

一文详解分布式 ID

分布式系统中&#xff0c;我们经常需要对数据、消息等进行唯一标识&#xff0c;这个唯一标识就是分布式 ID&#xff0c;那么我们如何设计它呢&#xff1f;本文将详细讲述分布式 ID 及其生成方案。 一、为什么需要分布式 ID 目前大部分的系统都已是分布式系统&#xff0c;所以在…

如何打造稳定、好用的 Android LayoutInspector?

速度极慢&#xff0c;遇到复杂的布局经常超时 某些情况无法选中指定的 View 本文将围绕 LayoutInspector 的痛点&#xff0c;分析问题并修复&#xff0c;最终将 LayoutInspector 变成一个稳定、好用的插件。 二、加速 Dump View Hierarchy 2.1 问题描述 开发复杂业务的同学…