学习redis的笔记,本文旨在基础概念的梳理、命令熟悉和使用


SQL和NoSQL

redis是典型的非关系型数据库(NoSQL)

非关系型数据库特征:

  • 无需提前定义表结构
  • 根据场景设计合适的数据结构
  • 弱化事务一致性,如不支持复杂的join

命令

通用命令

  • KEYS:查看符合模板的所有key,不建议在生产环境设备上使用
  • DEL:删除一个指定的key
  • EXISTS:判断key是否存在
  • EXPIRE:给一个key设置有效期,有效期到期时该key会被自动删除
  • TTL:查看一个KEY的剩余有效期

string命令

  • SET:添加或者修改已经存在的一个String类型的键值对
  • GET:根据key获取String类型的value
  • MSET:批量添加多个String类型的键值对
  • MGET:根据多个key获取多个String类型的value
  • INCR:让一个整型的key自增1
  • INCRBY:让一个整型的key自增并指定步长,例如:incrby num 2 让key为num的值自增2
  • INCRBYFLOAT:让一个浮点类型的数字自增并指定步长
  • SETNX:添加一个String类型的键值对,前提是这个key不存在,否则不执行
  • SETEX:添加一个String类型的键值对,并且指定有效期

hash命令

  • HSET key field value:添加或者修改hash类型key的field的值
  • HGET key field:获取一个hash类型key的field的值
  • HMSET:批量添加多个hash类型key的field的值
  • HMGET:批量获取多个hash类型key的field的值
  • HGETALL:获取一个hash类型的key中的所有的field和value
  • HKEYS:获取一个hash类型的key中的所有的field
  • HVALS:获取一个hash类型的key中的所有的value
  • HINCRBY:让一个hash类型key的字段值自增并指定步长
  • HSETNX:添加一个hash类型的key的field值,前提是这个field不存在,否则不执行

list命令

  • LPUSH key element…:向列表左侧插入一个或多个元素
  • LPOP key:移除并返回列表左侧的第一个元素,没有则返回nil
  • RPUSH key element…:向列表右侧插入一个或多个元素
  • RPOP key:移除并返回列表右侧的第一个元素
  • LRANGE key starend:返回一段角标范围内的所有元素
  • BLPOP和BRPOP:与LPOP和RPOP类似,只不过在没有元素时等待指定时间,而不是直接返回nil

set命令

  • SADD key member…:向set中添加一个或多个元素
  • SREM key member…:移除set中的指定元素
  • SCARD key:返回set中元素的个数
  • SISMEMBER key member:判断一个元素是否存在于set中
  • SMEMBERS:获取set中的所有元素
  • SINTER key1 key2…:求key1与key2的交集
  • SDIFF key1key2…:求key1与key2的差集
  • SUNION key1 key2..:求key1和key2的并集

sorted set

  • ZADD key score member:添加一个或多个元素到sortedset,如果已经存在则更新其score值
  • ZREMkey member:删除sortedset中的一个指定元素
  • ZSCORE key member:获取sorted set中的指定元素的score值
  • ZRANK key member:获取sorted set 中的指定元素的排名
  • ZCARD key:获取sorted set中的元素个数
  • ZCOUNT key min max:统计score值在给定范围内的所有元素的个数
  • ZINCRBY key increment member:让sorted set中的指定元素自增,步长为指定的increment值
  • ZRANGE key min max:按照score排序后,获取指定排名范围内的元素
  • ZRANGEBYSCORE key min max:按照score排序后,获取指定score范围内的元素
  • ZDIFF、ZINTER、ZUNION:求差集、交集、并集

练手demo

demo在GitHub仓库

自定义序列化

redis默认的序列化器是JDK自带的,把数据转换成二进制存储,不方便,难读且占空间大,所以需要自定义序列化器

JSON序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Configuration
public class RedisConfig {

@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();

// 设置连接工厂
template.setConnectionFactory(factory);

// 创建通用的 Jackson JSON 序列化器,用于将对象转为 JSON 存储
GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer();

// 设置key为字符串序列化
template.setKeySerializer(RedisSerializer.string());
template.setHashKeySerializer(RedisSerializer.string());

// 设置value为json序列化
template.setValueSerializer(serializer);
template.setHashValueSerializer(serializer);

return template;
}
}

读、写均可实现自动序列化

为了实现反序列化,JSON序列化器会将类的class类型也一起写入JSON结果中,存入redis,会带来额外的内存开销

所以为了节省内存空间,统一使用String序列化器,要求只存储String类型的key和value,当要存储Java对象的时候,手动完成序列化和反序列化

StringRedisTemplate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.flypiggyyoyoyo.redispracdemo;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.flypiggyyoyoyo.redispracdemo.data.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.StringRedisTemplate;

@SpringBootTest
public class RedisStringTests {
@Autowired
private StringRedisTemplate stringRedisTemplate;

private static final ObjectMapper mapper = new ObjectMapper();

@Test
public void testStoreUser() throws JsonProcessingException {
User user = new User("团长", 27);
String json = mapper.writeValueAsString(user);
stringRedisTemplate.opsForValue().set("user:300", json);
String json2 = stringRedisTemplate.opsForValue().get("user:300");
User user2 = mapper.readValue(json2, User.class);
System.out.println(user2);
}
}