JPQL 이란?

예전에는 JPQL은 Java Persistence Query Language로 불렸지만 현재의 JPQL은(Jakarta Persistence Query Language) 라고 합니다.(나무위키 링크 )
2019년부터 JPA(Java Persistence API)또한 Jakarta Persistence로 변경됐습니다.

이름은 달라졌지만 역할은 달라지지 않았습니다. JPQL을 이용하여 관계형 데이터베이스의 엔티티를 정의하고 이를 활용한 쿼리 언어를 자바를 이용하여 구현합니다.
더 나아가 Querydsl을 이용하면 좀 더 직관적이고 오류 없이 자바를 이용하여 작성할 수 있습니다.

간단한 예시로 회원 조회를 하는 경우 JPQL과 Querydsl의 차이는 아래와 같습니다.

JPQL

1
2
3
4
5
6
public List<Member> findAll() {
    EntityManager entityManager;

    return entityManager.createQuery("select m from Member m ", Member.class)
        .getResultList();
}

Querydsl

1
2
3
4
5
6
7
public List<Member> findAll() {
    JPAQueryFactory queryFactory;

    return queryFactory
        .selectFrom(QMember.member)
        .fetch();
}

결국은 같은 결과를 호출하지만 Querydsl을 이용하면 쿼리작성 및 빌드 오류를 컴파일 시점에 방지할 수 있습니다.
가독성도 Querydsl쪽이 더 좋습니다.

Spring Data JPA란?

CRUD 처리를 위한 공통 인터페이스를 JPA에서 미리 만들어 놓은 것입니다.
일반적으로 Entity 어노테이션을 선언한 클래스를 매개변수로 JpaRepository 인터페이스를 상속받아 사용합니다.
이렇게되면 실제로 SQL관련 코드하나 사용하지 않고 간단한 CRUD는 처리가 가능합니다.

사용자 정의 인터페이스 상속받기

인터페이스는 다중상속이 가능하기 때문에 먼저 CustomRepository를 인터페이스로 생성합니다.

1
2
3
public interface CustomMemberRepository {
    void customSave(Member member);
}

그리고 구현체에 해당 선언한 함수들을 구현합니다.

1
2
3
4
5
6
7
8
9
@RequiredArgsConstructor
public class CustomMemberRepositoryImpl implements CustomMemberRepository {
    private final EntityManager em;

    @Override
    public void customSave(Member member) {
        em.persist(member);
    }
}

마지막으로 직접사용할 인터페이스에 위의 인터페이스를 추가합니다.

1
2
3
public interface MemberRepository extends JpaRepository<Member, Long>, CustomMemberRepository {

}

위와 같이 스프링 데이터 JPA에서 제공하는 기능과 필요한 기능이 복잡해짐에 따른 커스텀 쿼리를 인터페이스화 하여 함께 사용할 수 있습니다.

같은 결과라도 memberRepository.customSave(member)memberRepository.save(member)의 방식이 다릅니다.
아래는 package org.springframework.data.jpa.repository.support;에서 구현된 save(S entity) 구현체 입니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
@Transactional
@Override
public <S extends T> S save(S entity) {

    Assert.notNull(entity, "Entity must not be null.");

    if (entityInformation.isNew(entity)) {
        em.persist(entity);
        return entity;
    } else {
        return em.merge(entity);
    }
}

스프링 데이터 JPA에서 제공하는 함수 가이드 링크 입니다.