banner
NEWS LETTER

08-spring-boot-整合redis

Scroll down

1 Spring boot整合redis

1.1 redis简介

l Redis 是一个高性能的开源的、C语言写的Nosql(非关系型数据库),数据保存在内存中。

l Redis 是以key-value形式存储,和传统的关系型数据库不一样。不一定遵循传统数据库的一些基本要求,比如说,不遵循sql标准,事务,表结构等等,非关系型数据库严格上不是一种数据库,应该是一种数据结构化存储方法的集合。

l Java中数据结构:String,数组,list,set map…

l Redis提供了很多的方法,可以用来存取各种数据结构的数据

1.2 什么是NoSql

NoSQL(NoSQL = Not Only SQL ),意即“不仅仅是SQL”,它泛指非关系型的数据库。随着互联网2003年之后web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的交友类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。

1.3 为什么用redis

1.数据保存在内存,存取速度快,并发能力强

2.它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、 zset(sorted set –有序集合)和hash(哈希类型)。

3.redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库(如MySQL)起到很好的补充作用。

4.它提供了Java,C/C++,C#,PHP,JavaScript等客户端,使用很方便。

5.Redis支持集群(主从同步)。数据可以主服务器向任意数量从的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。

6.支持持久化,可以将数据保存在硬盘的文件中

1.4 Redis使用场景

1:缓存,毫无疑问这是Redis当今最为人熟知的使用场景。再提升服务器性能方面非常有效。

2:排行榜,在使用传统的关系型数据库(mysql oracle 等)来做这个事儿,非常的麻烦,而利用Redis的SortSet(有序集合)数据结构能够简单的搞定。

3:利用Redis中原子性的自增操作,我们可以统计类似用户点赞数、用户访问数等,这类操作如果用MySQL,频繁的读写会带来相当大的压力;限速器比较典型的使用场景是限制某个用户访问某个API的频率,常用的有抢购时,防止用户疯狂点击带来不必要的压力;

4: 一些频繁被访问的数据,经常被访问的数据如果放在关系型数据库,每次查询的开销都会很大,而放在redis中,因为redis 是放在内存中的可以很高效的访问

springboot整合redis 环境搭建

1 导入依赖

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

2 加入配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#=======redis连接池配置==============

# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=20
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=10
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=0

3 创建redis配置类RedisConfig

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
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.lang.reflect.Method;
@Configuration
@EnableCaching // 启用缓存,使用 Lettuce,自动注入配置的方式
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisConfig extends CachingConfigurerSupport {

//缓存管理器
@Bean
@SuppressWarnings("all")
public CacheManager cacheManager(LettuceConnectionFactory factory) {
RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(factory);
RedisSerializationContext.SerializationPair pair =
RedisSerializationContext.SerializationPair.fromSerializer(
new Jackson2JsonRedisSerializer(Object.class));
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();

return new RedisCacheManager(writer, config);
}
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory);

// String 序列化方式
StringRedisSerializer stringSerializer = new StringRedisSerializer();
// 使用Jackson2JsonRedisSerialize替换默认序列化
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

// 设置key的序列化规则
redisTemplate.setKeySerializer(stringSerializer);
redisTemplate.setHashKeySerializer(stringSerializer);
// 设置value的序列化规则
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);

return redisTemplate;
}

// 重新定义缓存 key 的生成策略
@Bean
@Override
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params){
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for(Object obj:params){
sb.append(obj.toString());
}
return sb.toString();
}
};
}
}

4 搭建完毕

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
//设置字符串
redisTemplate.opsForValue().set("userName","张三");
//设置数字
redisTemplate.opsForValue().set("age",23);
UserInfo userInfo = new UserInfo();
userInfo.setUserName("rock");
userInfo.setUserPwd("123");
//设置对象
redisTemplate.opsForValue().set("userInfo",userInfo);

List<UserInfo> list = new ArrayList<>();
for(int i=0;i<3;i++){
UserInfo gg = new UserInfo();
gg.setUserName("rock"+i);
gg.setUserPwd("123"+i);
list.add(gg);
}
//设置集合对象
redisTemplate.opsForValue().set("userInfoList",list);

//获取 字符串
String userName = redisTemplate.opsForValue().get("userName")+"";
//获取 数字
int age =(int) redisTemplate.opsForValue().get("age");
//获取 对象
UserInfo u =(UserInfo) redisTemplate.opsForValue().get("userInfo");
//获取 集合对象
List<UserInfo> list1 = (List<UserInfo>)redisTemplate.opsForValue().get("userInfoList");

redis设置key的失效时间和获取失效时间

1
2
3
4
5
6
7
8
9
10
11
12
//设置key失效时间为2分钟
redisTemplate.opsForValue().set("userName","张三",2, TimeUnit.MINUTES);
//获取失效时间(默认时间单位是秒)
Long one =redisTemplate.getExpire("userName");
System.out.println(one+"");
//获取当前的失效时间(单位秒) 当给指定时间单位后,失效时间已经开始计时
Long two =redisTemplate.getExpire("userName",TimeUnit.SECONDS);
System.out.println(two+"");
//获取当前的失效时间(单位分钟) 当给指定时间单位后,失效时间已经开始计时
Long three =redisTemplate.getExpire("userName",TimeUnit.MINUTES);
System.out.println(three+"");

redis 数据自增和自减

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
public void three() {
//设置键one的数据自增,i++
redisTemplate.opsForValue().increment("one",1);
int dd = (int) redisTemplate.opsForValue().get("one");
System.out.println(dd);
}
@Test
public void four() {
//设置键one的数据递减 i--
redisTemplate.opsForValue().decrement("one",1);
int dd = (int) redisTemplate.opsForValue().get("one");
System.out.println(dd);
}

redis 设置获取缓存和清除缓存

1
2
3
4
5
6
7
8
9
10
11
12
//设置缓存
redisTemplate.opsForValue().set("address","成都",2,TimeUnit.MINUTES);
//获取缓存
String address = (String) redisTemplate.opsForValue().get("address");
System.out.println("删除之前="+address);
//清除缓存
boolean is = redisTemplate.delete("address");
System.out.println(is);
String addresss = (String) redisTemplate.opsForValue().get("address");
System.out.println("删除之后="+addresss);


案例:测试缓存提取数据效率高于数据库读取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//定义一个键名;
String key = "myClass";
long startTime = System.currentTimeMillis(); //获取开始时间
//查询数据库的数据
List<MyClass> list = myClassMapper.selectList(null);
long endTime = System.currentTimeMillis(); //获取结束时间
System.out.println("数据程序运行时间: " + (endTime - startTime) + "ms");

long startTime1 = System.currentTimeMillis(); //获取开始时间
//获取缓存数据
List<MyClass> list = (List<MyClass>) redisTemplate.opsForValue().get(key);
long endTime1 = System.currentTimeMillis(); //获取结束时间
System.err.println("缓存数据程序运行时间: " + (endTime1 – startTime1) + "ms");

其他文章
cover
  • 25/09/27
  • 15:00
  • 2.3k
  • 12
目录导航 置顶
  1. 1. 1 Spring boot整合redis
    1. 1.1. 1.1 redis简介
      1. 1.1.1. 1.2 什么是NoSql
      2. 1.1.2. 1.3 为什么用redis
      3. 1.1.3. 1.4 Redis使用场景
    2. 1.2. springboot整合redis 环境搭建
    3. 1.3. redis 数据设置和获取
    4. 1.4. redis设置key的失效时间和获取失效时间
    5. 1.5. redis 数据自增和自减
    6. 1.6. redis 设置获取缓存和清除缓存