Redis简介

Redis 是完全开源免费的,遵守BSD协议,是性能极高的nosql数据库,并提供多种语言的 API的非关系型数据库

Redis优点

  • Redis本质上是一个基于内存的高性能key-value数据库,定期通过异步操作把数据库数据保存到硬盘中 。
  • 性能极高,速度快,因为数据存在内存中,读的速度能达到110000次/s,写的速度能达到81000次/s 。
  • 支持rdb,aof两种方式数据持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。

数据类型

  • string 字符串
  • list 列表
  • set 集合
  • hash 哈希
  • zset 有序集合

Spring Data Redis

在spring boot中,默认集成的redis是Spring Data Redis,Spring Data Redis针对redis提供了非常方便的操作模版RedisTemplate

Spring Boot配置

1.引入pom.xml

1
2
3
4
5
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2.application.yml配置

1
2
3
4
5
6
# redis配置
redis:
host: 你的ip
port: 6379
password: 密码 #没有设置不填

3.配置类

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
@Configuration
public class RedisConfig {

@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate();
redisTemplate.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(mapper);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
redisTemplate.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
redisTemplate.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}

}

向Redis存值

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@SpringBootTest
public class TestRedis {

@Autowired
private RedisTemplate redisTemplate;

/**
* 向redis设置一个哈希结构数据
*/
@Test
void setHash(){

HashMap<String, Object> map = new HashMap<>();
map.put("name","刻晴");
map.put("jod","璃月七星");
map.put("clothes","黑丝");
map.put("hair","双马尾");
ArrayList<String> list = new ArrayList<>();
list.add("单手剑");
list.add("元素伤害");
list.add("雷元素");
list.add("下水道");
map.put("attributes",list);

redisTemplate.opsForHash().putAll("123",map);

}


/**
* 获取hash
*/
@Test
void getHash(){
Map<String,Object> map = redisTemplate.opsForHash().entries("123");
map.forEach((k, v) -> System.out.println(k+"="+v));
}


}

先后两次执行结果(Redis可视化工具:redis desktop manager)

封装工具类

用的时候在类里面把他@进去

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
@Component
public class RedisUitl {

@Resource
private RedisTemplate<String, Object> redisTemplate;

/**
* 保存属性
*
* @param key key值
* @param value value值
* @param time 时间戳
*/
public void set(String key, Object value, long time) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
}

/**
* 保存属性
*
* @param key key值
* @param value value值
*/
public void set(String key, Object value) {
redisTemplate.opsForValue().set(key, value);
}

/**
* 获取属性
*
* @param key key值
* @return 返回对象
*/
public Object get(String key) {
return redisTemplate.opsForValue().get(key);
}

/**
* 删除属性
*
* @param key key值
* @return 返回成功
*/
public Boolean del(String key) {
return redisTemplate.delete(key);
}

/**
* 批量删除属性
*
* @param keys key值集合
* @return 返回删除数量
*/
public Long del(List<String> keys) {
return redisTemplate.delete(keys);
}

/**
* 设置过期时间
*
* @param key key值
* @param time 时间戳
* @return 返回成功
*/
public Boolean expire(String key, long time) {
return redisTemplate.expire(key, time, TimeUnit.SECONDS);
}

/**
* 获取过期时间
*
* @param key key值
* @return 返回时间戳
*/
public Long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}

/**
* 判断key是否存在
*
* @param key key值
* @return 返回
*/
public Boolean hasKey(String key) {
return redisTemplate.hasKey(key);
}

/**
* 按delta递增
*
* @param key key值
* @param delta delta值
* @return 返回递增后结果
*/
public Long incr(String key, long delta) {
return redisTemplate.opsForValue().increment(key, delta);
}

/**
* 按delta递减
*
* @param key key值
* @param delta delta值
* @return 返回递减后结果
*/
public Long decr(String key, long delta) {
return redisTemplate.opsForValue().increment(key, -delta);
}

/**
* 获取Hash结构中的属性
*
* @param key 外部key值
* @param hashKey 内部key值
* @return 返回内部key的value
*/
public Object hGet(String key, String hashKey) {
return redisTemplate.opsForHash().get(key, hashKey);
}

/**
* 获取Hash结构中的属性
*
* @param key 外部key值
* @param hashKey 内部key值
* @return 返回内部key的value
*/
public Boolean hSet(String key, String hashKey, Object value, long time) {
redisTemplate.opsForHash().put(key, hashKey, value);
return expire(key, time);
}

/**
* 获取Hash结构中的属性
*
* @param key 外部key值
* @param hashKey 内部key值
* @return 返回内部key的value
*/
public void hSet(String key, String hashKey, Object value) {
redisTemplate.opsForHash().put(key, hashKey, value);
}

/**
* 直接获取整个Hash结构
*
* @param key 外部key值
* @return 返回hashMap
*/
public Map hGetAll(String key) {
return redisTemplate.opsForHash().entries(key);
}

