Redis基础
Redis数据结构
redis通用命令
string类型
字符串、整形、浮点型
key的分级存储
示例:
set heima:user:1 '{"name":"komorebi","age":23}'
Hash类型
hash操作命令
hset heimaHash:1 name mfx
hset heimaHash:1 age 18
上面代码可以转化为一行
hset heimaHash:1 name mfx age 18
List(链表)类型
常见命令
lpush heimaList v1 v2 v3
,左侧插入等于链表的头插。
Set类型
常见命令
示例:
sadd heimaSet 1 2 3
smembers heimaSet
练习
1、张三朋友集合(创建set)
sadd sanFriends lisi wangwu zaoliu
2、李四朋友集合(创建set)
sadd siFriends wangwu mazi ergou
3、张三好友个数(统计set元素个数)
scard sanFriends
4、张三和里斯的共同好友(统计两个set并集)
sinter sanFriends siFriends
5、那些是张三的朋友而不是李四的朋友(统计两个set差集)
sdiff sanFriends siFriends
6、张三和李四的好友共有那些人(统计set并集)
sunion sanFriends siFriends
7、判断李四是否是张三的朋友(判断某元素是否存在于set)
sismember sanFriends lisi
8、判断张三是否是李四的朋友
sismember siFriends zhangsan
9、从张三好友列表中移除李四(删除set某个元素)
srem sanFriends lisi
SortedSet类型
常见命令
练习
1、添加学生数据
zadd student 85 jack 89 luck 82 rose 95 tom 78 jerry 92 amy 76 miles
2、删除tom同学
zrem student tom
3、获取amy同学的分数
zscore student amy
4、获取rose同学的排名(降序排列然后查询)
zrevrank student rose
5、查询80分一下有几个学生
zcount student 0 80
6、给amy同学加两分
zincrby student 2 amy
7、查出成绩前三名的同学
zrevrange student 0 2
8、查出成绩80分一下的所有同学
zrangebyscore student 0 80
Redis JAVA客户端
SpringDataRedis
SpringData 是 Spring 中数据操作的模块,包含对各种数据库的集成,其中对 Redis 的集成模块就叫做 SpringDataRedis,官网地址:
- 提供了对不同 Redis 客户端的整合(Lettuce 和 Jedis)
- 提供了 RedisTemplate 统一 API 来操作 Redis
- 支持 Redis 的发布订阅模型
- 支持 Redis 哨兵和 Redis 集群
- 支持基于 Lettuce 的响应式编程
- 支持基于 JDK、JSON、字符串、Spring 对象的数据序列化及反序列化
- 支持基于 Redis 的 JDKCollection 实现
- SpringDataRedis 中提供了 RedisTemplate 工具类,其中封装了各种对 Redis 的操作。并且将不同数据类型的操作 API 封装到了不同的类型中:
快速入门
(1)引入依赖
<dependencies>
<!--redis依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--common-pool-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--Jackson依赖 ,springmvc中自带依赖,这里由于没有,故引用-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
(2)配置redis
spring:
redis:
host: 127.0.0.1
port: 6379
password: 747699
lettuce:
pool:
max-active: 8
max-idle: 8
min-idle: 0
max-wait: 100ms
(3)注入redisTemplate
private RedisTemplate redisTemplate;
(4)测试
@Test
void test(){
redisTemplate.opsForValue().set("name","redisTemplate测试111");
Object name = redisTemplate.opsForValue().get("name");
System.out.println(name);
}
查看 redisGUI, 发现 redis 中存的数据并不像我们预期的那样 name:阿陈,为什么呢?
原因:序列化
自定义序列化
redis 序列化器 有以下几种:常用的是 StringRedisSerializer 和 Jackson2JsonRedisSerializer 。
RedisTemplate 可以接收任意 Object 作为值写入 Redis:
只不过写入前会把 Object 序列化为字节形式,默认是采用 JDK 序列化,得到的结果是这样的:
缺点:
可读性差
内存占用较大
我们可以自定义 RedisTemplate 的序列化方式,代码如下:
@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和hashKey的序列化
template.setKeySerializer(RedisSerializer.string());
template.setHashKeySerializer(RedisSerializer.string());
// 设置Value和hashValue的序列化
template.setValueSerializer(jsonRedisSerializer);
template.setHashValueSerializer(jsonRedisSerializer);
// 返回
return template;
}
}
这里采用了 JSON 序列化来代替默认的 JDK 序列化方式,一般我们使用 redis 的时候,redis 的 key 都是 String 类型的,故在对 key 使用序列化器时,都采用 RedisSerializer.string() 的方式。再次测试 ,结果如图:
如果我们 是存 java 对象,那 redis 会怎样显示?
@Test
void test(){
User user = new User("komorebi",23);
redisTemplate.opsForValue().set("redisTest:user",user);
Object name = redisTemplate.opsForValue().get("redisTest:user");
System.out.println(name);
}
整体可读性有了很大提升,并且能将 Java 对象自动的序列化为 JSON 字符串,并且查询时能自动把 JSON 反序列化为 Java 对象。不过,其中记录了序列化时对应的 class 名称,目的是为了查询时实现自动反序列化。这会带来额外的内存开销。
StringRedisTemplate***
为了节省内存空间,我们可以不使用 JSON 序列化器来处理 value,而是统一使用 String 序列化器,要求只能存储 String 类型的 key 和 value。当需要存储 Java 对象时,手动完成对象的序列化和反序列化。
因为存入和读取时的序列化及反序列化都是我们自己实现的,SpringDataRedis 就不会将 class 信息写入 Redis 了。
objectMapper
实现手动序列化和反序列化
序列化:object转为字符串 ;objectMapper.writeValueAsString
反序列化:字符串转为object;objectMapper.readValue
这种用法比较普遍,因此 SpringDataRedis 就提供了 RedisTemplate 的子类:StringRedisTemplate ,它的 key 和 value 的序列化方式默认就是 String 方式。
省去了我们自定义 RedisTemplate 的序列化方式的步骤,而是直接使用:
@Resource
private StringRedisTemplate stringRedisTemplate;
private static final ObjectMapper objectMapper = new ObjectMapper();
@Test
void test() throws JsonProcessingException {
User user = new User("komorebi",23);
String userJson = objectMapper.writeValueAsString(user);
stringRedisTemplate.opsForValue().set("redisTest:user",userJson);
String s = stringRedisTemplate.opsForValue().get("redisTest:user");
User user1 = objectMapper.readValue(s, User.class);
System.out.println(user1);
}