docker run -p 6379:6379 --name redis -d redis
명령어로 실행시킨 뒤
docker exec -it redis /bin/bash
컨테이너에 접속
redis-cli
로 접근하면 redis 명령어로 조회할 수 있다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.6.7</version>
</dependency>
redis 의존성을 추가시켜준다.
@Configuration
@EnableRedisRepositories
@RequiredArgsConstructor
public class RedisConfig {
private final RedisProperties redisProperties;
@Bean
public RedisConnectionFactory redisConnectionFactory(){
return new LettuceConnectionFactory(redisProperties.getHost(), redisProperties.getPort());
}
@Bean
public RedisTemplate<String, Object> redisTemplate(){
RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
//redisTemplate.setKeySerializer(new StringRedisSerializer()); //key serializer
//redisTemplate.setValueSerializer(new StringRedisSerializer()); //value serializer
//redisTemplate.setHashKeySerializer(new StringRedisSerializer());
//redisTemplate.setHashValueSerializer(new StringRedisSerializer());
//redisTemplate.setDefaultSerializer(new StringRedisSerializer());
return redisTemplate;
}
}
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
@RedisHash(value = "refreshToken")
public class RefreshToken {
@Id
private String userId;
private String refreshToken;
@TimeToLive
private long expiredTime;
}
redis의 hash로 저장하기 위해 코드를 작성했다.
@RedisHash
저장시 hash key 값
@TimeToLive
redis 내에 저장될 시간을 정의
@Id
jpa 용 hibernate id가 아닌 org.springframework.data.annotation.Id
import 해야됨
public interface RefreshTokenRedisRepository extends CrudRepository<RefreshToken, String> {
}
public interface AdminUserRedisService {
RefreshToken save(RefreshToken adminUserToken);
RefreshToken findById(String userId);
}
@Service
@RequiredArgsConstructor
@Slf4j
public class AdminUserRedisServiceImpl implements AdminUserRedisService {
private final RefreshTokenRedisRepository refreshTokenRedisRepository;
@Override
public RefreshToken save(RefreshToken adminUserToken) {
return refreshTokenRedisRepository.save(adminUserToken);
}
@Override
public RefreshToken findById(String userId) {
return refreshTokenRedisRepository.findById(userId).get();
}
}
이렇게 정의하면 끝났다.
resdisTemplate을 사용할 수도 있는데. 우선은 내가 저장하려는 데이터가 hash 형태로 저장하는게 좋을거 같고 jpa가 자동으로 해주기 때문에 다른 코드들과 통일성 있게 가게 하기 위해서 우선 이렇게 작성했다.
@SpringBootTest(properties = "spring.cloud.config.enabled=false")
class AdminUserRedisServiceImplInteTest {
@Autowired
private AdminUserRedisService adminUserRedisService;
@DisplayName("token redis 저장 success")
@Test
void tokenSave(){
//given
RefreshToken token = RefreshToken.builder()
.userId("test")
.refreshToken("test_token")
.expiredTime(60) //테스트용 1분
.build();
//when
RefreshToken refreshToken = adminUserRedisService.save(token);
//then
RefreshToken findToken = adminUserRedisService.findById(token.getUserId());
System.out.println(refreshToken.getRefreshToken());
System.out.println(findToken.getRefreshToken());
assertEquals(refreshToken.getRefreshToken(), findToken.getRefreshToken());
}
}
해당 코드로 테스트를 해보자.
keys *
hgtall refreshToken:test
를 통해 결과를 확인해보면 다음과 같이 모두 정상적으로 등록되었고 우리가 파기 시간으로 정해둔 1분 뒤에 다시 검색해보면
파기되어진 것도 확인할 수 있다.
jpa로 활용하여 사용하니 코드 작성도 간편했고 공부할 것도 없이 잘 되었다.
redis의 다른 자료구조를 사용하고자 한다면 redisTemplate를 사용하여 적용시키면 될거 같다.
redisTemplate를 통해 더 다양한 자료구조를 사용할 수도 있다.
@Configuration
@EnableRedisRepositories
@RequiredArgsConstructor
public class RedisConfig {
private final RedisProperties redisProperties;
@Bean
public RedisConnectionFactory redisConnectionFactory(){
return new LettuceConnectionFactory(redisProperties.getHost(), redisProperties.getPort());
}
@Bean
public RedisTemplate<String, Object> redisTemplate(){
RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
//redisTemplate.setKeySerializer(new StringRedisSerializer()); //key serializer
//redisTemplate.setValueSerializer(new StringRedisSerializer()); //value serializer
//redisTemplate.setHashKeySerializer(new StringRedisSerializer());
//redisTemplate.setHashValueSerializer(new StringRedisSerializer());
redisTemplate.setDefaultSerializer(new StringRedisSerializer());
return redisTemplate;
}
}
설정 파일을 생성해주고 serializer 부분을 주석처럼 하나씩 설정해줘도 되지만 setDefaultSerializer()
를 통해 한번에 설정하는 것도 가능하다.
@SpringBootTest(properties = "spring.cloud.config.enabled=false")
class AdminUserRedisServiceImplInteTest {
@Autowired
private AdminUserRedisService adminUserRedisService;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@DisplayName("token redis 저장 success")
@Test
void tokenSave(){
//given
RefreshToken token = RefreshToken.builder()
.userId("test")
.refreshToken("test_token")
.expiredTime(60) //테스트용 1분
.build();
//when
RefreshToken refreshToken = adminUserRedisService.save(token);
//then
RefreshToken findToken = adminUserRedisService.findById(token.getUserId());
System.out.println(refreshToken.getRefreshToken());
System.out.println(findToken.getRefreshToken());
assertEquals(refreshToken.getRefreshToken(), findToken.getRefreshToken());
}
@DisplayName("redis template 사용")
@Test
@Transactional
void tokenSaveRedisTemplate(){
//given
String userId = "tester1";
RefreshToken token = RefreshToken.builder()
.userId(userId)
.refreshToken("test_token")
.expiredTime(60) //테스트용 1분
.build();
//when
String key = "refreshToken:"+userId;
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
hash.put(key, "userId", userId);
hash.put(key, "refreshToken", token.getRefreshToken());
//then
Object o = redisTemplate.opsForHash().get(key, "userId");
System.out.println(o);
}
}
jpa와 동일하게 데이터를 넣어주고 싶다면 다음과 같이 작성해야한다. hash 내부에 hash를 넣어서 작성할 수 있기도 하지만... 단점은 해당 데이터를 가져올때 key를 통해 하나씩 가져올 수 있는데 설정도 복잡해지고 template으로 객체를 하나씩 파싱해서 넣어줘야한다...
내가 redis를 잘 안써봐서 모르는 걸수도 있다.!
데이터를 성공적으로 저장시키면 다음과 같은 반환을 받을 수 있고 데이터를 가져오는것도 key-value라서 직접 template으로 가져오려고 하면 좀 코드도 길어지고 복잡해질거 같다. 객체 자체를 저장하는 용도는 jpa를 사용하고 특정 메세지나 특정 문자열만 저장하는 용도는 template으로 간단하게 하면 될거 같다!