/**
* 直接设置整个Hash结构
*
* @param key 外部key
* @param map hashMap值
* @param time 过期时间
* @return 返回是否成功
*/
public Boolean hSetAll(String key, Map<String, Object> map, long time) {
redisTemplate.opsForHash().putAll(key, map);
return expire(key, time);
}

/**
* 直接设置整个Hash结构
*
* @param key 外部key
* @param map hashMap值
*/
public void hSetAll(String key, Map<String, ?> map) {
redisTemplate.opsForHash().putAll(key, map);
}

/**
* 删除Hash结构中的属性
*
* @param key 外部key值
* @param hashKey 内部key值
*/
public void hDel(String key, Object... hashKey) {
redisTemplate.opsForHash().delete(key, hashKey);
}

/**
* 删除Hash结构中的属性
*
* @param key 外部key值
* @param hashKey 内部key值
*/
public Boolean hHasKey(String key, String hashKey) {
return redisTemplate.opsForHash().hasKey(key, hashKey);
}

/**
* Hash结构中属性递增
*
* @param key 外部key
* @param hashKey 内部key
* @param delta 递增条件
* @return 返回递增后的数据
*/
public Long hIncr(String key, String hashKey, Long delta) {
return redisTemplate.opsForHash().increment(key, hashKey, delta);
}

/**
* Hash结构中属性递减
*
* @param key 外部key
* @param hashKey 内部key
* @param delta 递增条件
* @return 返回递减后的数据
*/
public Long hDecr(String key, String hashKey, Long delta) {
return redisTemplate.opsForHash().increment(key, hashKey, -delta);
}

/**
* zset添加分数
*
* @param key 关键
* @param value 价值
* @param score 分数
* @return {@link Double}
*/
public Double zIncr(String key, Object value, Double score) {
return redisTemplate.opsForZSet().incrementScore(key, value, score);
}

/**
* zset减少分数
*
* @param key 关键
* @param value 价值
* @param score 分数
* @return {@link Double}
*/
public Double zDecr(String key, Object value, Double score) {
return redisTemplate.opsForZSet().incrementScore(key, value, -score);
}

/**
* zset根据分数排名获取指定元素信息
*
* @param key 关键
* @param start 开始
* @param end 结束
* @return {@link Map<Object, Double>}
*/
public Map<Object, Double> zReverseRangeWithScore(String key, long start, long end) {
return redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end)
.stream()
.collect(Collectors.toMap(ZSetOperations.TypedTuple::getValue, ZSetOperations.TypedTuple::getScore));
}

/**
* 获取zset指定元素分数
*
* @param key 关键
* @param value 价值
* @return {@link Double}
*/
public Double zScore(String key, Object value) {
return redisTemplate.opsForZSet().score(key, value);
}

/**
* 获取zset所有分数
*
* @param key 关键
* @return {@link Map}
*/
public Map<Object, Double> zAllScore(String key) {
return Objects.requireNonNull(redisTemplate.opsForZSet().rangeWithScores(key, 0, -1))
.stream()
.collect(Collectors.toMap(ZSetOperations.TypedTuple::getValue, ZSetOperations.TypedTuple::getScore));
}

/**
* 获取Set结构
*
* @param key key
* @return 返回set集合
*/
public Set<Object> sMembers(String key) {
return redisTemplate.opsForSet().members(key);
}

/**
* 向Set结构中添加属性
*
* @param key key
* @param values value集
* @return 返回增加数量
*/
public Long sAdd(String key, Object... values) {
return redisTemplate.opsForSet().add(key, values);
}

/**
* 向Set结构中添加属性
*
* @param key key
* @param time 过期时间
* @param values 值集合
* @return 返回添加的数量
*/
public Long sAddExpire(String key, long time, Object... values) {
Long count = redisTemplate.opsForSet().add(key, values);
expire(key, time);
return count;
}

/**
* 是否为Set中的属性
*
* @param key key
* @param value value
* @return 返回是否存在
*/
public Boolean sIsMember(String key, Object value) {
return redisTemplate.opsForSet().isMember(key, value);
}

/**
* 获取Set结构的长度
*
* @param key key
* @return 返回长度
*/
public Long sSize(String key) {
return redisTemplate.opsForSet().size(key);
}

/**
* 删除Set结构中的属性
*
* @param key key
* @param values value集合
* @return 删除掉的数据量
*/
public Long sRemove(String key, Object... values) {
return redisTemplate.opsForSet().remove(key, values);
}

/**
* 获取List结构中的属性
*
* @param key key
* @param start 开始
* @param end 结束
* @return 返回查询的集合
*/
public List<Object> lRange(String key, long start, long end) {
return redisTemplate.opsForList().range(key, start, end);
}

/**
* 获取List结构的长度
*
* @param key key
* @return 长度
*/
public Long lSize(String key) {
return redisTemplate.opsForList().size(key);
}

/**
* 根据索引获取List中的属性
*
* @param key key
* @param index 索引
* @return 对象
*/
public Object lIndex(String key, long index) {
return redisTemplate.opsForList().index(key, index);
}

