[java] JPA에서의 연관 관계 로딩 방식과 MyBatis에서의 N+1 문제 해결 방법 비교

개요

JPA(Java Persistence API)와 MyBatis는 Java 언어를 사용하여 데이터베이스와의 상호작용을 도와주는 ORM(Object-Relational Mapping) 프레임워크이다. 이들은 각자 다른 방식으로 연관 관계를 로딩하고 N+1 문제를 해결한다. 이번 글에서는 JPA와 MyBatis의 연관 관계 로딩 방식과 N+1 문제 해결 방법을 비교해보고자 한다.

JPA의 연관 관계 로딩 방식

JPA는 지연 로딩(lazy loading)즉시 로딩(eager loading) 두 가지 방식을 제공한다. 지연 로딩은 연관된 엔티티를 실제로 사용할 때까지 데이터베이스에서 불러오는 방식이며 즉시 로딩은 부모 엔티티를 가져올 때 함께 연관된 자식 엔티티까지 모두 가져오는 방식이다. 지연 로딩은 FetchType.LAZY로 설정하고, 즉시 로딩은 FetchType.EAGER로 설정한다.

@Entity
public class Parent {
    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
    private List<Child> children;
}

MyBatis에서의 N+1 문제 해결 방법

MyBatis에서 N+1 문제란 쿼리 한 번으로 가져와야 할 데이터를 N 번의 쿼리로 가져오는 문제를 말한다. 이를 해결하기 위해 MyBatis는 fetchSizeresultMap 등의 설정을 통해 한 번의 쿼리로 연관된 엔티티들을 모두 가져올 수 있도록 지원한다.

<select id="selectParent" parameterType="int" resultMap="parentResult">
    SELECT * FROM parent WHERE id = #{id}
</select>

<select id="selectChildrenByParentId" parameterType="int" resultMap="childResult">
    SELECT * FROM child WHERE parent_id = #{parentId}
</select>

<resultMap id="parentResult" type="Parent" >
    <association property="children" column="id" select="selectChildrenByParentId"/>
</resultMap>

결론

JPA는 지연 로딩과 즉시 로딩을 통해 연관 관계를 로딩하는 방식을 제공하고, MyBatis는 fetchSize나 resultMap 등의 설정을 통해 N+1 문제를 해결하는 방식을 제공한다. 각각의 프레임워크는 서로 다른 방식을 제공하므로 상황에 맞게 적절한 프레임워크를 선택하여 사용해야 한다.

이러한 차이점을 고려하여 프로젝트의 요구사항과 성능 등을 고려하여 ORM 프레임워크를 선택하는 것이 중요하다.

참고 자료

위의 내용을 통해 JPA와 MyBatis에서의 연관 관계 로딩과 N+1 문제 해결 방법을 비교해 보았다.