일하면서 터진 문제 중, 올려도 될만한 문제들을 포스팅하려고 합니다.
제 포스팅은 적용 방법만 보시고, 어떤 상황에 적용할지는 고민을 좀 더 하셨으면 좋겠습니다.
취준생일때나 개인 프로젝트 할때 보시면 크게 문제는 안될것같습니다
배경
@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를 써서 가져오기 때문에, 가져오는 데이터의 수가 많을 경우 성능 부하가 있을 수 있습니다.
저의 경우 데이터 양 자체가 크지 않아서 적용하였지만, 사용하기전에 현재 상황에 적절한 방법인지 고민을 하셨으면 좋겠습니다.
초보 개발자의 글이라 부족한 점이 많습니다. 잘못된 점 등을 말씀해주시면 감사히 받겠습니다.