이전에 다녔던 회사에서 JPA와 querydsl을 주로 사용해 비즈니스 로직을 구현해 서비스를 제공해주었다. 물론 외주받아 처음에 수행해주었던 SI 회사에서는 jdbc를 사용해 네이티브 쿼리를 사용했지만 사수가 입사 후에 JPA와 querydsl을 사용해 리팩토링을 했다. 나 또한 지금까지도 네이티브 쿼리보다는 JPA, querydsl을 많이 차용했고 필요한 데이터를 추출할 때의 과정에서는 디비버 툴을 사용해 해당 데이터베이스의 쿼리문을 직접 작성하여 확인하고 이를 querydsl로 변형하여 코드를 구성했었다.
문득, 이 방법에 대해서 옳은 방향인가에 대해 깊은 고민을 하기 시작했고 각자의 장점과 단점을 파악하기로 마음 먹었다.
네이티브 쿼리
스프링에서부터 네이티브 쿼리는 jdbc나 mybatis 라이브러리를 사용해 쿼리를 작성해온 것으로 보인다. 데이터베이스와 스프링 프레임워크 사이의 다리같은 역할로 sql의 질의 방식을 프레임워크 단에서 적용할 수 있도록 도와주는 것인데 대체적으로 우리가 흔히 하는 질의문을 다이렉트로 적는 그림이 보였다.
네이티브 쿼리의 장점은 특정 상황에 구애받지 않고 쿼리를 호출함에 문제가 없다는 것을 장점으로 볼 수 있다. 쿼리라는 게 다소 복잡해질 수 있지만 그에 대해 잘 알고 있다면 그것을 그대로 적어나가 기술할 수 있다는 것이다.
JPA, querydsl
JPA나 querydsl은 스프링이 발전해옴에 따라 좀 더 간편하게 쿼리를 호출할 수 있도록 도와주는 ORM이라고 보면 된다. 코드로 네이티브 쿼리와 비교하면 다음과 같다.
SELECT * FROM test t
네이티브 쿼리로 test라고 하는 테이블에서 모든 컬럼들을 추출하는 방식이다. 이를 JPA로 표현했을 땐 다음과 같다.
// Repository
@Repository
public class TestRepository extends JpaRepository<Test, Long> {
}
// Test Entity
@Entity
public class Test {
...Column
}
// Service Layer
@Service
public class TestService {
@Autowired
private TestRepository testRepository;
// 실제로는 엔티티를 호출하지 않으나 예제를 위해 엔티티 리턴
public List<Test> query() {
return testRepository.findAll();
}
}
JPA를 통해 호출하면 이와 같은 형식으로 데이터베이스에서 값을 추출하여 객체로써 리턴해줄 것이다.
// querydsl Repository
... QClass Skip
@Repository
public class testDslRepository {
@Autowired
private JPAQueryFactory jpaQueryFactory;
public List<Test> findDslAll() {
return JPAQueryFactory
.selectFrom(test)
.fetch();
}
}
// Test Entity
public class Test {
...Column
@QueryProjection
...Construtor
}
querydsl은 이러한 형태로 작성될 것이다.
각각의 장단점들
JPA의 경우에는 흔히 보이는 쿼리의 형태가 아니어도 데이터베이스에서 값을 호출해 추출해낼 수가 있다. 그런 점에서 장점으로 보이나 복잡한 쿼리문의 경우에는 JPA로 한계가 있기 마련이다. 실제 업무에서는 다중 조인을 사용하여 값을 추출하는 경우가 많기 때문에 JPA만을 고집할 수 없다.
querydsl의 경우에는 JPA의 이러한 한계를 어느 정도 보완했음을 알 수 있다. 하지만 마찬가지로 jdbc나 mybatis를 온전히 커버할 수는 없다. 또한 버전에 따라서 아직 querydsl은 문제점도 상당히 많은 편이다.
네이티브 쿼리 자체를 보완하기 위해 많은 라이브러리들이 나오고 있지만 결국 프로그래밍 언어로써 sql을 온전히 대체하기가 아직도 많이 어려운 상황이기에 결국 쿼리에 대해서는 필수적으로 공부해야할 수밖에 없다고 생각한다.
'java > 메모장' 카테고리의 다른 글
[코딩테스트] 바탕화면 정리 (0) | 2024.02.18 |
---|---|
[코딩테스트] 공원 산책 (0) | 2024.02.18 |
[코딩테스트] 추억 점수 (0) | 2024.02.18 |
[코딩테스트] 달리기 경주 (0) | 2024.02.18 |
형 변환 (0) | 2024.02.12 |