레디스 With 스프링

김파란·2024년 7월 29일

Spring-Library

목록 보기
3/7

참고) https://developer-nyong.tistory.com/21

1. 환경설정

spring:
  data:
    redis:
      host: localhost
      port: 6379

2. RedisConfig

  • 따로 빈 등록을 안해도 실행은 되는데, 직접 redis-cli로 데이터 확인이 어렵다
  • 그리고 배포했을때 redis를 AWS로 올려야하는데 위치찾기도 안되기 때문에 Config로 설정해놓자
@Configuration
public class RedisConfig {
    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    // Redis 연결 팩토리 설정
    @Bean
    public LettuceConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory(redisHost, redisPort);
    }

    // RedisTemplate 설정
     @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory());

        // 일반적인 key:value의 경우 시리얼라이저
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        // json으로 변경
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());

        // Hash를 사용할 경우 시리얼라이저
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new StringRedisSerializer());

        // 모든 경우
        redisTemplate.setDefaultSerializer(new StringRedisSerializer());

        return redisTemplate;
    }
}

3. Redis 사용법

  • 전체삭제: flushall
  • 전체키 찾기: keys *

메서드 명 || 레디스 타입
opsForValue || String
opsForList || List
opsForSet || Set
opsForZSet || Sorted Set
opsForHash || Hash

// 자바 map.putIfAbsent()랑 똑같이 없으면 넣고 있으면 false를 반환하는 식도 할 수 있다
public Boolean lock(Long key) {
        return redisTemplate
                .opsForValue()
                .setIfAbsent(generateKey(key), "lock", Duration.ofMillis(3_000));
    }
    // 1씩 올리는 것도 가능
    redisTemplate.opsForZSet().add(KEY,keyword,1);
        redisTemplate.opsForZSet().incrementScore(KEY,keyword,1);
        redisTemplate.opsForZSet().incrementScore(KEY,keyword,1);

4. Repository

  • Redis에 저장할때는 CrudRepository or RedisTemplate를 쓰면 된다
  • CrudRepository로 저장할 때는 기존 CrudRepository랑 똑같이 findBy~가 되지만 redis-cli에서 찾기 어렵다
  • RedisTemplate를 쓴다면 redis-cli에서 찾을 수 있지만 findBy~가 안된다

1). CrudRepository

  • RedisTemplate 설정을 안해도 된다
  • 다만 Entity Serializable을 해줘야한다 (직렬화)
  • @Id, @indexed 붙은것만 FindBy~ 를 할 수 있다
  • @TimeTiLive로 expiration을 줄 수 있다
  1. Entity 설정
  2. Crud Repository 만들기
  3. 사용

(1). Entity

@RedisHash("refreshTokenEntity")
@Getter
@NoArgsConstructor
@ToString
public class RefreshTokenEntity implements Serializable {

    @Id
    private String id;

    private String loginId;
    @Column(length = 512)
    @Indexed
    private String refreshToken;
    @TimeToLive
    private Long ttl;

    public RefreshTokenEntity(String loginId, String refreshToken) {
        this.id = UUID.randomUUID().toString();
        this.loginId = loginId;
        this.refreshToken = refreshToken;
        this.ttl =  JwtVO.REFRESH_TOKEN_EXPIRES_TIME;
    }
}

(2). Repository

public interface RefreshTokenRepository extends CrudRepository<RefreshTokenEntity, String> {
    Optional<RefreshTokenEntity> findByRefreshToken(String refreshToken);

    @Transactional
    void deleteByRefreshToken(String refreshToken);

    Boolean existsByRefreshToken(String refreshToken);
}

(3). 사용

    @Test
    @DisplayName("RedisRepository를 활용")
    void redis_repository_test() throws Exception {
        RefreshTokenEntity refreshTokenEntity = new RefreshTokenEntity("hi", "123");
        refreshTokenRepository.save(refreshTokenEntity);
        Optional<RefreshTokenEntity> byRefreshToken = refreshTokenRepository.findByRefreshToken("123");
        RefreshTokenEntity refreshTokenEntity1 = byRefreshToken.get();
        System.out.println("refreshTokenEntity1 = " + refreshTokenEntity1)
        ;
    }

2). RedisTemplate

(1). Template 설정

    @Bean
    public RedisTemplate<String, Object> redisTEmplate(){
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory());

        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());

        return redisTemplate;
    }

(2). 사용

    private final RedisTemplate<String, Object> redisTemplate;

    @Transactional
    public void saveRefreshToken(String key, Object value) {
        redisTemplate.opsForValue().set(key, value, JwtVO.REFRESH_TOKEN_EXPIRES_TIME, TimeUnit.MILLISECONDS);
    }

    public Object getRefreshToken(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    public void deleteToken(String key) {
        redisTemplate.delete(key);
    }


    public boolean existsByRefreshToken(String refreshToken) {
        
        return true;

    }

0개의 댓글