티스토리 뷰

 JPA를 탐독한지 어느덧 약 두 달째가 된 것 같습니다. 처음에 JPA를 하면서 QueryDsl을 쓰려다가 Spring 3.0.0에서 QClass가 잘 생성되지 않는 문제가 있기도 하고, QueryDsl을 사용하기 위해 QClass + Impl 구현체까지 만든다는 게 가뜩이나 Entity 및 Repository 숫자가 넘쳐나는 데 저것까지 만든 다는 점이 마음에 안들어서 폐기했습니다. 그렇게 순수 Spring data로만 구현한지 벌써 2달 째.. 결국 QueryDsl 없이 모든 걸 구현하긴 했습니다. 아직 그렇게 꽤 마음에 드는 수준이 아니라 좀 더 공부를 하면서 리팩토링 해야겠지만.. 그 와 중에 하다보니 좋은 기능이 있어서 소개를 해드리려고 합니다.

소개 해드릴 기능은 Annotation인 @Formula 입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Entity
public class Employee implements Serializable {
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
 
    private long income;
 
    private int taxPercent;
 
    @Formula("income * taxPercent / 100")
    private long tax;
 
}
cs

 위 예제는 여러분들이 많이 보셨을 곳인

https://www.baeldung.com/hibernate-dynamic-mapping

이 곳에서 퍼왔습니다.

 

 보시면 @Formula를 통해 임의로 쿼리를 생성할 수 있음을 볼 수 있습니다. 그래서 이걸 찾은 저는 그렇게 생각이 들었습니다. 아? 이걸 잘 사용하면 서브쿼리 및 조건문으로 사용할 수 있겠네? 그리고 그 예감은 성공하고야 말았습니다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Entity
public class Employee implements Serializable {
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
 
    private long income;
 
    private int taxPercent;
 
    @Formula("(SELECT JOB_NM FROM EMPLOYEE_JOB EJ WHERE EJ.ID = ID)")
    private String jobNm;
 
}
cs

 위와 같이 alias에 유의하면서 잘 써주면 다른 테이블에 있는 데이터도 들고 올 수 있고, 카운트나 CASE WHEN, ROW_NUMBER() 등 다양하게 활용이 가능했습니다. 또한 Spring data를 기본적으로 사용하므로 Interface로 DTO를 작성할 때 @Formula가 선언된 부분은 제외해주면 따로 불러오지 않기에 적절하게 넣거나 뺄 수 있었습니다. 다만, 너무 서브쿼리로 떡칠을 하면 성능에 안 좋으니 유의하시기 바랍니다. 또 약점은 Join이 되는 테이블이 어떻게 Alias되는지 대충 유추는 가능하지만 확실하지 않아서 Join되는 테이블에 대한 조건문을 확실하게 걸 수 없다는 점도 있습니다. 그렇다고 하더라도 잘 쓰면 매우 편리하게 개발이 가능하니 알고 계시면 좋을 것 같습니다.

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday