본문 바로가기

WEB/Spring

[Spring, JPA] @OrderBy로 정렬하기, OneToMany 특정 칼럼 기준 정렬

일하면서 터진 문제 중, 올려도 될만한 문제들을 포스팅하려고 합니다.

제 포스팅은 적용 방법만 보시고, 어떤 상황에 적용할지는 고민을 좀 더 하셨으면 좋겠습니다.

취준생일때나 개인 프로젝트 할때 보시면 크게 문제는 안될것같습니다


배경

 

@OneToMany 관계로 매핑된 엔티티를 조회할 때, 정렬 순서가 중요한 요구사항이 생겼습니다.

HappyStair Entity는 여러개의 HappyStairTarget을 가지고 있습니다. 즉 OneToMany 관계입니다.
HappyStairTarget은 orders라는 칼럼을 가지고 있고 이는 순서를 나타냅니다.

항상 이 orders를 기준으로 정렬된 상태로 가지고 와야하는 상황입니다.

 

처음에는 List<HappyStairTarget>을 가져온 뒤 Collections.sort()를 사용하였지만 매번 사용하는것이 번거로웠습니다.

JPA의 @OrderBy 어노테이션을 사용하면, 데이터 조회 시점에 DB 쿼리에 ORDER BY 절을 추가하여 자동으로 정렬된 상태로 가져올 수 있습니다.

 

구현방법

 

1. 엔티티 설정

@Getter
@Entity
@Table(name = "happy_stair")
public class HappyStair {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany(
            mappedBy = "happyStair",
            fetch = FetchType.LAZY,
            cascade = CascadeType.ALL,
            orphanRemoval = true
    )

    // @OrderBy("orders ASC, name DESC")    // 다중 정렬 조건
    @OrderBy("orders ASC")
    private List<HappyStairTarget> happyStairTargetList = new ArrayList<>();


}

 

@OrderBy는 @OneToMany, @ManyToMany가 매핑된 필드에 적용할 수 있습니다.

원하는 정렬 기준으로 사용할 필드와 정렬순서(ASC, DESC)를 지정해주면 됩니다.

저는 HappyStairTarget의 orders를 기준으로 오름차순으로 정렬하였습니다.

쉼표로 구분하여 다중 정렬조건을 사용할 수도 있습니다.

 

 

2. 사용

@Service
@RequiredArgsConstructor
public class HappyStairService {
    private final HappyStairRepository happyStairRepository;

    @Transactional(readOnly = true)
    public HappyStairListResponse searchList(Account account) {
        HappyStair entity = happyStairRepository.findByAccount(account).orElse(null);
        
        List<HappyStairTarget> targetList = entity.getHappyStairTargetList();
        
       // 이외 로직...
       
        return new HappyStairListResponse(...);
    }
}

 

 

위는 예시로 가져온 서비스 로직입니다.

저는 lombok의 getter을 사용하여 가지고 왔습니다. 이렇게 불러와진 targetList는 orders 순으로 이미 정렬이 되어있는 상태입니다.

여기서 중요한 부분은 @OrderBy에서는 DB 칼럼명이 아닌 엔티티 필드명을 사용해야 한다는 겁니다.

 

3. 주의사항

 

@OrderBy를 사용하면 JPA는 쿼리에서 ORDER BY를 실행합니다.

DB에서 가져올 때 ORDER BY를 써서 가져오기 때문에, 가져오는 데이터의 수가 많을 경우 성능 부하가 있을 수 있습니다.

저의 경우 데이터 양 자체가 크지 않아서 적용하였지만, 사용하기전에 현재 상황에 적절한 방법인지 고민을 하셨으면 좋겠습니다.


초보 개발자의 글이라 부족한 점이 많습니다. 잘못된 점 등을 말씀해주시면 감사히 받겠습니다.