Chris Devlog

Mysql에서 Json type 활용하기(3) 본문

Spring Boot/JPA

Mysql에서 Json type 활용하기(3)

Chris Dev Heo 2025. 1. 2. 01:11
반응형

들어가며


이전글 Mysql에서 Json type 활용하기(2)에서 findById를 통해 데이터를 재조회 하는 로직을 JpaRepository에 saveAndRefresh 함수를 추가함으로써 여러 엔티티에서도 코드 추가없이 사용할 수 있도록 설정을 추가해보겠습니다

설정 추가하기


1. BaseRepository

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.NoRepositoryBean;

@NoRepositoryBean
public interface BaseRepository<T, ID> extends JpaRepository<T, ID> {
  T saveAndRefresh(T entity);
}

 

2. BaseRepositoryImpl

import jakarta.persistence.EntityManager;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.data.repository.core.EntityInformation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

public class BaseRepositoryImpl<T, ID> extends SimpleJpaRepository<T, ID> implements BaseRepository<T, ID> {

  private final EntityManager entityManager;

  public BaseRepositoryImpl(EntityInformation<T, ID> entityInformation, EntityManager entityManager) {
    super((JpaEntityInformation<T, ?>) entityInformation, entityManager);
    this.entityManager = entityManager;
  }

  /**
   * 데이터베이스에 대한 save와 refresh 작업을 수행하므로 트랜잭션 내에서 실행되어야 함.
   */
  @Override
  @Transactional(propagation = Propagation.MANDATORY)
  public T saveAndRefresh(T entity) {
    // save 호출
    T savedEntity = super.save(entity);
    // 영속성 컨텍스트 갱신
    entityManager.refresh(savedEntity);
    return savedEntity;
  }
}

 

3. JpaConfig

import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@Configuration
@EnableJpaRepositories(
    basePackages = "com.dev.domain", // 리포지토리 경로
    repositoryBaseClass = BaseRepositoryImpl.class // 커스텀 구현체 지정
)
public class JpaConfig {

}


위 설정을 통해 기존 JpaRepository에는 없는 saveAndRefresh함수를 사용할 수 있게되며, 함수는 기본적으로 save와 refresh를 수행해야하기때문에 Propagation.MANDATORY로 설정하여 트랜잭션내에서만 실행될 수 있도록 함

4. JsonToStrRepository

import com.dev.config.jpa.BaseRepository;
import com.dev.domain.json_to_str.JsonToStr;

public interface JsonToStrRepository extends BaseRepository<JsonToStr, Long> {

}

 

기존의 JpaRepository extends 를 BaseRepository로 변경

 

활용하기


1. saveAndRefresh

  @Autowired
  JsonToStrRepository jsonToStrRepository;

  @Test
  void test1() {
    String json = "{\"key1\": \"value1\", \"key2\": 30000, \"key3\": \"2024-12-30 02:27:00\"}";

    JsonToStr jsonToStr = jsonToStrRepository.saveAndRefresh(JsonToStr.builder()
        .jsonData(json)
        .build());

    Assertions.assertEquals("value1", jsonToStr.getKey1());
    Assertions.assertEquals(30000, jsonToStr.getKey2());

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    Assertions.assertEquals(LocalDateTime.parse("2024-12-30 02:27:00", formatter), jsonToStr.getKey3());

  }

Result > 
  Execute DML : 
    insert 
    into
        json_to_str
        (create_at, json_data) 
    values
        ('2024-12-31T22:07:17.462+0900', cast('{"key1": "value1", "key2": 30000, "key3": "2024-12-30 02:27:00"}' as json))

  Execute DML : 
    select
        jts1_0.json_test_id,
        jts1_0.create_at,
        jts1_0.json_data,
        jts1_0.key1,
        jts1_0.key2,
        jts1_0.key3 
    from
        json_to_str jts1_0 
    where
        jts1_0.json_test_id=6
        
Tests passed: 1

 

saveAndRefresh를 통해 이전글의 findById 로직을 생략 할 수 있음

 

끝으로


처음 Json type을 RDB에서 활용하는법을 찾아봤던 이유는 외부 API를 통한 데이터 수집시 수집된 데이터를 저장하면서 겪는 불편한 점

 

1. 데이터 매핑을 위해 DTO를 만드는과정

2. JDBCTemplarte를 이용한 벌크 인설트 시 일일히 데이터를 매핑해야하는점

3. 당장은 활용하지 않더라도 데이터는 수집해야하는상황에서 불필요한 컬럼을 추가해야하는점

4. Object Mapper와 Gson 사용중 오류가 발생하면 로그를 통해서 데이터를 확인해야하는점

 

등등 을 해소하기위한 방법을 찾아보면서 json 데이터를 활용할 방법이 없을지를 고민해보면서 였습니다

물론 다른 방법들로도 문제점을 해소할 수 있겠지만 이런 방법을 찾고계셨던 분들에게 도움이 되었으면 합니다.

반응형

'Spring Boot > JPA' 카테고리의 다른 글

Mysql에서 Json type 활용하기(2)  (1) 2024.12.31
Mysql에서 Json type 활용하기(1)  (0) 2024.12.30