JPA, JPQL, Native Query, QueryDSL

달래·2024년 2월 16일
0

JPA

목록 보기
9/9

JPA를 사용해보았다면 익숙한 이름들인데요, JPA로 쿼리를 작성할 때 사용되는 대표적인 방법들입니다.

이들의 차이점과 특징을 정확하게 알아보고싶어서 정리해보았습니다.

1. JPA (Java Persistence API)


관계형 데이터베이스를 사용하는 방식을 정의하는 인터페이스입니다.
java ORM(Object Relational Mapping) 기술의 표준 명세라고 할 수 있습니다.

JPA를 다룰 때 필요한 EntityManager가 인터페이스로 정의되어 있습니다.

public interface EntityManager {
    public void persist(Object entity);

    public <T> T merge(T entity);

    public void remove(Object entity);

    public <T> T find(Class<T> entityClass, Object primaryKey);
	...
}

ORM(Object Relational Mapping)
DB 데이터와 Object 필드를 매핑합니다. 즉, 객체를 통해 간접적으로 DB 데이터를 다룹니다.
예) JPA, Hibernate

SQL Mapper
SQL문으로 DB를 직접 조작합니다.
예) MyBatis, jdbcTemplate

Hibernate

JPA 인터페이스의 구현체로서, 라이브러리입니다.
EntityManagerFactory, EntityManager, EntityTransaction을 SessionFactory, Session, Transaction으로 상속받아 구현하였습니다.

즉, JPA를 사용할 때 꼭 구현체인 Hibernate를 사용하지 않아도 된다는 점! 하지만 굳이 사용하지 않을 필요도 없어보입니다.

Spring data JPA

Spring에서 제공하는 모듈로, Spring에서 JPA를 사용할 때 주로 사용됩니다.
Spring에서 JPA를 더 추상화한 인터페이스 JpaRepository는, 사용자가 정해진 규칙대로 메소드를 입력하면 Spring이 알아서 해당 메소드 이름에 적합한 쿼리를 생성하는 구현체를 만들어 Bean으로 등록합니다. (findByEmail()...)

@Repository
public interface MemberRepository extends JpaRepository<Member, Long> {
	List<Member> findAllByEmailIn(List<String> emails);
}

특징

  • JPQL이나 Native Query로 쿼리를 직접 작성하는 것보다 개발자가 사용하기 쉽도록 자동(Hibernate)으로 쿼리를 만들어줍니다.
  • DB에 직접적으로 쿼리를 실행하는 Native Query보다 속도가 느릴 수 있습니다.
  • 조건이 길고 복잡한 경우 가독성이 좋지 않습니다. (findEmailByMemberIdAndStatusGraterThan...)

2. JPQL (Java Persistence Query Language)


@Query 로 구현 가능한 JPA 쿼리입니다.

private final EntityManager em;

Query query = em.createQuery("SELECT m FROM Member m where m.name = :name");
TypedQuery<Member> query = em.createQuery("SELECT m From Member m", Member.class); // 반환 유형 지정 가능

List<Member> members = (List<Member>) query.getResultList();

특징

  • 데이터베이스에 직접 쿼리를 실행하지 않고, Entity 테이블에 매핑하여 사용합니다.
  • DB에 종속적이지 않기 때문에 유지보수성이 뛰어나고, 코드 작성 시점에 오류를 발견할 수 있습니다.
  • 마찬가지로 Native Query보다 느릴 수 있고, 여러 조인/복잡한 쿼리를 작성해야 할 때 가독성이 좋지 않습니다. 또한 모든 SQL 기능을 지원하지 않습니다.

3. Native Query


@Query로 구현 가능한 Native Query입니다.

@Modifying
@Query(value = "update Member m" + 
			   "left join diary d on m.id = d.writer_id" + ...,
               nativeQuery = true)
void updateMember(@Param("memberId" Long memberId);

특징

  • 데이터베이스에 직접적으로 쿼리를 실행해 속도가 빠릅니다.
  • SQL 언어를 전체적으로 사용 가능하고, Join이나 복잡한 쿼리를 작성 시 직관적입니다.
  • SQL 쿼리를 직접 작성하기 때문에 DB 종속성이 높고, 반환 타입이 List<Object>로 제한적입니다.
  • 작성된 쿼리만을 실행하기 때문에, Listener와 @Where같이 Entity에 설정된 JPA 기능을 무시합니다.

4. QueryDSL


HQL (Hibernate Query Language)를 타입에 안전하게 생성/관리해주는 프레임워크입니다.
주로 복잡한 쿼리나 동적인 쿼리를 위해 사용됩니다.

List<Member> result = queryFactory
	.select(member)
    .from(member)
    .where(memberIdEq(memberId))
    .fetch();

특징

  • 자바코드로 SQL을 작성하여 컴파일 시 쿼리 오류를 발견할 수 있습니다.
  • 복잡하거나 동적인 쿼리를 작성할 때 유지보수나 가독성이 좋습니다.
  • QClass를 따로 생성해야 합니다.
profile
아좌잣~!

0개의 댓글