Spring 访问 Redis

Spring 访问 Redis

简介

Redis 是一个被数百万开发人员用作数据库、缓存、流引擎和消息代理的开源内存数据库。

在 Spring 中,spring-data-redis 项目对访问 Redis 进行了 API 封装,提供了便捷的访问方式。 spring-data-redis

spring-boot 项目中的子模块 spring-boot-starter-data-redis 基于 spring-data-redis 项目,做了二次封装,大大简化了 Redis 的相关配置。

Spring Boot 快速入门

引入依赖

在 pom.xml 中引入依赖:

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

数据源配置

1
2
3
4
spring.redis.database = 0
spring.redis.host = localhost
spring.redis.port = 6379
spring.redis.password =

定义实体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import java.io.Serializable;

@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {

private static final long serialVersionUID = 4142994984277644695L;

private Long id;
private String name;
private Integer age;
private String address;
private String email;

}

定义 CRUD 接口

1
2
3
4
5
6
7
8
9
10
11
12
13
import java.util.Map;

public interface UserService {

void batchSetUsers(Map<String, User> users);

long count();

User getUser(Long id);

void setUser(User user);

}

创建 CRUD 接口实现

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

import cn.hutool.core.bean.BeanUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Map;

@Service
public class UserServiceImpl implements UserService {

public static final String DEFAULT_KEY = "spring:tutorial:user";

private final RedisTemplate<String, Object> redisTemplate;

public UserServiceImpl(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}

@Override
public void batchSetUsers(Map<String, User> users) {
redisTemplate.opsForHash().putAll(DEFAULT_KEY, users);
}

@Override
public long count() {
return redisTemplate.opsForHash().size(DEFAULT_KEY);
}

@Override
public User getUser(Long id) {
Object obj = redisTemplate.opsForHash().get(DEFAULT_KEY, id.toString());
return BeanUtil.toBean(obj, User.class);
}

@Override
public void setUser(User user) {
redisTemplate.opsForHash().put(DEFAULT_KEY, user.getId().toString(), user);
}

}

创建 Application

创建 Application,实例化一个 RedisTemplate 对象。

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
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Slf4j
@SpringBootApplication
public class RedisQuickstartApplication {

@Autowired
private ObjectMapper objectMapper;

@Bean
@Primary
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {

// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
// objectMapper.activateDefaultTyping(new DefaultBaseTypeLimitingValidator(),
// ObjectMapper.DefaultTyping.NON_FINAL);

// 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
serializer.setObjectMapper(objectMapper);

RedisTemplate<String, Object> template = new RedisTemplate<>();
// 配置连接工厂
template.setConnectionFactory(factory);
// 值采用json序列化
template.setValueSerializer(serializer);
// 使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
// 设置hash key 和value序列化模式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();

return template;
}

public static void main(String[] args) {
SpringApplication.run(RedisQuickstartApplication.class, args);
}

}

测试

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
@Slf4j
@SpringBootTest(classes = { RedisQuickstartApplication.class })
public class RedisQuickstartTests {

@Autowired
private UserService userService;

@Test
public void test() {
final long SIZE = 1000L;
Map<String, User> map = new HashMap<>();
for (long i = 0; i < SIZE; i++) {
User user = new User(i, RandomUtil.randomChineseName(),
RandomUtil.randomInt(1, 100),
RandomUtil.randomEnum(Location.class).name(),
RandomUtil.randomEmail());
map.put(String.valueOf(i), user);
}
userService.batchSetUsers(map);
long count = userService.count();
Assertions.assertThat(count).isEqualTo(SIZE);

for (int i = 0; i < 100; i++) {
long id = RandomUtil.randomLong(0, 1000);
User user = userService.getUser(id);
log.info("user-{}: {}", id, user.toString());
}
}

}

示例源码

更多 Spring 访问 Redis 示例请参考:Redis 示例源码

参考资料