본문으로 바로가기

[JPA] UPSERT 방법 (없으면 Insert , 있으면 Update)

category 카테고리 없음 2022. 2. 18. 09:24

목적

JPA를 사용하여 테이블에 특정 조건의 데이터가 없으면 Insert , 있으면 Update 하는 방법

 

단계

1. 있는 지 없는 지 검색하는 쿼리 사용

2. 데이터 있는 경우(Insert) 검색된 entity에 Key를 포함한 전체 데이터를 Set 한다.

3. 데이터 없는 경우(Update) 검색된 entity에 Key를 제외한 데이터를 Set 한다.

(Key를 제외한 데이터만 Update하면 된다)

4. jpa의 save 실행

 

코드 설명

AdStatistics adStatistics = new AdStatistics();
			
adStatistics = adStatisticsRepository.findByColdateAndColhour(coldate, colhour);


if(adStatistics != null) {
    // 데이터 있으므로 update
    adStatistics.setReq_cnt(req_cnt);
    adStatistics.setRes_cnt(res_cnt);
    adStatistics.setCtr_cnt(ctr_cnt);

} else {
    adStatistics = new AdStatistics();
    // 데이터 없으므로 insert
    adStatistics.setColdate(coldate);
    adStatistics.setColhour(colhour);
    adStatistics.setReq_cnt(req_cnt);
    adStatistics.setRes_cnt(res_cnt);
    adStatistics.setCtr_cnt(ctr_cnt);
}

adStatisticsRepository.save(adStatistics);

※변수명은 개인 프로젝트 하면서 진행한거라 보기 어려우실 수 있습니다. 양해 부탁드립니다.

 

1. findByColdateAndColhour(coldate, colhour)

coldate, colhour 두가지를 만족하는 where 조건을 사용하여 select를 한다.

find로 해야한다.

find는 조회된 첫번째 쿼리만 가져오고 findAll은 조회된 모든 쿼리를 가져오기 때문.

 

2. if(adStatistics != null) {

조회된 entity로 null 체크

 

3. Update인 경우 (if 첫번째 조건)

    adStatistics.setReq_cnt(req_cnt);
    adStatistics.setRes_cnt(res_cnt);
    adStatistics.setCtr_cnt(ctr_cnt);

Key로 사용했던 coldate, colhour는 업데이트 할 필요 없으므로 제외한다.

 

4. Insert인 경우 (else 조건)

    adStatistics = new AdStatistics();
    // 데이터 없으므로 insert
    adStatistics.setColdate(coldate);
    adStatistics.setColhour(colhour);
    adStatistics.setReq_cnt(req_cnt);
    adStatistics.setRes_cnt(res_cnt);
    adStatistics.setCtr_cnt(ctr_cnt);

Key로 사용했던 coldate, colhour 까지 Set하여 업데이트 해준다.

※주의

이때 new 선언을 한번 더 해야한다.

1단계에서 entity가 null로 반환되어 nullException error 가 발생하는 걸 방지.

 

5. adStatisticsRepository.save(adStatistics);

마지막으로 save하면 완료된다.

 

후기

코드 작성 소요 시간은 대략 2시간 걸렸다.

Insert시 null 에러를 잡느라 시간이 꽤 걸렸다.

Mysql에선 duplicate key update 를 사용해서 간단하게 했는데

JPA에선 뭔가 정형화된 것 같진 않다. 내가 아직 미숙해서 그런거겠지.

방법이 틀렸거나 문의사항 댓글 달아주세요~ 감사합니다.