/**
* 向List结构中添加属性
*
* @param key key
* @param value value
* @return 增加后的长度
*/
public Long lPush(String key, Object value) {
return redisTemplate.opsForList().rightPush(key, value);
}

/**
* 向List结构中添加属性
*
* @param key key
* @param value value
* @param time 过期时间
* @return 增加后的长度
*/
public Long lPush(String key, Object value, long time) {
Long index = redisTemplate.opsForList().rightPush(key, value);
expire(key, time);
return index;
}

/**
* 向List结构中批量添加属性
*
* @param key key
* @param values value 集合
* @return 增加后的长度
*/
public Long lPushAll(String key, Object... values) {
return redisTemplate.opsForList().rightPushAll(key, values);
}

/**
* 向List结构中批量添加属性
*
* @param key key
* @param time 过期时间
* @param values value集合
* @return 增加后的长度
*/
public Long lPushAll(String key, Long time, Object... values) {
Long count = redisTemplate.opsForList().rightPushAll(key, values);
expire(key, time);
return count;
}

/**
* 从List结构中移除属性
*
* @param key key
* @param count 总量
* @param value value
* @return 返回删除后的长度
*/
public Long lRemove(String key, long count, Object value) {
return redisTemplate.opsForList().remove(key, count, value);
}

/**
* 向bitmap中新增值
*
* @param key key
* @param offset 偏移量
* @param b 状态
* @return 结果
*/
public Boolean bitAdd(String key, int offset, boolean b) {
return redisTemplate.opsForValue().setBit(key, offset, b);
}

/**
* 从bitmap中获取偏移量的值
*
* @param key key
* @param offset 偏移量
* @return 结果
*/
public Boolean bitGet(String key, int offset) {
return redisTemplate.opsForValue().getBit(key, offset);
}

/**
* 获取bitmap的key值总和
*
* @param key key
* @return 总和
*/
public Long bitCount(String key) {
return redisTemplate.execute((RedisCallback<Long>) con -> con.bitCount(key.getBytes()));
}

/**
* 获取bitmap范围值
*
* @param key key
* @param limit 范围
* @param offset 开始偏移量
* @return long类型集合
*/
public List<Long> bitField(String key, int limit, int offset) {
return redisTemplate.execute((RedisCallback<List<Long>>) con ->
con.bitField(key.getBytes(),
BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(limit)).valueAt(offset)));
}

/**
* 获取所有bitmap
*
* @param key key
* @return 以二进制字节数组返回
*/
public byte[] bitGetAll(String key) {
return redisTemplate.execute((RedisCallback<byte[]>) con -> con.get(key.getBytes()));
}

/**
* 向hyperlog中添加数据
*
* @param key key
* @param value 值
* @return {@link Long}
*/
public Long hyperAdd(String key, Object... value) {
return redisTemplate.opsForHyperLogLog().add(key, value);
}

/**
* 获取hyperlog元素数量
*
* @param key key
* @return {@link Long} 元素数量
*/
public Long hyperGet(String... key) {
return redisTemplate.opsForHyperLogLog().size(key);
}

/**
* 删除hyperlog数据
*
* @param key key
*/
public void hyperDel(String key) {
redisTemplate.opsForHyperLogLog().delete(key);
}

/**
* 增加坐标
*
* @param key key
* @param x x
* @param y y
* @param name 地点名称
* @return 返回结果
*/
public Long geoAdd(String key, Double x, Double y, String name) {
return redisTemplate.opsForGeo().add(key, new Point(x, y), name);
}

/**
* 根据城市名称获取坐标集合
*
* @param key key
* @param place 地点
* @return 坐标集合
*/
public List<Point> geoGetPointList(String key, Object... place) {
return redisTemplate.opsForGeo().position(key, place);
}

/**
* 计算两个城市之间的距离
*
* @param key key
* @param placeOne 地点1
* @param placeTow 地点2
* @return 返回距离
*/
public Distance geoCalculationDistance(String key, String placeOne, String placeTow) {
return redisTemplate.opsForGeo()
.distance(key, placeOne, placeTow, RedisGeoCommands.DistanceUnit.KILOMETERS);
}

/**
* 获取附该地点附近的其他地点
*
* @param key key
* @param place 地点
* @param distance 附近的范围
* @param limit 查几条
* @param sort 排序规则
* @return 返回附近的地点集合
*/
public GeoResults<RedisGeoCommands.GeoLocation<Object>> geoNearByPlace(String key, String place, Distance distance, long limit, Sort.Direction sort) {
RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().includeCoordinates();
// 判断排序方式
if (Sort.Direction.ASC == sort) {
args.sortAscending();
} else {
args.sortDescending();
}
args.limit(limit);
return redisTemplate.opsForGeo()
.radius(key, place, distance, args);
}

/**
* 获取地点的hash
*
* @param key key
* @param place 地点
* @return 返回集合
*/
public List<String> geoGetHash(String key, String... place) {
return redisTemplate.opsForGeo()
.hash(key, place);
}

}