Backend/mybatis

[mybatis]수동 매핑 & resultMap 엘리먼트(컬럼명과 DTO파일 필드명 다를 때)

sukii 2024. 3. 6. 19:47
반응형

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>
반응형