본문 바로가기
프로그래밍/Java

[Spring/Redis] spring에서 redisTemplate을 쓰는 것과 CRUDRepository를 상속받아 사용하는 것은 어떤 차이가 있을까?

by 물고기고기 2023. 9. 14.

Spring에서 redis에 데이터를 저장하는 방법 중 두가지와 두가지를 섞어쓰면서 내가 겪은 상황도 같이 설명하고자 한다.

 

일단 redisTemplate이란 뭘까? redisTemplate은 Spring에서 따로 관리하지 않고 직접 Redis명령어를 사용한다고 보면된다. 예를 들어 우리가 아는 Redis의 CRUD 명령어나 key값을 조회하는 명령어등을 Spring에서 제공하는 메소드를 통해 직접 요청을 날린다고 보면 된다. SQL로 따지면 mybatis로 쿼리를 직접 작성하는것과 비슷하다고 볼 수 있다. CRUDRepository를 사용하는 것은 Spring에서 제공하는 JPA를 활용해 우리가 아는 익숙한 JpaRepository를 활용하는 것과 비슷하다 다만 SQL, 테이블의 형식을 갖지 않은 DB를 사용할때 CRUDRepository를 사용한다고 보면 된다.

 

각 활용 예제는 

RedisTemplate의 경우

  •  의존성 추가
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
  • 예제
@Service
public class RedisService {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public void set(String key, String value) {
        redisTemplate.opsForValue().set(key, value);
    }

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

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

CRUDRepository의 경우

  • 의존성 추가
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.h2</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>
  • 예제
    JpaRepository를 사용할때와 동일하게 Entity 클래스 작성 -> Repository 클래스 작성하여 사용하면 된다.
// 1. 엔티티 생성
@Entity
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    // getter, setter 등의 메서드는 생략
}


// 2. 레포지토리 생성
public interface PersonRepository extends CrudRepository<Person, Long> {
}

 

그럼 이 코드에 따른 둘의 동작에는 어떤 차이가 있을까?

RedisTemplate CRUDRepository
Redis의 데이터베이스와 직빵으로 통신하는 데에 사용됨 CRUDRepository는 주로 관계형 데이터베이스와 통신하는 데 사용되는 Spring Data JPA의 일부
 단순한 키-값 저장에서 리스트, 셋, 해시 등의 복잡한 데이터 구조에 이르기까지 Redis에서 지원하는 모든 기능을 사용할 수 있음 메소드 이름만으로 간단한 쿼리를 자동으로 생성할 수 있음
RedisTemplate에서 데이터를 Redis에 저장하거나 검색할 때 직렬화 및 역직렬화가 필요함 JPA의 고질적인 문제점인데 간단한 쿼리밖에 사용하지 못함

요약하자면 RedisTemplate은 쿼리가 자동생성되지 않고 Redis의 모든 명령어를 사용할 수 있으나 직렬화 및 역직렬화를 코드에 직접 추가해줘야하는 불편함이 있다. 그러나 이건 이론상의 이야기고 조금 더 파보면 CRUDRepository에서 추가적으로 데이터를 관리해주기도 한다.

 

이게 무슨 얘기냐면 Spring Data Redis를 사용하여 CRUDRepository를 활용하면, 이를 통해 관리되는 객체에 대한 정보가 Redis에 저장된다. 일반적으로 해당 엔터티에 대한 메타데이터와 함께 데이터가 저장되고 이를 통해 객체를 저장, 조회, 삭제하는 과정이 어떻게 동작하는지 개발자가 직접적으로 알지 않아도 된다.(추상화된다는 뜻)

반면, RedisTemplate을 사용하면 직접 Redis 명령을 실행하게 된다.
따라서 RedisTemplate로 저장된 데이터는 직접 관리해야 한다.(CRUDRepository가 관리하는 메타데이터에는 해당 데이터가 저장되지 않기때문에)

 

이에 대해 GPT에게 이 둘을 교차로 쓰려면 어떤걸 주의해야 하냐고 물어봤다.

pring Data Redis에서 CRUDRepository를 사용할 때, 데이터는 일반적으로 특정한 포매팅과 함께 Redis에 저장됩니다. 이 포매팅은 RedisTemplate로 직접적인 저장 방식과는 다를 수 있습니다. CRUDRepository를 통해 관리되는 엔터티의 키 포맷팅은 특정 규칙에 따라 생성되며, 이를 통해 각 객체는 Redis 내에서 구별됩니다.

이 규칙과 포매팅이 RedisTemplate을 사용할 때와 다르기 때문에, RedisTemplate로 직접 저장한 데이터는 CRUDRepository를 통해 바로 조회하기 어려울 수 있습니다. 반대의 경우도 마찬가지입니다.

따라서 RedisTemplate으로 저장한 데이터를 CRUDRepository로 조회하려면:

CRUDRepository가 사용하는 키 포맷을 정확히 알아야 합니다.
해당 포맷에 따라 RedisTemplate을 사용하여 데이터를 저장해야 합니다.
그러나 이런 방식은 권장되지 않습니다. 데이터를 저장하고 조회하는 방식을 명확하게 분리하는 것이 좋습니다. CRUDRepository로 데이터를 저장하고 조회할 경우, 같은 방식을 계속 사용하는 것이 바람직합니다. 반대로, RedisTemplate을 사용하려면 CRUDRepository 없이 계속해서 그 방식을 사용하는 것이 좋습니다.

만약 CRUDRepository와 RedisTemplate을 함께 사용해야 하는 특별한 이유가 있다면, 각 도구의 특성과 한계를 정확히 파악하고 사용해야 합니다.

 

요는 이 둘을 섞어쓰는 방식은 추천하지 않는다는거다. RedisTemplate로 생성한 데이터는 CRUDRepository로 추적하지 않고있어 조회가 불가능하는 등의 에러가 날수도 있기때문이다.

 


참고한 글

댓글