본문 바로가기
일상/일기장

TIL.22.02.24 - Mybatis : 인터페이스 맵퍼, XML 맵퍼, 맵퍼 바인딩

by jmaster 2022. 2. 25.

Interface Mapper

  • Interface 파일 결로는 Java 자료형 형식으로 표현
<mapper class="xyz.itwill.mapper.MyMemberInterfaceMapper"/>

Interface파일 생성

  • mybatis 프레임워크는 인터페이스를 이용하여 맵퍼 설정 가능
  • 추상메소드에 맵퍼 어노테이션(Mapper)을 사용하여 SQL 명령 등록
  • 추상메소드의 매개변수에는 SQL 작성에 필요한 값을 저장받기 위해 선언하면 반환형은 SQL 명령의 실행결과를 제공받기 위한 Java 자료형을 선언
  • value 속성 : 추상메소드에 등록한 SQL 명령을 속성값으로 설정
  • 어노테이션에 value 속성외에 다른 속성이 없는 경우 속성값만 설정 가능
  • @Insert : INSERT 명령을 등록하기위한 어노테이션
@Insert(value = "insert into mymember values(#{id},#{name},#{phone},#{email})") //어노테이션
int insertMember(MyMember member); //추상 메소드 

@Update : UPDATE 명령을 등록하기 위한 어노테이션

@Update("update mymember set name=#{name},phone=#{phone},email=#{email} where id=#{id}")
	int updateMember(MyMember member);

@Delete : DELETE 명령을 등록하기 위한 어노테이션

@Delete("delete from mymember where id=#{id}")
	int deleteMember(String id);

@Select : SELECT 명령을 등록하기 위한 어노테이션

@Select("select * from mymember order by id")
List<MyMember> selectMemberList();

@Select : SELECT 명령을 등록하기 위한 어노테이션

@Select("select * from mymember order by id")
	List<MyMember> selectMemberList();

Interface Mapper를 받아서 DAO 클래스를 만드는 법

  • sqlSession.getMapper(Class<T> Clazz) : 메모리에 저장된 맵퍼 인터페이스(clazz - Mapper) 전달받아 Mapper 인스턴스를 생성하여 반환하는 메소드
  • 매개 변수에 XXX.class 형식으로 Class 객체(Clazz)을 전달하여 저장
  • Mapper: 인터페이스 맵퍼의 추상메소드를 호출하여 등록된 SQL 명령을 제공받기 위한 인스턴스
return sqlSession.getMapper(MyMemberInterfaceMapper.class).insertMember(member);

특징(Interface 맵퍼 vs XML맵퍼 )

Interface 맵퍼 XML 맵퍼

장점 SqlSession 인스턴스로 SQL 명령을 XML 맵퍼보다 쉽게 제공받아 사용하기 편리 매핑 설정 기능과 동적 SQL 기능을 구현하기 편리 (ex) join기능)
단점 매핑 설정 기능과 동적 SQL 기능을 구현하기 불편 SqlSession 인스턴스로 SQL 명령을 XML 맵퍼보다 쉽게 제공받아 사용하기 불편

맵퍼 바인딩(Mapper binding)

  • XML 맵퍼 파일과 Interface 맵퍼 파일을 하나위 동작되도록 설정하여 사용 것(두개의 장점만을 사용)
  • SQL 명령은 XML 맵퍼에 등록하고 DAO 클래스는 Interface 맵펄를 이용하여 작성
  • mapper 엘리머트에는 XML 맵퍼 파일만 등록하여 설정
  • XML 맵퍼 파일과 Interface 맵퍼 파일을 하나의 맵퍼로 동작되도록 설정하는 방법 (Mapper binding)

방법

  1. XML 맵퍼에서 mapper 엘리먼트의 namespace 속성값과 같은 이름으로 Interface맵퍼 파일을 작성
  2. XML 맵퍼에서 SQL 명령이 등록된 엘리먼트와 Interface 맵퍼의 추상메소드가 동일한 형태로 작성
<mapper resource="xyz/itwill/mapper/MyMemberMapper.xml"/>
  1. Interface 맵퍼는 namespace 속성값과 같은 이름으로 작성
<mapper namespace="xyz.itwill.mapper.MyMemberMapper">
</mapper>

