[mybatis]수동 매핑 & resultMap 엘리먼트(컬럼명과 DTO파일 필드명 다를 때)
resultType 속성을 사용하면 resultType 속성값으로 설정된 클래스로 객체를 생성하여 검색행의 컬럼값을 같은 이름의 객체 필드값으로 자동 저장하여 제공 - 자동 매핑
문제점 : 검색행의 컬럼명과 resultType 속성값으로 설정된 클래스의 필드명이 모두 다른 경우 resultType 속성값으로 설정된 클래스로 객체를 생성하여 제공하지 않고 NULL 제공
=> 웹프로그램 실행시 NullPointerException 발생
먼저 테이블과 필드명을 확인해보면⬇️
⚫MYUSER 테이블 : 회원정보를 저정하기 위한 테이블
=> SQL 명령은 대소문자를 구분하지 않기 때문에 식별자를 선언할 때 스네이크 표기법 사용
=> 스네이크 표기법(SnakeCase) : 단어와 단어를 구분하기 위해 _ 기호를 사용하여 식별자를 선언하는 방법
이름 널? 유형
--------- -------- ------------
USER_ID NOT NULL VARCHAR2(50) - 아이디
USER_NAME VARCHAR2(50) - 이름
⚫MyUser DTO 파일
DTO 파일에서 필드명은 카멜 표기법 사용
=> 카멜 표기법(CamelCase) : 첫단어를 제외한 나머지 단어의 첫번째 문자를 대문자로 표현하여 식별자 선언하는 방법
package xyz.itwill.dto;
public class MyUser {
private String userId;
private String userName;
public MyUser() {
// TODO Auto-generated constructor stub
}
public MyUser(String userId, String userName) {
super();
this.userId = userId;
this.userName = userName;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
해결법-1 : 검색행의 컬럼명을 resultType 속성값으로 설정된 클래스의 필드명과 같도록 검색
=> SELECT 명령에서 Column Alias 기능을 사용하여 검색대상의 별칭을 필드명과 같도록 작성
<select id="selectUserList" resultType="MyUser">
select user_id userId, user_name userName from myuser order by user_id
</select>
아니면 sql 엘리먼트와 include 엘리먼트를 사용하여 컬럼명과 필드명을 같게 만들어도 됨. 방법은 아래글 참조!
2024.03.06 - [Java/mybatis] - [mybatis]매퍼XML 파일 - sql 엘리먼트과 include 엘리먼트
[mybatis]매퍼XML 파일 - sql 엘리먼트과 include 엘리먼트
🔸sql : SQL 명령을 구성하는 일부분의 문장을 등록하기 위한 엘리먼트 ▪️ id 속성 : 엘리먼트를 구분하기 위한 식별자를 속성값으로 설정 🔸include : sql 엘리먼트에 등록된 문장을 제공받아 SQL
sukis.tistory.com
해결법-2 : mybatis 환경설정파일(mybatis-config.xml)의 setting 엘리먼트를 사용하여 SQL 명령에서 사용하는 스네이크 표기법의 식별자를 카멜 표기법의 식별자로 자동 변환하는 기능 사용
⬇️mybatis-config.xml 파일
<settings>
<!-- mapUnderscoreToCamelCase 옵션을 [true]로 설정하면 SELECT 명령 실행시 스네이크 표기법으로
작성된 컬럼명을 자동으로 카멜 표기법의 컬럼명으로 변환하여 검색하는 기능 제공 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
⬇️위에서 설정해두면 XML 매퍼 파일에서는 그냥 아래와 같이 써도 알아서 카멜표기법으로 바꿔서 검색함!
<select id="selectUserList" resultType="MyUser">
select user_id, user_name from myuser order by user_id
</select>
해결법-3 : resultMap 엘리먼트를 사용하여 검색행의 컬럼값이 객체의 필드에 저장되도록 설정 - 수동 매핑
🔸resultMap : 검색행을 Java 객체로 생성하여 제공하기 위한 엘리먼트 - 매핑정보 제공
=> 검색행의 컬럼값이 객체 필드에 저장되도록 처리하기 위해 하위 엘리먼트 사용
=> 하위 엘리먼트 : constructor, id, result, association, collection, discriminator
▪️ type 속성 : resultMap 엘리먼트로 제공될 객체의 Java 자료형을 속성값으로 설정
=> Java 자료형 대신 typeAlias 엘리먼트로 설정한 별칭(AliasName) 사용 가능
▪️ id 속성 : resultMap 엘리먼트를 구분하기 위한 식별자를 속성값으로 설정
🔸id : 검색행의 컬럼값을 Java 객체 필드에 저장하기 위한 엘리먼트 - Setter 메소드 자동 호출
=> PK 제약조건이 설정된 컬럼값을 제공받아 필드에 저장하기 위해 사용
🔸result : 검색행의 컬럼값을 Java 객체 필드에 저장하기 위한 엘리먼트 - Setter 메소드 자동 호출
▪️ column 속성 : 검색행의 컬럼명을 속성값으로 설정
▪️ property 속성 : Java 객체의 필드명을 속성값으로 설정
<resultMap type="MyUser" id="myUserResultMap">
<id column="user_id" property="userId"/>
<result column="user_name" property="userName"/>
</resultMap>
여기서 끝이 아님!!!
select 엘리먼트에 resultMap 속성을 사용하여 검색행의 컬럼값을 객체 필드에 저장되도록 설정 - 수동 매핑
▪️ resultMap 속성 : resultMap 엘리먼트의 식별자(id 속성값)를 속성값으로 설정
<select id="selectUserList" resultMap="myUserResultMap">
select user_id, user_name from myuser order by user_id
</select>