• 티스토리 홈
  • 프로필사진
    chantleman
  • 방명록
  • 공지사항
  • 태그
  • 블로그 관리
  • 글 작성
chantleman
  • 프로필사진
    chantleman
    • 분류 전체보기 (328)
      • 프로젝트 (1)
      • react (2)
      • 코딩테스트 (133)
        • lv0 (101)
        • lv1 (10)
        • lv2 (7)
        • lv3 (15)
      • 오류 (14)
      • 리눅스 (5)
      • 자바 (75)
        • spring (7)
      • js (35)
      • 오라클 (39)
        • PLSQL (3)
      • cs (5)
      • 도커 aws (3)
      • 단축키 (3)
      • 나만봐 (0)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    • 최근 공지
        등록된 공지가 없습니다.
      # Home
      # 공지사항
      #
      # 태그
      # 검색결과
      # 방명록
      • MyBatis ResultMap - Collection, Association
        2024년 11월 20일
        • chantleman
        • 작성자
        • 2024.11.20.:03

         

         

         

         

        데이터베이스 결과를 자바 객체에 매핑하는 방법 중에 resultMap 과 resultType이 있당

        자바에서는 카멜 표기법을 사용하고, sql에서는 스네이크 표기법을 사용하는데

        db의 컬럼명과 자바의 프로퍼티를 매핑하기 위해 resultType이 아닌 resultMap을 사용한당

        혹은 테이블 조인이 있을 때 테이블간의 관계를 매핑하기 위해 resultMap을 사용한당

        조인없을때는 resultType 사용

         

        다중 파일 업로드 같이 다대다 관계를 나타낼때 테이블 조인(left outer join)을 하게 되는데 그때 객체들을 매핑시키기위해 resultMap의 association과 collection을 사용한당

         

         

         

         

         

        db 컬럼명 - 자바 프로퍼티 연결을 위해 sql에서 아래코드 실행 후 resultMap 태그 안에 넣어주깅

        SELECT COLUMN_NAME
        , DATA_TYPE
        , CASE WHEN DATA_TYPE='NUMBER' THEN 'private int ' || FN_GETCAMEL(COLUMN_NAME) || ';'
        WHEN DATA_TYPE IN('VARCHAR2','CHAR') THEN 'private String ' || FN_GETCAMEL(COLUMN_NAME) || ';'
        WHEN DATA_TYPE='DATE' THEN 'private Date ' || FN_GETCAMEL(COLUMN_NAME) || ';'
        ELSE 'private String ' || FN_GETCAMEL(COLUMN_NAME) || ';'
        END AS CAMEL_CASE
        , '<result property="'||FN_GETCAMEL(COLUMN_NAME)||'" column="'||COLUMN_NAME||'"/>' RESULTMAP
        FROM ALL_TAB_COLUMNS
        WHERE TABLE_NAME = '테이블(대문자)'
        AND    OWNER = '계정(대문자)';

         

         

         

         

         

        https://chantleman.tistory.com/entry/resultType%EA%B3%BC-resultMap-%EC%B0%A8%EC%9D%B4

         

        resultType과 resultMap 차이

        resultType : Mybatis에서 SQL 쿼리의 결과를 매핑할 때 사용할 클래스의 타입을 지정하는 속성.이 속성에 지정된 클래스의 인스턴스로 결과를 매핑. SQL 쿼리 결과를 특정 클래스 타입으로 매핑하는

        chantleman.tistory.com

         

         

         


         

         

         


        Association

         

        1:1  관계를 매핑할 때 사용

         

        <resultMap id="blogResult" type="Blog">
          <id property="id" column="blog_id"/>
          <result property="title" column="blog_title"/>
          <association property="author" javaType="Author">
            <id property="id" column="author_id"/>
            <result property="username" column="author_username"/>
          </association>
        </resultMap>

         

        Blog 객체는 하나의 Author 객체를 가지고, 

        association 요소는 Author 객체를 Blog 객체의 author 프로퍼티에 매핑한당

         

         

         

        Collection

         

        1:N 관계를 매핑할 때 사용

         

         

        <resultMap id="blogWithPostsResult" type="Blog">
          <id property="id" column="blog_id"/>
          <result property="title" column="blog_title"/>
          <collection property="posts" ofType="Post">
            <id property="id" column="post_id"/>
            <result property="subject" column="post_subject"/>
            <result property="body" column="post_body"/>
          </collection>
        </resultMap>

         

        Blog 객체는 여러개의 Post 객체를 가지고,

        collection 요소는 여러 Post 객체를 Blog 객체의 posts 프로퍼티에 매핑한당

         

         

         

        • property : 매핑할 자바 객체의 프로퍼티 이름
        • javaType : 매핑할 자바 객체의 타입 (association 에서 사용)
        • ofType : 컬렉션에 포함된 객체의 타입 (collection 에서 사용)

         


        예시

         

        학생의 사진을 등록하는 기능을 넣는다고 하장

        학생(Stud) : 사진(FileDetail) = 다 : 다 이기때문에 중간에 연결다리 테이블(FileGroup) 하나 만들어주장

         

         

        ↓ FileGroupVO ↓ 

        public class FileGroupVO {
        	private long fileGroupNo;
        	private Date fileRegdate;
        }

         

         

         

        ↓ StudVO ↓ 

        public class StudVO {
        	private String email;
        	private String password;
        	private String rememberMe;
        	private long fileGroupNo;
        	private MultipartFile[] uploadFiles; 
        }

         

         

         

        ↓ FileDetailVO ↓ 

        public class FileDetailVO {
        	private int 		fileSn;
        	private long 		fileGroupNo;
        	private String 		fileOriginalName;
        	private String 		fileSaveName;
        	private String 		fileSaveLocate;
        	private long 		fileSize;
        	private String 		fileExt;
        	private String 		fileMime;
        	private String 		fileFancysize;
        	private Date 		fileSaveDate;
        	private int 		fileDowncount;
        }

         

        이렇게 세개의 vo가 있고,   

         

        studVO → fileGroupVO  

        fileDetailVO → fileGroupVO  

         

        이렇게 참조하고 있다고 하장

         

         

         


         

        public class FileGroupVO {
        	private long fileGroupNo;
        	private Date fileRegdate;
        	
        	private int 		fileSn;
        	private long 		fileGroupNo;
        	private String 		fileOriginalName;
        	private String 		fileSaveName;
        	private String 		fileSaveLocate;
        	private long 		fileSize;
        	private String 		fileExt;
        	private String 		fileMime;
        	private String 		fileFancysize;
        	private Date 		fileSaveDate;
        	private int 		fileDowncount;
        }

         

        FileGroupVO에 fileDetailVO 객체들을 넣어야 하기 때문에 위와 같게 된당

        하지만 위의 방식처럼 하는 것보다는 아래 방식처럼 하는 것이 더 간단하당 !!

         

        public class FileGroupVO {
        	private long fileGroupNo;
        	private Date fileRegdate;
        	
        	//파일그룹 : 파일상세 = 1 : N
        	private List<FileDetailVO> fileDetailVOList;
        }

         

         

        이를 xml 파일의  resultMap에서 매핑을 하게 되는데 

        FileGroup과 FileDetail은 1:N 관계이기 때문에 collection을 사용해서 아래처럼 매핑한당

         

        <resultMap type="kr.or.ddit.vo.FileGroupVO" id="fileGroupMap">
            <result property="fileGroupNo" column="FILE_GROUP_NO"/>
            <result property="fileRegdate" column="FILE_REGDATE"/>
            <collection property="fileDetailVOList" resultMap="fileDetailMap"></collection>
        </resultMap>

         

        <resultMap type="kr.or.ddit.vo.FileDetailVO" id="fileDetailMap">
            <result property="fileSn" column="FILE_SN"/>
            <result property="fileGroupNo" column="FILE_GROUP_NO"/>
            <result property="fileOriginalName" column="FILE_ORIGINAL_NAME"/>
            ...															
        </resultMap>

         

         

         

        마찬가지로 아래처럼 StudVO에 FileGroupVO 객체들을 넣어야 하지만

         

        public class StudVO {
        	private String email;
        	private String password;
        	private String rememberMe;
        	private long fileGroupNo;
        	private MultipartFile[] uploadFiles;
        	
        	private long fileGroupNo;
        	private Date fileRegdate;
        }

         

         

        이렇게 하는 것이 더 간단!

        public class StudVO {
        	private String email;
        	private String password;
        	private String rememberMe;
        	private long fileGroupNo;
        	private MultipartFile[] uploadFiles;
        	
        	//학생 : 파일 그룹 = 1 : 1 (1:1은 리스트가 없음)
        	private FileGroupVO fileGroupVO;
        }

         

         

         

        또 이를 xml파일에서 매핑하는데

        둘은 1:1 관계이기때문에 collection이 아닌 association을 사용하여 아래처럼 매핑한당

         

        <resultMap type="kr.or.ddit.vo.StudVO" id="studMap">
            <result property="email" column="EMAIL"/>
            <result property="password" column="PASSWORD"/>
            <result property="rememberMe" column="REMEMBER_ME"/>
            <result property="fileGroupNo" column="FILE_GROUP_NO"/>	
            <association property="fileGroupVO" resultMap = "fileGroupMap"></association>
        </resultMap>

         

        <resultMap type="kr.or.ddit.vo.FileGroupVO" id="fileGroupMap">
            <result property="fileGroupNo" column="FILE_GROUP_NO"/>
            <result property="fileRegdate" column="FILE_REGDATE"/>	
            <collection property="fileDetailVOList" resultMap="fileDetailMap"></collection>
        </resultMap>

         

         

         

         

         

        resultMap 세팅해준 후 select 쿼리문에서 resultMap id에 맞게 매핑해준당

        <select id="detail" parameterType="kr.or.ddit.vo.StudVO" resultMap="studMap">
            select s.EMAIL, s.PASSWORD, s.REMEMBER_ME, s.FILE_GROUP_NO 
                , fg.FILE_REGDATE, fd.FILE_SN
                 ,fd.FILE_ORIGINAL_NAME, fd.FILE_SAVE_NAME
                , fd.FILE_SAVE_LOCATE, fd.FILE_SIZE, fd.FILE_EXT, fd.FILE_MIME
                , fd.FILE_FANCYSIZE, fd.FILE_SAVE_DATE, fd.FILE_DOWNCOUNT
            from stud s left outer join file_group fg 
                            on s.file_group_no = fg.file_group_no
                        left outer join file_detail fd 
                            on s.file_group_no = fd.file_group_no
            where s.email = #{email}
        </select>

         

         

        그리고 데이터 꺼낼 때는 이런식으로 타고 타고 들어가서 꺼내야한당!!

        <c:forEach var="list" items="${studVO.fileGroupVO.fileDetailVOList}">
            <div class="col-sm-1">
              <img  width="200px" class="img-fluid" src="${list.fileSaveLocate}" alt="Photo">
            </div>
        </c:forEach>

         


         

        public class StudVO {
        	private String email;
        	private String password;
        	private String rememberMe;
        	private long fileGroupNo;
        	private MultipartFile[] uploadFiles;
        	
        	private long fileGroupNo;
        	private Date fileRegdate;
            
            private int 		fileSn;
        	private long 		fileGroupNo;
        	private String 		fileOriginalName;
        	private String 		fileSaveName;
        	private String 		fileSaveLocate;
        	private long 		fileSize;
        	private String 		fileExt;
        	private String 		fileMime;
        	private String 		fileFancysize;
        	private Date 		fileSaveDate;
        	private int 		fileDowncount;
        }

         

        만약 굳이 굳이 이렇게 하나의 vo에 합쳐서 하고싶다면

         

        resultMap할 때도 아래처럼 합쳐서 쓰면 된당

        <resultMap type="kr.or.ddit.vo.StudVO" id="studMap">
            <result property="email" column="EMAIL"/>
            <result property="password" column="PASSWORD"/>
            <result property="rememberMe" column="REMEMBER_ME"/>
            <result property="fileGroupNo" column="FILE_GROUP_NO"/>	
            <result property="fileRegdate" column="FILE_REGDATE"/>
            <result property="fileSn" column="FILE_SN"/>
            <result property="fileOriginalName" column="FILE_ORIGINAL_NAME"/>
            <result property="fileSaveName" column="FILE_SAVE_NAME"/>
            <result property="fileSaveLocate" column="FILE_SAVE_LOCATE"/>
            <result property="fileSize" column="FILE_SIZE"/>
            <result property="fileExt" column="FILE_EXT"/>
            <result property="fileMime" column="FILE_MIME"/>
            <result property="fileFancysize" column="FILE_FANCYSIZE"/>
            <result property="fileSaveDate" column="FILE_SAVE_DATE"/>    
        </resultMap>

         

         


        정리

         

        MyBatis에서 SQL 결과를 객체로 변환하여 관계 매핑할 때 Association과 Collection을 사용하여 객체간의 관계를 표현한당. 복잡한 조인 쿼리 결과를 객체 그래프로 변환할 때 중첩된 객체 구조를 쉽게 표현할 수 있기 때문에 association과 collection 매핑이 필수적이당. 

        또 매핑을 통해 지연 로딩이나 즉시 로딩같은 고급 기능을 설정하여 성능을 최적화시킬 수 있당

         

         

         

         

         

        728x90

        '자바' 카테고리의 다른 글

        서블릿 저장소 Request, Session, Context 차이와 사용법  (0) 2025.04.21
        자바 기초  (0) 2024.12.22
        iterator  (1) 2024.11.09
        selectkey  (1) 2024.10.15
        forward, sendredirect  (0) 2024.10.15
        다음글
        다음 글이 없습니다.
        이전글
        이전 글이 없습니다.
        댓글
      조회된 결과가 없습니다.
      스킨 업데이트 안내
      현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
      ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
      목차
      표시할 목차가 없습니다.
        • 안녕하세요
        • 감사해요
        • 잘있어요

        티스토리툴바