관리 메뉴

The Nirsa Way

[Spring Data JPA] ORM이란? (Object-Relational Mapping, JPA vs Hibernate vs Spring Data JPA) 본문

Development/Spring Data JPA

[Spring Data JPA] ORM이란? (Object-Relational Mapping, JPA vs Hibernate vs Spring Data JPA)

KoreaNirsa 2025. 7. 16. 20:19
반응형

 

ORM(Object-Relational Mapping)이란?

JPA를 사용한지 너무 오래되어 다시 처음부터 개념을 학습하기 위한 포스팅 입니다.

ORM이란 객체(Object)와 관계형 데이터베이스(Relational Database) 간의 불일치 문제를 자동으로 매핑을 추상화하여 개발자가 SQL 쿼리 대신 객체를 조작하는 것 만으로 데이터베이스 작업을 수행할 수 있도록 도와줍니다.

자바에서 대표적인 ORM은 JPA가 있는데, 간단한 쿼리의 경우 SQL 직접 작성 없이 사용이 가능하므로 편리하지만 복잡한 쿼리를 사용해야 할 경우 Native Query, QueryDSL 등을 사용해야 하므로 오히려 더 복잡해질 가능성도 있습니다.

개인적으로 간단한 CRUD 작업이 많은 경우에 JPA가 적합하며, 복잡한 쿼리를 작성해야 하는 경우가 많을땐 적합하지 않다고 생각합니다. 이로인해 "무조건 JPA를 써야한다"가 아니라, 상황에 맞춰 JPA를 사용하던 MyBatis를 사용하던 아니면 둘 다 같이 사용하던 선택되어야 합니다.


JDBC vs JPA

간단한 사용 방법의 차이만 보자면 JDBC와 JPA의 차이를 비교하면 아래와 같이 됩니다.

JDBC로 직접 개발해야 하는 경우 개발자가 쿼리를 직접 작성하며 PreparedStatement를 사용해야 하나, JPA의 경우 이미 추상화된 메서드를 호출함으로써 SQL을 직접 작성하지 않아도 됩니다.

방식 예시
JDBC String sql = "SELECT * FROM member WHERE id = ?" + PreparedStatement 사용
JPA Member member = em.find(member.class, id);

JPA vs Hibernate vs Spring Data JPA 간단 정리

첫번째로 JPA는 자바 진영에서의 ORM 표준 인터페이스 입니다. JPA는 규약일뿐이므로 실제 동작은 JPA의 구현체가 담당하게 됩니다.

두번째로 Hibernate는 JPA에서 대표적인 구현체로써 JPA의 스펙을 기반으로 실제 동작하는 코드가 구현되어 있는 프레임워크입니다.

세번째로 Spring Data JPA는 JPA와 Hibernate를 기반으로 더 추상화된 Repository 인터페이스를 제공합니다. 개발자가 직접 쿼리를 작성하지 않아도 간단한 CRUD를 자동으로 실행시켜줍니다.

아래와 같이 JpaRepository를 상속받은 후 메서드를 호출만 해도 쿼리가 실해되기 때문에 개발자가 코드에 직접 접근하지 않아도 도 됩니다. Repository에 정해진 규칙을 지켜 메서드를 호출하면 적합한 쿼리를 실행할 구현체를 만든 후 Bean으로 등록하여 실행합니다.

public interface MemberRepository extends JpaRepository<Member, Long> {
    Optional<Member> findByName(String name);
}

JpaRepository<Member, Long> 간단히 짚고 넘어가기

JpaRepository는 Spring Data JPA가 제공하는 인터페이스로써 간단한 CRUD, 페이징 등의 기능을 포함하고 있으며 내부적으로 ListCrudRepository, ListPagingAndSortingRepository, QueryByExmapleExcutor를 상속받고 있습니다.

  1. ListCrudRepository : findAll, findById, save, count와 같이 간단한 CRUD 기능들을 제공합니다.
  2. ListPagingAndSoringRepository :  페이징, 정렬 기능을 제공합니다.
  3. QueryByExmapleExcutor : 엔티티 객체에 검색 조건을 직접 셋팅한 후 그 객체를 기준으로 쿼리를 생성하는 기능을 제공합니다.

QueryByExmapleExcutor의 경우 설명을 조금 더 붙이자면 특정 엔티티에 이름을 "홍길동"으로 셋팅한 후 아래와 같이 코드를 작성하게 되면 이름이 "홍길동"인 데이터를 SELECT하는 쿼리가 완성 됩니다. Example.of에서 내부적으로 matcher를 사용하여 어떤 방식으로 비교할지 정하게 됩니다. 

Member member = new Member();
member.setName("홍길동");

Example<Member> example = Example.of(member);

Optional<Member> result = memberRepository.findOne(example);

 

마지막으로 <Member, Long>의 뜻은 해당 repository가 관리할 엔티티의 클래스 타입을 지정해주는 것이며, 뒤의 Long은 해당 엔티티의 기본 키 타입(@id 필드) 이라고 생각하시면 됩니다.

@Entity
public class Member {
    @Id
    @GeneratedValue
    private Long id;  // 이 필드의 타입

    private String name;
}

 

반응형