IT/development

[spring/mybatis] Rest API ๊ณ„์ธต๊ตฌ์กฐ(1:N) ๊ฐ์ฒด ์กฐํšŒ(feat .์‰ฌ์šด ์˜ˆ์ œ)

์•Œ ์ˆ˜ ์—†๋Š” ์‚ฌ์šฉ์ž 2022. 12. 25.

๋ชฉ์ฐจ

    ์—ญ์‹œ๋‚˜ ๋ฏธ๋ž˜์˜ ๋‚˜๋ฅผ ์œ„ํ•ด ๊ธฐ๋กํ•œ๋‹ค.

    ๊ณ„์ธต๊ตฌ์กฐ ์กฐํšŒ๊ฐ€ ์ฒ˜์Œ ์ ‘ํ•˜๊ณ  ์ต์ˆ™ํ•ด์ง€๊ธฐ ์ „๊นŒ์ง€๋Š” ์ข€ ์–ด๋ ต๋‹ค.(๋ฌผ๋ก  ์ง€๊ธˆ๋„ ์‰ฌ์šด ๊ฑด ์•„๋‹ˆ๋‹ค.)

    ๋ชจ๋“  ์ผ์ด ์ต์ˆ™ํ•ด์ง€๋ฉด ์•„๋ฌด๊ฒƒ๋„ ์•„๋‹Œ ๊ฒŒ ๊ทธ์ „๊นŒ์ง€๋Š” ์–ด๋ ค์šด ๋ฒ•์ด๋‹ค.

    Rest API ๊ณ„์ธต๊ตฌ์กฐ ์กฐํšŒ ๊ฐ„๋‹จ ์˜ˆ์‹œ๋‹ค.

    ์‚ฌ์šฉ์ž(UserDto) ๊ฐ์ฒด๊ฐ€ ๋„์„œ ๊ฐ์ฒด(BookDto)๋ฅผ list๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ตฌ์กฐ๋‹ค.

    ํšŒ์›๊ณผ ๋„์„œ์˜ ๊ด€๊ณ„๋ฅผ 1:N์œผ๋กœ ๋งคํ•‘ํ–ˆ๊ณ  ํšŒ์›์ด ๋ถ€๋ชจ๊ณ  ์ฑ…์ด ์ž์‹์ด๋‹ค.

    ์•„๋ž˜์ฒ˜๋Ÿผ ํ•œ๋ช…์˜ ํšŒ์›์ด ์—ฌ๋Ÿฌ๊ฐœ์˜ ์ฑ…์„ ๋Œ€์ถœํ•  ์ˆ˜ ์žˆ๋Š” ์กฐ๊ฑด

    ๊ทธ๋ž˜์„œ ํšŒ์› ๊ฐ์ฒด๋Š” ๋„์„œ ๊ฐ์ฒด๋ฅผ list๋กœ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค.

    ์•„๋ž˜ DB ํ…Œ์ด๋ธ”์„ ๋ณด๋ฉด ํšŒ์›๋ฒˆํ˜ธ 1๋ฒˆ์ธ ์ฒœ๋‘ฅ์˜ ์‹  ํ† ๋ฅด๊ฐ€ ์—ดํ˜ˆ๊ฐ•ํ˜ธ 1๊ถŒ~5๊ถŒ๊นŒ์ง€ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

    API๋‹ˆ๊นŒ ๋‹น์—ฐํžˆ ํด๋ผ์ด์–ธํŠธ์— ์ „๋‹ฌํ•  ๊ฐ์ฒด์ธ dto์™€ db ์กฐ์ž‘์‹œ ์‚ฌ์šฉํ•  ๊ฐ์ฒด์ธ vo๋ฅผ ๋”ฐ๋กœ ๋‘์—ˆ๋‹ค.


    DB ๐Ÿ˜„

    ํšŒ์› ํ…Œ์ด๋ธ”

    CREATE TABLE `temp_user` (
      `user_seq` int(20) NOT NULL AUTO_INCREMENT COMMENT '์‚ฌ์šฉ์ž๋ฒˆํ˜ธ',
      `user_name` varchar(30) NOT NULL COMMENT '์‚ฌ์šฉ์ž๋ช…',
      `user_email` varchar(30) NOT NULL COMMENT '์‚ฌ์šฉ์ž ์ด๋ฉ”์ผ',
      `reg_date` timestamp NULL DEFAULT NULL COMMENT '๋“ฑ๋ก์ผ',
      PRIMARY KEY (`user_seq`,`user_email`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

    ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ

    INSERT INTO temp_user
    (user_seq, user_name, user_email, reg_date)
    VALUES(1, 'ํ† ๋ฅด', 'thor@naver.com', '2022-12-21 22:57:07.000');
    INSERT INTO temp_user
    (user_seq, user_name, user_email, reg_date)
    VALUES(2, 'ํ—ํฌ', 'hulk@naver.com', '2022-12-21 22:57:07.000');
    INSERT INTO temp_user
    (user_seq, user_name, user_email, reg_date)
    VALUES(3, 'ํƒ€๋…ธ์Šค', 'tanos@naver.com', '2022-12-21 22:57:07.000');

    ๋„์„œ ํ…Œ์ด๋ธ”

    CREATE TABLE `temp_book` (
      `book_seq` int(20) NOT NULL AUTO_INCREMENT COMMENT '๋„์„œ ๋ฒˆํ˜ธ',
      `book_name` varchar(30) NOT NULL COMMENT '๋„์„œ๋ช…',
      `author` varchar(30) NOT NULL COMMENT '์ €์ž',
      `user_seq` int(11) NOT NULL COMMENT '์‚ฌ์šฉ์ž๋ฒˆํ˜ธ',
      PRIMARY KEY (`book_seq`,`book_name`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

    ํ…Œ์ŠคํŠธ๋ฐ์ดํ„ฐ

    INSERT INTO temp_book
    (book_seq, book_name, author, user_seq)
    VALUES(25, '์—ดํ˜ˆ๊ฐ•ํ˜ธ1๊ถŒ', '์–‘๊ทน์ง„', 1);
    INSERT INTO temp_book
    (book_seq, book_name, author, user_seq)
    VALUES(26, '์—ดํ˜ˆ๊ฐ•ํ˜ธ2๊ถŒ', '์–‘๊ทน์ง„', 1);
    INSERT INTO temp_book
    (book_seq, book_name, author, user_seq)
    VALUES(27, '์—ดํ˜ˆ๊ฐ•ํ˜ธ3๊ถŒ', '์–‘๊ทน์ง„', 1);
    INSERT INTO temp_book
    (book_seq, book_name, author, user_seq)
    VALUES(28, '์—ดํ˜ˆ๊ฐ•ํ˜ธ4๊ถŒ', '์–‘๊ทน์ง„', 1);
    INSERT INTO temp_book
    (book_seq, book_name, author, user_seq)
    VALUES(29, '์—ดํ˜ˆ๊ฐ•ํ˜ธ5๊ถŒ', '์–‘๊ทน์ง„', 1);
    INSERT INTO temp_book
    (book_seq, book_name, author, user_seq)
    VALUES(30, '์›ํ”ผ์Šค1๊ถŒ', '์ผ๋ณธ1', 2);
    INSERT INTO temp_book
    (book_seq, book_name, author, user_seq)
    VALUES(31, '์›ํ”ผ์Šค6๊ถŒ', '์ผ๋ณธ1', 2);
    INSERT INTO temp_book
    (book_seq, book_name, author, user_seq)
    VALUES(32, '์›ํ”ผ์Šค7๊ถŒ', '์ผ๋ณธ1', 2);
    INSERT INTO temp_book
    (book_seq, book_name, author, user_seq)
    VALUES(33, '์Šฌ๋žจ๋ฉํฌ1๊ถŒ', '์ผ๋ณธ2', 3);
    INSERT INTO temp_book
    (book_seq, book_name, author, user_seq)
    VALUES(34, '์Šฌ๋žจ๋ฉํฌ100๊ถŒ', '์ผ๋ณธ2', 3);

    DB ๋„์„œ ํ…Œ์ด๋ธ”์˜ ์™ธ๋ž˜ํ‚ค๋Š” ํ…Œ์ŠคํŠธ๋‹ˆ ๋…ผ๋ฆฌ์ ์œผ๋กœ๋งŒ ์„ค์ •ํ–ˆ๋‹ค.


    Java๋‹จ ๐Ÿ˜˜

    Vo(DB์™€ ํ†ต์‹  ์šฉ๋„)

    ๋„ค์ด๋ฐ ๋ฃฐ์€ ์„œ๋ฒ„๋‹จ์ด๋‹ˆ ์นด๋ฉœ์ผ€์ด์Šค๋กœ ์„ ์–ธ

    ์•„๋ž˜ ์ธํ…”๋ฆฌ์ œ์ด์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ข€ ์ˆ˜์›”ํ•˜๋‹ค.

     

    [IntelliJ] camelCase <-> snake_case ๋ณ€ํ™˜(feat. CamelCase plugin)

    ๋ชฉ์ฐจ camelCase snake_case ๐Ÿ˜Š ๊ฐœ๋ฐœ์‹œ์— ๋Œ€์ฒด์ ์œผ๋กœ java์—์„œ๋Š” ์นด๋ฉœ์ผ€์ด์Šค(userName)๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  DB ํ•„๋“œ๋Š” ์Šค์ผ€์ดํฌ์ผ€์ด์Šค(user_name)์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ์ˆ˜์ž‘์—…์œผ๋กœ ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ๊ดœ์ฐฎ์€ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๋ฐœ๊ฒฌํ•ด

    yaga.tistory.com

    package study.lsyrestapitest1.domain.vo;
    
    import lombok.Getter;
    import lombok.Setter;
    import lombok.ToString;
    
    import java.util.ArrayList;
    import java.util.List;
    
    @Getter @Setter
    @ToString
    // ํšŒ์›
    public class UserVo {
        private int userSeq;
        private String userName;
        private String userEmail;
        private String regDate;
        private List<BookVo> bookVoList = new ArrayList<>();
    }
    package study.lsyrestapitest1.domain.vo;
    
    import lombok.Getter;
    import lombok.Setter;
    import lombok.ToString;
    
    @Getter @Setter @ToString
    // ๋„์„œ
    public class BookVo {
        private int bookSeq;
        private String bookName;
        private String author;
    }

    Dto(ํด๋ผ์ด์–ธํŠธ์™€ ํ†ต์‹  ์šฉ๋„)

    ์‰ฌ์šด ์˜ˆ์ œ๋ฅผ ์œ„ํ•ด ๋นŒ๋”ํŒจํ„ด์ด ์•„๋‹Œ Getter/Setter๋ฅผ ์ด์šฉํ–ˆ๋‹ค.

    ๋„ค์ด๋ฐ ๋ฃฐ์€ ํด๋ผ์ด์–ธํŠธ๋‹จ์ด๋‹ˆ ์Šค๋„ค์ดํฌ์ผ€์ด์Šค๋กœ ์„ ์–ธ

    package study.lsyrestapitest1.domain.dto;
    
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.Setter;
    import lombok.ToString;
    
    import java.util.ArrayList;
    import java.util.List;
    
    @Getter @Setter
    @ToString
    @NoArgsConstructor
    // ํšŒ์›
    public class UserDto {
        private int user_seq;
        private String user_name;
        private String user_email;
        private String reg_date;
        private List<BookDto> book_dto_list = new ArrayList<>();
    
        public UserDto(int user_seq, String user_name, String user_email, String reg_date) {
            this.user_seq = user_seq;
            this.user_name = user_name;
            this.user_email = user_email;
            this.reg_date = reg_date;
        }
    }
    package study.lsyrestapitest1.domain.dto;
    
    import lombok.*;
    
    @Getter @Setter
    @ToString
    @NoArgsConstructor
    // ๋„์„œ
    public class BookDto {
        private int book_seq;
        private String book_name;
        private String author;
    
        public BookDto(int book_seq, String book_name, String author) {
            this.book_seq = book_seq;
            this.book_name = book_name;
            this.author = author;
        }
    }

    mapper xml

    resultMap์˜ collection์„ ์ด์šฉํ•ด ๊ณ„์ธต๊ตฌ์กฐ๋ฅผ ๋งคํ•‘ํ–ˆ๊ณ  resultMap์œผ๋กœ ๋ฐ›์•˜๋‹ค.

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="study.lsyrestapitest1.mapper.UserMapper">
        <resultMap id="userMap" type="study.lsyrestapitest1.domain.vo.UserVo">
            <id column="user_seq" property="userSeq"/>
            <result column="user_name" property="userName"/>
            <result column="user_email" property="userEmail"/>
            <result column="reg_date" property="regDate"/>
            <!-- ์ฑ… list -->
            <collection property="bookVoList" javaType="java.util.ArrayList" resultMap="bookMap"/>
        </resultMap>
    
        <!--  ์ฑ… -->
        <resultMap id="bookMap" type="study.lsyrestapitest1.domain.vo.BookVo">
            <id column="book_seq" property="bookSeq"/>
            <result column="book_name" property="bookName"/>
            <result column="author" property="author"/>
        </resultMap>
    
        <select id="findUserList" resultMap="userMap">
            SELECT  tu.user_seq
                   ,tu.user_name
                   ,tu.user_email
                   ,tu.reg_date
                   ,tb.book_seq
                   ,tb.book_name
                   ,tb.author
            FROM temp_user tu LEFT OUTER JOIN temp_book tb ON tu.user_seq = tb.user_seq
        </select>
    </mapper>

    ํ˜น์€ ์•„๋ž˜์ฒ˜๋Ÿผ collection์˜ ofType์„ ๋Œ€์ƒ ํด๋ž˜์Šค๋กœ ์„ ์–ธํ•˜๊ณ  resultMap์•ˆ์—๋‹ค ๋„ฃ์–ด๋„ ๋œ๋‹ค.

    ofType์„ ์„ ์–ธํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ NPE๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="study.lsyrestapitest1.mapper.UserMapper">
        <resultMap id="userMap" type="study.lsyrestapitest1.domain.vo.UserVo">
            <id column="user_seq" property="userSeq"/>
            <result column="user_name" property="userName"/>
            <result column="user_email" property="userEmail"/>
            <result column="reg_date" property="regDate"/>
            <!-- ์ฑ… list -->                                                                      
            <collection property="bookVoList" ofType="study.lsyrestapitest1.domain.vo.BookVo">
                <result column="book_seq" property="bookSeq"/>
                <result column="book_name" property="bookName"/>
                <result column="author" property="author"/>             
            </collection>
        </resultMap>
    
        <select id="findUserList" resultMap="userMap">
            SELECT  tu.user_seq
                 ,tu.user_name
                 ,tu.user_email
                 ,tu.reg_date
                 ,tb.book_seq
                 ,tb.book_name
                 ,tb.author
            FROM temp_user tu LEFT OUTER JOIN temp_book tb ON tu.user_seq = tb.user_seq
        </select>
    </mapper>

    โ€ป hasOne(๋ถ€๋ชจ ์ž์‹์˜ ๊ด€๊ณ„๊ฐ€ 1:1)๊ด€๊ณ„๋Š” association ํƒœ๊ทธ๋ฅผ ์ด์šฉํ•˜๋ฉด ๋˜๊ณ  ์•„๋ž˜์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

    <association property="BookInfo" javaType="com.test.lsy.vo.bookInfo">
        <result column="book_no" property="BookNo"/>
        <result column="book_nm" property="BookNm"/>
    </association>

    mapper interface

    package study.lsyrestapitest1.mapper;
    
    import org.apache.ibatis.annotations.Mapper;
    import org.springframework.stereotype.Repository;
    import study.lsyrestapitest1.domain.vo.UserVo;
    
    import java.util.List;
    
    @Mapper @Repository
    public interface UserMapper {
    
        List<UserVo> findUserList();
    }

    service

    DB ์กฐํšŒ ๊ฐ’์„ Voํƒ€์ž… list์— ๋ฐ›์•„ list๋ฅผ ๋ฃจํ”„ ๋Œ๋ฉฐ ์ƒˆ๋กœ ๋งŒ๋“  dto๊ฐ์ฒด์— ์„ธํŒ…์„ ์‹œํ‚จ ํ›„ DtoList ๋ฐ˜ํ™˜

    ๋ฌผ๋ก  stream ๋“ฑ์„ ์ด์šฉํ•ด ๋” ์ฝ”๋“œ๋ฅผ ๊ฐ„๊ฒฐํ™” ํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ๋ˆ„๊ตฌ๋‚˜ ๋ณด๊ธฐ ์‰ฝ๊ฒŒ ํ–ฅ์ƒ๋œ for๋ฌธ ์ด์šฉ

    ์•„๋‹ˆ๋ฉด ๊ทธ๋ƒฅ mapper์—์„œ๋ถ€ํ„ฐ dto๋กœ ๋ฐ›์œผ๋ฉด ์„œ๋น„์Šค ์ฝ”๋“œ๋„ ๋งค์šฐ ๊ฐ„๊ฒฐํ•ด ์ง„๋‹ค.(์ด๊ฒŒ ๋” ๋‚˜์„ ๋“ฏ ํ•˜๋‹ค.)

    package study.lsyrestapitest1.service;
    
    import lombok.RequiredArgsConstructor;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    import study.lsyrestapitest1.domain.dto.BookDto;
    import study.lsyrestapitest1.domain.dto.UserDto;
    import study.lsyrestapitest1.domain.vo.BookVo;
    import study.lsyrestapitest1.domain.vo.UserVo;
    import study.lsyrestapitest1.mapper.UserMapper;
    
    import java.util.ArrayList;
    import java.util.List;
    
    @Service
    @Slf4j
    @RequiredArgsConstructor
    @Transactional(readOnly = true)
    public class UserService {
    
        private final UserMapper userMapper;
        
        public List<UserDto> findUserList() {
        	// DB๊ฐ’ ์กฐํšŒํ•œ ๊ฐ’์„ userVoList์— ์ €์žฅ
            List<UserVo> userVoList = userMapper.findUserList();
            List<UserDto> userDtoList = new ArrayList<>();
    		// userVoList๋ฅผ ๋ฃจํ”„ ๋Œ๋ฉฐ UserDto๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ ํ•ด Vo์˜ ๊ฐ’์„ dto์— ์„ธํŒ…
            for (UserVo userVo : userVoList) {
                UserDto userDto = new UserDto(userVo.getUserSeq(), userVo.getUserName(), userVo.getUserEmail(), userVo.getRegDate());
    			// UserVo์˜ bookVoList๊ฐ’์„ bookVoList์— ์ €์žฅ ํ›„ ๋ฃจํ”„ ๋Œ๋ฉฐ bookDtoList์— ์ €์žฅ            
                List<BookVo> bookVoList = userVo.getBookVoList();
                List<BookDto> bookDtoList = new ArrayList<>();
                for (BookVo bookVo : bookVoList) {
                    BookDto bookDto = new BookDto(bookVo.getBookSeq(), bookVo.getBookName(), bookVo.getAuthor());
                    bookDtoList.add(bookDto);
                    // userDto์˜ book_dto_list์— bookVoList์˜ ๊ฐ’์„ ์„ธํŒ…
                    userDto.setBook_dto_list(bookDtoList);
                }
                // userDtoList์— userDto ๊ฐ์ฒด ์ถ”๊ฐ€
                userDtoList.add(userDto);
            }
            return userDtoList;
        }
    }

    controller

    ๋ฐ˜ํ™˜ data๋ฅผ view ์—†์ด Http Body์— ์‹ค์–ด HttpStatus 200์ฝ”๋“œ์™€ ํ•จ๊ป˜ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

    @RestController๋Š” @Controller์™€ @ResponseBody๊ฐ€ ํ•ฉ์ณ์ง„ ์• ๋…ธํ…Œ์ด์…˜์ด๋‹ค.

    package study.lsyrestapitest1.controller.api;
    
    import lombok.RequiredArgsConstructor;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import study.lsyrestapitest1.domain.dto.UserDto;
    import study.lsyrestapitest1.domain.vo.UserVo;
    import study.lsyrestapitest1.service.UserService;
    
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    @RestController
    @Slf4j
    @RequiredArgsConstructor
    @RequestMapping(value = "/api/v1/users")
    public class UserApiController {
    
        private final UserService userService;
    
        @GetMapping(value = "")
        public ResponseEntity<?> findUserList() {
        
            Map<String, Object> resultMap = new HashMap<>();
            
            try {
                resultMap.put("resultData", userService.findUserList());
                resultMap.put("resultCode", "0000");
                resultMap.put("resultMsg", "์ •์ƒ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.");
                return new ResponseEntity(resultMap, HttpStatus.OK);
            } catch (Exception e) {
                log.info("exception :: {}", e.getMessage());
                resultMap.put("resultCode", "9999");
                resultMap.put("errorMsg", e.getMessage());
                resultMap.put("resultMsg", "๋‚ด๋ถ€ ์„œ๋น„์Šค ์˜ค๋ฅ˜์ž…๋‹ˆ๋‹ค.");
                return new ResponseEntity(resultMap, HttpStatus.BAD_REQUEST);
            }
        }
    }

    ํ…Œ์ŠคํŠธ

    ๋‚ด๊ฐ€ ์›ํ•œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋Œ€๋กœ ์ž˜ ๋ฐ˜ํ™˜์ด ๋œ๋‹ค.

    Map({})์•ˆ์— list([])์•ˆ์— uerDto๊ฐ์ฒด({book_dto_list[]})๊ฐ€ ๋‹ด๊ฒจ ์žˆ๊ณ  http ์ƒํƒœ์ฝ”๋“œ 200์ด ๋ฐ˜ํ™˜๋˜์—ˆ๋‹ค.

    ์ฒ˜์Œ์—๋Š” ๊ฐ์ฒด์•ˆ์— ๊ฐ์ฒดํƒ€์ž… ๋ฆฌ์ŠคํŠธ๊ฐ€ ์žˆ๋Š” ๊ตฌ์กฐ๊ฐ€ ๋ฌด์ฒ™ ํ—ท๊ฐˆ๋ ธ๋Š”๋ฐ ์ต์ˆ™ํ•ด์ง€๋‹ˆ ์ข€ ๋‚˜์•„์กŒ๋‹ค. 

    ์‹ค๋ฌด๋Š” ๋” ๋ณต์žกํ•œ ๊ตฌ์กฐ๊ฐ€ ๋งŽ๊ธฐ์— ์ด ๊ฐ„๋‹จํ•œ ๊ตฌ์กฐ๋ถ€ํ„ฐ ์ดํ•ด๊ฐ€ ๋˜์–ด์•ผ ์‘์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

    ํ”„๋กœ์ ํŠธ  ์ƒ์„ฑ ํ›„ ํŒจํ‚ค์ง€๋ช…๋งŒ ๋ณ€๊ฒฝํ•ด์„œ ๊ตฌํ˜„ํ•˜๋ฉด ๊ฒฐ๊ณผ๊ฐ’์ด ์ž˜ ๋‚˜์˜ฌ ๊ฒƒ์ด๋‹ค.

    ์ด๋ ‡๊ฒŒ mybatis์—์„œ ๊ณ„์ธต ๋งคํ•‘ํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๊ณ  ์ฟผ๋ฆฌ๋กœ ๋ฐ์ดํ„ฐ ํ•œ๋ฒˆ์— ๊ฐ€์ ธ์™€์„œ list์— ๋‹ด์•„ java๋‹จ์—์„œ for๋ฌธ ๋Œ๋ ค์„œ ๋งคํ•‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

    ๋Œ“๊ธ€