Polymor!

JPA , hibernate, 그리고 SpringDataApi 본문

Web

JPA , hibernate, 그리고 SpringDataApi

Megan Kim 2021. 2. 24. 14:27

JPA ? 

Java Persistence API 라는 뜻으로 Java 진영의 ORM(Object-Relational Mapping) 기술의 표준이다. 

객체와 데이터베이스 간의 적절하고 이상적인 매핑은 개발자들의 가장 큰 고민이 될테며 JPA는 이를 해결해주기 위한 솔루션이다.개발자가 JDBC 를 직접적으로 쓰지않고 JPA가 쿼리를 날려주고 영속성을 관리해주는 등 큰 메리트가 있어 Java 개발에 있어 매우 편리함을 제공한다.  가장 큰 이점은 '패러다임의 불일치'(RDB엔 상속,다형성,객체,참조 등과같은 객체지향 성격이없다) 문제를 해결해주는 것이다. 데이터베이스에는 상속관계가 없고 양방향 연관관계가 존재하지않는데, 객체에선 이를 어떻게 바라보고 데이터를 담아내야하는지 등에대한 고민을 하게된다. 

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);

}

 

**참고로 MyBatis는 SPL Mapper이고 JPA는 Object Mapper 이기에 서로 다른 개념이다.

 

 

Hibernate vs JPA? 

JPA는 Interface이고 Hibernate는 그 JPA 를 구현하는 구현체(Class)이다. 물론 구현체로 hibernate외에  DataNucleus, EclipseLink등 도 있으니 꼭 hibernate를 사용하는 것은 아니다. 'spring-starter-data-jpa'에는 hibernate 기능을 사용하는건 참고하자. 아래와 같은 관계라고 생각하면 편하다.

 

 

// JPA interface

public interface JPAInterface{

    void method1(){}
    void method2(){}
    
    
    }
// Hibernate Implementation

public class hiberateclass implements JPAInterface{

	void method1(){ System.out.println("method1"); }
    void method1(){ System.out.println("method2"); }
    
   }

 

 

 

Spring Data JPA? 

쉽게말하면 JPA를 한단계 더 추상화한 것이라고 생각하자. 이를테면 우리는 Spring 개발에 있어 entity manager을 직접 가져다 쓰기 보단 repository를 사용하는데, 이것이 바로 JPA를 추상화한 인터페이스이다. Repository 인터페이스의 기본 구현체인 SimpleJpaRepository의 코드를 보면 아래와 같이 내부적으로 EntityManager을 사용하고 있는 것을 볼 수 있다.

 

public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID> {

    private final EntityManager em;

    public Optional<T> findById(ID id) {

        Assert.notNull(id, ID_MUST_NOT_BE_NULL);

        Class<T> domainType = getDomainClass();

        if (metadata == null) {
            return Optional.ofNullable(em.find(domainType, id));
        }

        LockModeType type = metadata.getLockModeType();

        Map<String, Object> hints = getQueryHints().withFetchGraphs(em).asMap();

        return Optional.ofNullable(type == null ? em.find(domainType, id, hints) : em.find(domainType, id, type, hints));
    }

}

 

 

 

추가적으로, JPARepository는 무엇이냐?

// JPArepository를 이용하여 memberrepository 만들기

public interface MemberRepository extends JpaRepository<Member, Long> {

Member findByName(String name);

Page<Member> findByName(String name, Pageable pageable);
}

 

필자는 위와같이 JpaRepository를 뭔지도 모르면서 무작정 갖다썼던 때가 있다.  그러다 생각을 해보니, 

MemberRepository 도 인터페이스이고, JpaRepository도 인터페이스일텐데, 대체 class가 없는데 이걸 어떻게 쓰고 있었던거지?

그리고 @Repository는 왜 안붙여도 동작하는거지? 하는 원초적인 질문을 갖게 되었다.

 

JpaRepository는 기본적으로 CRUD 관련 메소드들만 갖고있는 인터페이스인데 Spring에서 관리를 해주어 실행될때 클래스도 생성되고 빈으로 자동 등록되어 사용가능하게 되는 것이다. 더불어 쿼리까지 생성하여 날려주니 더할 나위없이 편리한 기능들을 제공한다. 

JpaRepository 내에 entitymanager 가 있을 것이고 그래서 @Repository 어노테이션을 안붙여도 된다고 한다. 

 

 

Comments