4.SQL 명령이 등록된 엘리먼트 식별자와 같은 이름으로 Interface 맵퍼에 추상 메소드 작성

  • DAO 클래스에서 추상메소드를 호출한 경우 같은 이름의 엘리먼트의 SQL 명령을 제공받아 사용
  • parameterType 속성값은 추상메소드의 매개변수로 설정하고 resultType 속성값은 추상메소드의 반환형으로 설정
  • 맵퍼 바인딩한 경우 엘리먼트의 parameterType 속성은 생략 가능
<insert id="insertMember" parameterType="MyMember"> //parameterType 생략기능
	insert into mymember values(#{id},#{name},#{phone},#{email})
</insert>

5.XML 맵퍼와 바인딩된 InterfaceMaper

public interface MyMemberMapper {
	int insertMember(MyMember member);
	int updateMember(MyMember member);
	int deleteMember(String id);
	MyMember selectMember(String id);
	List<MyMember> selectMemberList();
}

6.DAO설정

  • Interface 맵퍼의 추상메소드를 호출하면 XML 맵퍼에 등록된 SQL 명령을 제공받아 사용
return sqlSession.getMapper(MyMemberMapper.class).insertMember(member);

Package 엘리먼트

  • 특정 패키지에 작성된 모든 Interface 맵퍼 파일을 자동으로 맵퍼 파일을 자동으로 맵퍼로 등록되도록 설정
  • name 속성 : Interface 맵퍼 파일이 작성될 패키지를 속성 값으로 설정
  • xml 맵퍼는 자동으로 등록이 안됨
<package name="xyz.itwill.mapper"/>

표기법

1.SQL 명령은 대소문자를 구분하지 않아 식별자를 선언할 때 스네이크 표기법(Snake Case) 사용

  • 스네이크 표기법(Snake Case) 단언와 단어를 구분하기 위해 _ 기호 사용하여 식별자 선언
USER_ID
  1. Java 자료형(Class, Interface, Enum)은 파스칼 표기법 사용
  • 파스칼 표기법(Pascal Case) 모든 단어의 첫문자를 대문자로 표현하여 식별자 선언
public class **MyUser**

3.Java 자료형으 제외한 식별자는 카멜 표기법 사용

  • 카멜 표기법(CamelCase) : 첫번째 단어의 첫무자를 제외한 나머지 단어의 첫무자를 대문자로 표현
private String **userId**;

AbstractSession

SqlSessionFactory 인스턴스를 생성하여 반환하는 기능을 제공하는 클래스 맵퍼를 사용하는 DAO 클래스가상속받기 위한 부모클래스 상속을 목적으로 작성된 클래스이므로 추상클래스로 선언하는 것을 권장

public class AbstractSession {
	private static SqlSessionFactory sqlSessionFactory

	static {
		String resource="mybatis-config.xml";
	
		InputStream inputStream=null;
		try {
			inputStream=Resources.getResourceAsStream(resource);
		} catch (IOException e) {
			throw new IllegalArgumentException(e);
		}
	
		sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
	}
	
	protected SqlSessionFactory getSqlSessionFactory() {
		return sqlSessionFactory;
	}
}

Select 이슈

검색행의 컬럼명과 DTO 클래스의 필드명이 모두 다르면 검색행의 컬럼값이 DTO 클래스의 픽드에 하나도 저장되지 않아 DTO 인스턴스를 생성하여 제공하지 않고 NULL 제공

해결방법1

  • 검색행의 컬럼명을 DTO 클래스의 필드명과 같도록 검색

⇒SELECT 명령에서 검색대상에 별칭 Column Alias 기능을 이용하여 검색대상에 별치을 설정하여 검색

<select id="selectUserList" resultType="MyUser">	
	select user_id userId,user_name userName from myuserorder by user_id
</select>

sql 엘리먼트

SQL 멸령을 구성하는 일부분의 문자을 등록하기 위한 엘리먼트

<sql id="selectColumn">
	user_id userId,user_name userName
</sql>

include : sql 엘리먼트에 등록된 SQL 문장을 SQL 명령에 포함하는 엘리먼트

refid 속성 : sql 엘리먼트를 구분하기 위한 식별자를 속성값으로 설정

<select id=”selectUserList” resultType=”myUser”>
  select <include refid=”selectColumn”/>  from myuser order by user_id
</select>

해결방법2

  • mabatis 환경설정파일에서 setting 엘리먼트를 이용하여 [mapUnderscoreToCamelCase]라는 이름으로 적용된 실행 관련 값을 [true]로 변경
<settings>
		<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
  • => SQL 명령에서 사용된 스네이크 표기법의 식별자가 자동으로 카멜 표기법으로 변경되어 검색
<select id="selectUserList" resultType="MyUser">
		select * from myuser order by user_id
</select>

해결방법3

  • resultMap : 검색행의 컬럼값을 클래스의 필드에 매핑되어 저장되도록 설정하는 상위 엘리먼트

-(주로 조인할 때 사용함)

  • type 속성 : 검색행의 컬럼값을 저장하기 위한 필드가 선언된 DTO 클래스르 속성값으로 설정 -
  • 클래스명 대신 별칭 사용 가능

id: 검색행의 컬럼값을 클래스의 필드에 저장되도록 매핑 설정하는 엘리먼트

→PK 제약조건이 부여된 컬럼값을 매핑 처리할 때 사용

column 속성 : 검색행의 컬럼값이 저장된 컬럼명을 속성값으로 설정

property 속성 : 검색행의 컬럼값이 저장된 필드명을 속성값으로 설정

result 속성:검색행의 컬럼값을 클래스의 필드에 저장되도록 매핑 설정하는 엘리먼트

유형 1

→DTO 클래스의 기본 생성자를 사용하여 인스턴스 생성하고 Setter 메소드르 호출하여 검색행의 컬럼값을 전달받아 인스턴스의 필드값으로 변경

<resultMap type=”MyUser” id=”myUserResultMap”>
	<id column=”user_id” property=”userId”/>  
	<result column=”user_name” property=”userName”/>  
</resultMap>

resultMap 속성 : 매핑정보가 저장된 resultMap 엘리먼트의 식별자를 속성값으로 설정 - 수동 매핑 처리

<select id=”selectUserList” resultMap=”myUserResultMap">
	select * from myuser order by user user_id
</select>

유형2

→매개변수가 선언된 생성자를 이용하여 DTO 인스턴스를 생성하고 생성자의 필드 초기화 명령을 이용하여 검색행의 컬럼값을 필드값으로 저장되도록 매핑처리

  • constructor 생성자를 이요아형 매칭 처리하기 위한 정보를 제공하는 상위 엘리먼트
  • ⇒ idArg 엘리먼트 arg 엘리먼트를 하위 엘리먼트로 사용하여 매핑 정보 제공
  • ⇒생성자 매개변수와 하위 엘리먼트의 갯수와 Java 자료형이 반드시 일치해야만 생성자를 제공
  • idArg: 검색행의 컬럼값을 생성자의 매개변수에 전달하여 저장하는 엘리먼트
  • →PK 제약조건이 부여된 컬럼값을 매핑 처리할 때 사용
  • column속성 : 검색행의 컬럼값이 저장된 컬럼명을 설정
  • javaType : 검색행의 컬럼값이 저장될 매개변수의 Java 자료형을 속성값으로설정
  • arg: 검색행의 컬럼값을 생성자의 매개변수에 전달하여 저장하는 엘리먼트
<resultMap type="MyComment2" id="myComment2ConstructorResultMap">
		<constructor>
			<idArg column="comment_no" javaType="_int"/>
			<arg column="comment_id" javaType="string"/>
			<arg column="comment_content" javaType="string"/>
			<arg column="comment_date" javaType="string"/>
		</constructor>
	</resultMap>
	<select id="selectCommentList2" resultMap="myComment2ConstructorResultMap">
		select * from mycomment order by comment_no desc
	</select

 

selectKey 엘리먼트

selectKey : SELCT 명령의 검색 결과값을 인스턴스의 필드값으로 저장하기 위한 엘리먼트

insert 엘리먼트의 종속된 하위 엘리먼트

자동 즉가값 또는 난수값을 검색하여 인스턴스의 필드에 저장

resultType 속성 : SELECT 멸령의 검색 결과값을 매핑하여 제공하기 위한 Java 자료형의 속성값으로 설정

order 속성 : [BEFOR] 또는 [AFTER] 중 하나를 속성값으로 설정

<insert id="insertComment" parameterType="MyComment1">
		<selectKey resultType="int" keyProperty="commentNo" order="BEFORE">
			select mycomment_seq.nextval from dual
		</selectKey>
		insert into mycomment values(#{commentNo},#{commentId},#{commentContent},sysdate)
	</insert>

'일상 > 일기장' 카테고리의 다른 글

TIL22.03.01 - MyBatis : ResultMap  (0) 2022.02.28
TIL22.02.25 - MyBatis : join  (0) 2022.02.25
TIL20.01.24  (0) 2022.01.24
TIL20.02.21  (0) 2022.01.21
TIL22.01.18  (0) 2022.01.18

댓글