MyBatis resultMap 사용법 정리
resultMap은 MyBatis에서 SQL 쿼리의 결과 집합(ResultSet)과 자바 객체(Result Object) 간의 매핑을 정의하는 데 사용된다.
resultMap이 필요한 경우:
- 컬럼명과 필드명이 다른 경우:
데이터베이스 컬럼명과 자바 객체의 필드명이 다를 때, resultMap을 사용하여 명시적으로 매핑을 정의해야 한다. - TypeHandler를 사용하는 경우:
사용자 정의 TypeHandler를 사용하여 데이터 타입 변환을 처리할 때, resultMap에서 typeHandler를 지정해야 한다. - 중첩된 객체(Nested Object) 또는 컬렉션(Collection)을 매핑하는 경우:
다른 객체를 포함하는 객체나, 리스트, 맵과 같은 컬렉션을 매핑할 때 resultMap을 사용하여 중첩 매핑을 정의해야 한다.
이때 <id> 태그를 통해 자바 객체와 데이터베이스 테이블의 기본키를 명시해 주는것이 중요하다.
또한, MyBatis는 객체의 equals()와 hashCode() 메서드를 사용하여 동일성을 판단하기 때문에, @EqualsAndHashCode(of = "기본키가 되는 프로퍼티명")와 같이 특정 필드를 기준으로 equals()와 hashCode()를 정의해두면, MyBatis가 중첩 객체나 컬렉션의 동일성을 더 정확하게 판별할 수 있다. - 상속 관계 매핑:
상속 관계에 있는 객체들을 매핑할 때 resultMap의 상속 및 discriminator를 사용할 수 있다. - 결과에 따라 다른 객체로 동적 매핑:
discriminator를 사용하면 결과 값에 따라 동적으로 다른 객체로 매핑할 수 있다. - N+1 문제 해결:
연관 관계 매핑 시 N+1 문제가 발생할 수 있는데, resultMap의 fetchType 속성으로 이를 최적화할 수 있다.
resultMap의 구성 요소:
- <resultMap>: 매핑 정보를 정의하는 최상위 엘리먼트다.
- id: resultMap의 고유 식별자.
- type: 매핑할 자바 객체의 FQCN(Fully Qualified Class Name) 또는 별칭(Type Alias).
- autoMapping (Boolean, 기본값: true): 자동 매핑 여부를 지정. false로 설정하면 명시된 매핑만 적용.
- <id>: 객체의 식별자, 주로 기본 키(Primary Key)를 매핑.
- property: 자바 객체의 필드명.
- column: 데이터베이스 컬럼명.
- javaType (선택): 자바 데이터 타입을 명시적으로 지정.
- jdbcType (선택): JDBC 데이터 타입을 명시적으로 지정.
- typeHandler (선택): 사용할 TypeHandler의 FQCN 또는 별칭을 지정.
- <result>: 일반 컬럼을 매핑.
- property: 자바 객체의 필드명.
- column: 데이터베이스 컬럼명.
- javaType (선택): 자바 데이터 타입을 명시적으로 지정.
- jdbcType (선택): JDBC 데이터 타입을 명시적으로 지정.
- typeHandler (선택): 사용할 TypeHandler의 FQCN 또는 별칭을 지정.
- <constructor>: 생성자를 통해 객체를 생성할 때 사용.
- <idArg>: 기본 키를 생성자 인자로 전달.
- <arg>: 일반 컬럼을 생성자 인자로 전달.
- <association>: 다른 객체와의 1:1 연관 관계를 매핑. 내부에 <id> 태그를 사용하여 연관 객체의 기본 키를 매핑하는 것이 중요.
- property: 자바 객체 내의 연관 객체를 나타내는 필드명.
- javaType: 연관 객체의 FQCN 또는 별칭.
- columnPrefix: 중첩된 객체 매핑 시 컬럼명에 접두사를 추가하여 중복을 피할 수 있다.
- fetchType (선택): eager(즉시 로딩), lazy(지연 로딩)를 지정하여 N+1 문제 최적화 가능.
- <collection>: 다른 객체와의 1:N 연관 관계 (List, Set, Map 등)를 매핑. 내부에 <id> 태그를 사용하여 컬렉션 요소 객체의 기본 키를 매핑하는 것이 중요.
- property: 자바 객체 내의 컬렉션 필드명.
- ofType: 컬렉션 요소의 FQCN 또는 별칭.
- columnPrefix: 중첩된 객체 매핑 시 컬럼명에 접두사를 추가하여 중복을 피할 수 있다.
- fetchType (선택): eager(즉시 로딩), lazy(지연 로딩)를 지정하여 N+1 문제 최적화 가능.
- <discriminator>: 결과 값에 따라 동적으로 다른 resultMap을 선택하여 매핑.
- column: case를 결정할 컬럼 이름
- javaType: 컬럼의 Java 타입
- <case>: discriminator의 하위 엘리먼트로, 특정 값에 따라 어떤 resultMap을 사용할지 정의.
- value: case를 선택할 값
- resultMap: 사용할 resultMap의 id 또는 resultType: 사용할 결과 자바 유형
resultMap 사용 예시:
1. 컬럼명과 필드명이 다른 경우:
XML
<resultMap id="userResultMap" type="User" autoMapping="false">
<id property="id" column="user_id" />
<result property="name" column="user_name" />
<result property="emailAddress" column="email" />
</resultMap>
<select id="getUserById" resultMap="userResultMap">
SELECT user_id, user_name, email
FROM users
WHERE user_id = #{id}
</select>
2. 중첩된 객체 매핑 (1:1) - <id> 태그 사용 강조:
XML
<resultMap id="orderResultMap" type="Order" autoMapping="false">
<id property="orderId" column="order_id" />
<result property="orderDate" column="order_date" />
<association property="customer" javaType="Customer">
<id property="customerId" column="customer_id" />
<result property="customerName" column="customer_name" />
</association>
</resultMap>
<select id="getOrderById" resultMap="orderResultMap">
SELECT o.order_id, o.order_date, c.customer_id, c.customer_name
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
WHERE o.order_id = #{orderId}
</select>
3. 컬렉션 매핑 (1:N) - <id> 태그 사용 강조:
XML
<resultMap id="postResultMap" type="Post" autoMapping="false">
<id property="postId" column="post_id" />
<result property="title" column="title" />
<collection property="comments" ofType="Comment" resultMap="commentResultMap" />
</resultMap>
<resultMap id="commentResultMap" type="Comment">
<id property="commentId" column="comment_id" />
<result property="content" column="comment_content" />
</resultMap>
<select id="getPostById" resultMap="postResultMap">
SELECT p.post_id, p.title, c.comment_id, c.comment_content
FROM posts p
LEFT JOIN comments c ON p.post_id = c.post_id
WHERE p.post_id = #{postId}
</select>
4. discriminator를 사용한 동적 매핑:
XML
<resultMap id="vehicleResultMap" type="Vehicle" autoMapping="false">
<id property="id" column="id" />
<result property="brand" column="brand" />
<discriminator javaType="string" column="vehicle_type">
<case value="car" resultMap="carResultMap"/>
<case value="truck" resultMap="truckResultMap"/>
</discriminator>
</resultMap>
<resultMap id="carResultMap" type="Car" extends="vehicleResultMap">
<result property="numDoors" column="num_doors" />
</resultMap>
<resultMap id="truckResultMap" type="Truck" extends="vehicleResultMap">
<result property="cargoCapacity" column="cargo_capacity" />
</resultMap>
<select id="getVehicleById" resultMap="vehicleResultMap">
SELECT id, brand, vehicle_type, num_doors, cargo_capacity
FROM vehicles
WHERE id = #{id}
</select>
'개발 > Mybatis' 카테고리의 다른 글
Mybatis에서 TypeHandler 사용하기 (0) | 2025.01.24 |
---|---|
Mybatis란? (0) | 2025.01.24 |
Mybatis에서 Oracle과 Java의 일반적인 데이터 타입 매핑 (0) | 2025.01.24 |