์‡ผํ•‘๋ชฐ ํ”„๋กœ์ ํŠธ(8) ์ƒํ’ˆ ๋“ฑ๋ก

2023. 3. 29. 16:59ใ†Spring

์•„๋ž˜์˜ ๋ณด์—ฌ์ง€๋Š” ์ƒํ’ˆ ๋“ฑ๋ก ํ™”๋ฉด์˜ CATEGORY select ๋ฐ•์Šค์—๋Š” ํ˜„์žฌ ์‚ฌ์šฉ์ค‘์ธ ์นดํ…Œ๊ณ ๋ฆฌ๋งŒ ๊ฐ€์ง€๊ณ  ์™€์•ผ ํ•จ.

์ƒํ’ˆ ๋“ฑ๋ก ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•  ๋•Œ ์ด์ „์— ์ž‘์„ฑํ•œ ์‚ฌ์šฉ์ค‘์ธ ์นดํ…Œ๊ณ ๋ฆฌ ๋ชฉ๋ก ์กฐํšŒ ๋ฉ”์†Œ๋“œ ์‚ฌ์šฉ

๋ฉ”์†Œ๋“œ ์‚ฌ์šฉ์„ ์œ„ํ•ด AdminController์— itmeService ์˜์กด์„ฑ ์ฃผ์ž… ํ›„ ๋ฉ”์†Œ๋“œ ์‹คํ–‰

	//์ƒํ’ˆ ๋“ฑ๋ก ํŽ˜์ด์ง€						
	@GetMapping("/regItem")				
	public String regItemForm(Model model, AdminSubMenuVO adminSubMenuVO) {
		//์‚ฌ์šฉ์ค‘์ธ ์นดํ…Œ๊ณ ๋ฆฌ ๋ชฉ๋ก ์กฐํšŒ
		model.addAttribute("categoryList", itemService.getCateListInUse());
		
		return "content/admin/reg_item";
	}

reg_item.html์˜ ์นดํ…Œ๊ณ ๋ฆฌ ์„ ํƒํ•˜๋Š” select ๋ฐ•์Šค์—์„œ for๋ฌธ ์‚ฌ์šฉ

         <div class="col-3">
            <label for="" class="form-label">CATEGORY</label> 
            <select id="" name="cateCode" class="form-select">
               <th:block th:each="category : ${categoryList}">
               	<option th:value="${category.cateCode}">[[${category.cateName}]]</option>
               </th:block>
            </select>
         </div>

 

 

์ƒํ’ˆ ๋“ฑ๋ก ๊ธฐ๋Šฅ

 

itemVO ์ž‘์„ฑ

์ƒํ’ˆ ๋“ฑ๋ก ์ฟผ๋ฆฌ ์ž‘์„ฑ.

์ƒํ’ˆ๋“ฑ๋ก์€ ๊ด€๋ฆฌ์ž ๊ถŒํ•œ์ด๊ธฐ ๋•Œ๋ฌธ์— admin-mapper์— ์ž‘์„ฑ.

itemCode๋Š” ์ถ”ํ›„์— ๋“ฑ๋ก๋  itemCode ์กฐํšŒํ•˜๋Š” ์ฟผ๋ฆฌ ๋”ฐ๋กœ ์ž‘์„ฑํ•ด์„œ ์ฒ˜๋ฆฌ.

	<!-- ์ƒํ’ˆ ๋“ฑ๋ก -->
	<insert id="regItem">
		INSERT INTO SHOP_ITEM (
			ITEM_CODE
			, CATE_CODE
			, ITEM_NAME
			, ITEM_PRICE
			, ITEM_STOCK
			, ITEM_INTRO
			, ITEM_STATUS
		) VALUES (
			#{itemCode}
        	, #{cateCode}
        	, #{itemName}
        	, #{itemPrice}
        	, #{itemStock}
        	, #{itemIntro}
        	, #{itemStatus}
		)
	</insert>

 

AdminService ๋ฉ”์†Œ๋“œ ์ƒ์„ฑ

	//์ƒํ’ˆ ๋“ฑ๋ก
	void insertItem(ItemVO itemVO);

AdminServiceImpl ๋ฉ”์†Œ๋“œ ๊ตฌํ˜„

	//์ƒํ’ˆ ๋“ฑ๋ก
	@Override
	public void insertItem(ItemVO itemVO) {
		sqlSession.insert("adminMapper.insertItem", itemVO);
		
	}

 

๋‹ค์Œ์— ์˜ฌ itemCode ์กฐํšŒ ์ฟผ๋ฆฌ ์ž‘์„ฑ.

	<!-- ๋‹ค์Œ์— ์˜ฌ itemCode ์กฐํšŒ -->
	<select id="getNextItemCode" resultType="String">
		SELECT 'ITEM_'||LPAD(NVL(MAX(TO_NUMBER(SUBSTR(ITEM_CODE, 6))), 0) + 1, 3, '0') 
        FROM SHOP_ITEM
	</select>

AdminService ๋ฉ”์†Œ๋“œ ์ƒ์„ฑ

	//๋‹ค์Œ ๋“ฑ๋ก๋  ์ƒํ’ˆ ์ฝ”๋“œ ์กฐํšŒ
	String getNextItemCode();

AdminServiceImpl ๋ฉ”์†Œ๋“œ ๊ตฌํ˜„

	//๋‹ค์Œ ์ƒํ’ˆ ์ฝ”๋“œ ์กฐํšŒ
	@Override
	public String getNextItemCode() {
		
		return sqlSession.selectOne("adminMapper.getNextItemCode");
	}

 

reg_item.html์—์„œ form ํƒ€๊ณ  ์ž…๋ ฅํ•œ ๋ฐ์ดํ„ฐ๋กœ ์ƒํ’ˆ ๋“ฑ๋ก๋˜์–ด์•ผ ํ•จ.

๋“ฑ๋ก ๋ฒ„ํŠผ submit์œผ๋กœ ์ˆ˜์ •ํ•˜๊ณ  form ํƒœ๊ทธ ์†์„ฑ ๋„ฃ์–ด์„œ ์‹ค์ œ๋กœ ์ƒํ’ˆ ๋“ฑ๋กํ•˜๋Š” AdminController๋กœ ์ด๋™.

<th:block layout:fragment="content">
<div class="row">
   <div class="col-12">
      <form id="" class="row g-3" th:action="@{/admin/regItem}" method="post">
         <div class="col-3">
            <label for="" class="form-label">CATEGORY</label> 
            <select id="" name="cateCode" class="form-select">
               <th:block th:each="category : ${categoryList}">
               	<option th:value="${category.cateCode}">[[${category.cateName}]]</option>
               </th:block>
            </select>
         </div>
         <div class="col-9">
            <label for="" class="form-label">ITEM NAME</label> 
            <input type="text" class="form-control" id="" name="itemName">
         </div>
         <div class="col-6">
            <label for="" class="form-label">ITEM PRICE</label> 
            <input type="text" class="form-control" id="" name="itemPrice">
         </div>
         <div class="col-6">
            <label for="" class="form-label">ITEM STOCK</label> 
            <input type="number" class="form-control" value="10" min="10" max="100" id="" name="itemStock">
         </div>
         <div class="col-12">
            <label for="" class="form-label">ITEM INTRODUCTION</label> 
            <textarea rows="5" class="form-control" name="itemIntro"></textarea>
         </div>
         <div class="col-6">
            <label for="" class="form-label">MAIN IMAGE</label> 
            <input type="file" class="form-control" id="" name="">
         </div>
         <div class="col-6">
            <label for="" class="form-label">MAIN IMAGE</label> 
            <input type="file" class="form-control" id="" name="">
         </div>
         <div class="col-12">
            <div class="form-check form-check-inline">
               <input class="form-check-input" value="1" type="radio" id="" name="itemStatus" checked>
               <label class="form-check-label" for="">ํŒ๋งค์ค‘</label>
            </div>
            <div class="form-check form-check-inline">
               <input class="form-check-input" value="2" type="radio" id="" name="itemStatus">
               <label class="form-check-label" for="">์ค€๋น„์ค‘</label>
            </div>
            <div class="form-check form-check-inline">
               <input class="form-check-input" value="3" type="radio" id="" name="itemStatus">
               <label class="form-check-label" for="">ํ’ˆ์ ˆ</label>
            </div>
         </div>
         <div class="col-3">
            <button id="" type="submit" class="btn btn-primary">REGISTRATION ITEM</button>
         </div>
      </form>
   </div>
</div>
</th:block>

AdminController ์ž‘์„ฑ.

์ƒํ’ˆ ๋“ฑ๋ก ์ „์— ๋“ฑ๋ก๋  ์ƒํ’ˆ ์ฝ”๋“œ ์กฐํšŒํ•˜๋Š” ๋ฉ”์†Œ๋“œ ๋จผ์ € ์‹คํ–‰

ItemVO์— ๋ฐ์ดํ„ฐ ์„ธํŒ…ํ•ด์ค€ ํ›„ ์ƒํ’ˆ ๋“ฑ๋ก ๋ฉ”์†Œ๋“œ ์‹คํ–‰.

	//์ƒํ’ˆ ๋“ฑ๋ก
	@PostMapping("/regItem")
	public String regItem(ItemVO itemVO) {
		//๋“ฑ๋ก๋  ์ƒํ’ˆ์ฝ”๋“œ ์กฐํšŒ
		String itemCode = adminService.getNextItemCode();
		itemVO.setItemCode(itemCode);
		
		//์ƒํ’ˆ ๋“ฑ๋ก ์ฟผ๋ฆฌ
		adminService.insertItem(itemVO);
					//์ƒํ’ˆ ๋“ฑ๋ก ํ›„์— ์„œ๋ธŒ ๋ฉ”๋‰ด์— ์ƒ‰ ์ฃผ๊ธฐ ์œ„ํ•ด subMenuCode ๊ฐ€์ ธ๊ฐ€๊ธฐ
		return "redirect:/admin/regItem?subMenuCode=SUB_MENU_002";
	}

์ƒํ’ˆ ๋“ฑ๋ก ํ›„ ๋‹ค์‹œ regItem controller๋กœ ์ด๋™ํ•˜๋ฉด ์„œ๋ธŒ๋ฉ”๋‰ด์ธ ์ƒํ’ˆ๋“ฑ๋ก์— ์ƒ‰์ด ์‚ฌ๋ผ์ง.

ํŽ˜์ด์ง€ ์ด๋™ํ•  ๋•Œ ๊ฐ•์ œ๋กœ(? subMenuCode ๊ฐ€์ ธ๊ฐ€๊ฒŒ ํ•จ.

 

 

 

 

์ƒํ’ˆ ์ด๋ฏธ์ง€ ํŒŒ์ผ ์—…๋กœ๋“œ

 

์ฒจ๋ถ€ํŒŒ์ผ๋„ form ํƒœ๊ทธ submit ๋ฒ„ํŠผ์œผ๋กœ ๊ฐ€์ ธ๊ฐ€์•ผํ•จ.

itemVO์—๋Š” ์ด๋ฏธ์ง€ ๋ณ€์ˆ˜ ์—†์Œ

์‹ค๋ฌด์—์„œ๋„ ์ด๋ฏธ์ง€ํŒŒ์ผ์€ ์ƒํ’ˆ๊ณผ ํ…Œ์ด๋ธ”, VO ๋“ฑ ๋ถ„๋ฆฌํ•จ

> ์ƒํ’ˆ์ด ๋“ฑ๋ก๋  ๋•Œ ์ด๋ฏธ์ง€๋Š” ์—ฌ๋Ÿฌ๊ฐœ ๋“ฑ๋ก๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ.

 

mainImg๋Š” 1๊ฐœ subImg๋Š” ์—ฌ๋Ÿฌ๊ฐœ ํŒŒ์ผ ๋“ฑ๋ก ๊ฐ€๋Šฅํ•˜๊ฒŒ ์„ค์ •.

input ํƒœ๊ทธ์— multiple ์†์„ฑ์„ ์ฃผ๋ฉด ํ•˜๋‚˜์˜ input์— ์—ฌ๋Ÿฌ๊ฐœ ์‚ฌ์ง„ ์—…๋กœ๋“œ ๊ฐ€๋Šฅ

         <div class="col-6">
            <label for="" class="form-label">MAIN IMAGE</label> 
            <input type="file" class="form-control" id="" name="mainImg">
         </div>
         <div class="col-6">
            <label for="" class="form-label">SUB IMAGE</label> 
            <input type="file" class="form-control" id="" name="subImg" multiple>
         </div>

์ด๋ฏธ์ง€ ๊ฐ์‹ธ๊ณ  ์žˆ๋Š” form ํƒœ๊ทธ์— enctype="multipart/form-data ์†์„ฑ ๊ผญ ๋„ฃ์–ด์ค˜์•ผ ์ฒจ๋ถ€ํŒŒ์ผ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ๊ฐ!

<form id="" class="row g-3" th:action="@{/admin/regItem}" method="post" enctype="multipart/form-data">

controller์—์„œ ์ƒํ’ˆ ๋“ฑ๋ก์„ ํ•  ๋•Œ ์ด๋ฏธ์ง€ ์™ธ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ๋Š” itemVO ์ปค๋งจ๋“œ ๊ฐ์ฒด๊ฐ€ ์ฒ˜๋ฆฌํ•จ

itemVO๋Š” ์ด๋ฏธ์ง€ ํŒŒ์ผ ์•ˆ ๋ฐ›์•„์˜ด.

์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฐ์ฒด ๋”ฐ๋กœ ํ•„์š”!

 

ํŒŒ์ผ์ฒจ๋ถ€ ์‹œ ํŒŒ์ผ๋ช…์ด ์ค‘๋ณต๋˜๋ฉด ์•ˆ๋จ.

์›๋ณธํŒŒ์ผ๋ช…์„ ๋ฐ›์•„์™€์„œ ์„œ๋ฒ„์— ์˜ฌ๋ผ๊ฐˆ ํŒŒ์ผ๋ช…์„ ์ƒ์„ฑํ•ด์คŒ.

์›๋ณธํŒŒ์ผ๋ช…์ด abc.jpg > ๋žœ๋ค๋ฌธ์ž์—ด.jpg์˜ ํ˜•์‹์œผ๋กœ ์ƒ์„ฑ

์›๋ณธํŒŒ์ผ๋ช…์—์„œ ํ™•์žฅ์ž ์ถ”์ถœํ•˜์—ฌ ๋žœ๋ค๋ฌธ์ž์—ด๊ณผ ๋ถ™์—ฌ์ฃผ๋ฉด ๋จ.

๋ฌธ์ž์—ด ์ถ”์ถœ ์ฝ”๋“œ subString๊ณผ ๋ฌธ์ž์—ด ์ˆœ์„œ ์•Œ ์ˆ˜ ์žˆ๋Š” indexOf ์ฝ”๋“œ ์‚ฌ์šฉ.

//์ƒํ’ˆ ๋“ฑ๋ก
	@PostMapping("/regItem")			//์ด๋ฏธ์ง€ ๋ฐ›์•„์˜ค๋Š” ๊ฐ์ฒด, ๋ณ€์ˆ˜๋ช…์€ mainImg inputํƒœ๊ทธ์˜ name , subImg๋Š” ์•ˆ ๋ฐ›์•„์˜ด.
	public String regItem(ItemVO itemVO, MultipartFile mainImg) {
		//---ํŒŒ์ผ ์ฒจ๋ถ€---
	
		//์›๋ณธํŒŒ์ผ๋ช… ๋ฐ›์•„์˜ค๊ธฐ
		String originFileName = mainImg.getOriginalFilename();
		
		//์„œ๋ฒ„์— ์˜ฌ๋ผ๊ฐˆ(์ฒจ๋ถ€๋ ) ํŒŒ์ผ๋ช… ์ƒ์„ฑ(ํŒŒ์ผ๋ช…์ด ์ค‘๋ณต๋˜์ง€ ์•Š๊ฒŒ) 
		//UUID : ์ค‘๋ณตX ๋žœ๋คํ•œ ๋ฌธ์ž์—ด์„ ์ƒ์„ฑ 
		String uuid = UUID.randomUUID().toString();
		
		//์›๋ณธํŒŒ์ผ๋ช…์ด abc.jpg > ๋žœ๋ค๋ฌธ์ž์—ด.jpg์˜ ํ˜•์‹์œผ๋กœ ์ฒจ๋ถ€๋  ํŒŒ์ผ๋ช…์„ ์ƒ์„ฑ
		//์ฒจ๋ถ€๋œ ํŒŒ์ผ์˜ ํ™•์žฅ์ž ์ถ”์ถœ
		String extension = originFileName.substring(originFileName.lastIndexOf("."));  //๋งˆ์ง€๋ง‰ "."๋ฌธ์ž์—์„œ ๋๊นŒ์ง€
		
		//์„œ๋ฒ„์— ์˜ฌ๋ฆด(์ฒจ๋ถ€๋ ) ํŒŒ์ผ๋ช…
		String attachedFileName = uuid + extension;
		
		System.out.println("์›๋ณธํŒŒ์ผ๋ช… : " + originFileName);
		System.out.println("์ฒจ๋ถ€๋  ํŒŒ์ผ๋ช… : " + attachedFileName);
		
		//๋“ฑ๋ก๋  ์ƒํ’ˆ์ฝ”๋“œ ์กฐํšŒ
		String itemCode = adminService.getNextItemCode();
		itemVO.setItemCode(itemCode);
		
		//์ƒํ’ˆ ๋“ฑ๋ก ์ฟผ๋ฆฌ
		adminService.insertItem(itemVO);
						//์ƒํ’ˆ ๋“ฑ๋ก ํ›„์— ์„œ๋ธŒ ๋ฉ”๋‰ด์— ์ƒ‰ ์ฃผ๊ธฐ ์œ„ํ•ด subMenuCode ๊ฐ€์ ธ๊ฐ€๊ธฐ
		return "redirect:/admin/regItem?subMenuCode=SUB_MENU_002";
	}

 

์ฒจ๋ถ€ํŒŒ์ผ์ด ๋“ฑ๋ก๋  ๊ฒฝ๋กœ ์„ค์ •.

static ํด๋” ๋ฐ‘์— ์ด๋ฏธ์ง€ ์—…๋กœ๋“œํ•  ํด๋” upload ์ƒ์„ฑ

upload ํด๋” ๊ฒฝ๋กœ ์ฐพ์•„๊ฐ€๋Š” ๋ฒ•

ํ”„๋กœ์ ํŠธ - ์˜ค๋ฅธ์ชฝ ๋งˆ์šฐ์Šค - properties ์•„๋ž˜ ์‚ฌ์ง„์˜ ์ฒดํฌ ๋ฒ„ํŠผ ๋ˆ„๋ฅด๋ฉด ํด๋” ๋œธ

ํด๋”์—์„œ upload ํด๋” ์ฐพ์•„๊ฐ€์„œ ๊ฒฝ๋กœ ๋ณต์‚ฌํ•ด์˜ค๋ฉด ๋จ.

์‚ฌ์ง„ ํด๋” ๊ฒฝ๋กœ๋Š” ์›ฌ๋งŒํ•˜๋ฉด ๋ณ€ํ•˜์ง€ ์•Š์Œ > ์ƒ์ˆ˜๋กœ ์คŒ.

์ƒ์ˆ˜๋Š” ํด๋ž˜์Šค ๋”ฐ๋กœ ๋งŒ๋“ค์–ด์„œ ๊ด€๋ฆฌํ•จ.

util ํŒจํ‚ค์ง€ - ConstVariable ํด๋ž˜์Šค ์ƒ์„ฑ

์ฒจ๋ถ€ ํŒŒ์ผ ๊ฒฝ๋กœ ๋„ฃ์–ด์คŒ.

package com.study.shop.util;

public class ConstVariable {
	//์ฒจ๋ถ€ ํŒŒ์ผ ๊ฒฝ๋กœ 
	//์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด public ๊ผญ ๋ถ™์ด๊ณ  ์ „์—ญ๋ณ€์ˆ˜(๊ณต์šฉ)๋กœ static ๋ถ™์ด๊ธฐ
	//ํŒŒ์ผ ์—…๋กœ๋“œ ์œ„์น˜  
	//๋ฐ”๋€Œ๋ฉด ์•ˆ๋˜๋Š” ๊ฐ’์— final ๋ถ™์—ฌ์„œ ์ƒ์ˆ˜๋กœ ๋งŒ๋“ค์–ด์คŒ.
	//์ƒ์ˆ˜๋Š” ๋‹ค๋ฅธ ๋ณ€์ˆ˜์™€ ๊ตฌ๋ถ„์„ ์œ„ํ•ด ๋Œ€๋ฌธ์ž๋กœ ์ž‘์„ฑํ•˜๊ณ  ์ƒ์ˆ˜๋“ค๋ผ๋ฆฌ ํด๋ž˜์Šค๋กœ ๋”ฐ๋กœ ๊ด€๋ฆฌ
																//""์— ๊ฒฝ๋กœ ๋ถ™์—ฌ๋„ฃ์œผ๋ฉด \\ 2๊ฐœ ์ƒ๊น€.
	public static final String UPLOAD_PATH = "D:\\dev\\workspaceSTS\\Shop\\src\\main\\resources\\static\\upload\\";
	
	//ํด๋ž˜์Šค๋ช…์œผ๋กœ ์ ‘๊ทผ > static ๋ณ€์ˆ˜
	//System.out.println(ConstVariable.UPLOAD_PATH);

}

 

 

์ƒํ’ˆ ๋“ฑ๋ก์‹œ ์ฒจ๋ถ€ ํŒŒ์ผ ์—†์œผ๋ฉด ์˜ค๋ฅ˜ 

> ์ฒจ๋ถ€ ํŒŒ์ผ ์žˆ์„ ๋•Œ๋งŒ ํŒŒ์ผ ์—…๋กœ๋“œ ์ฝ”๋“œ ์‹คํ–‰๋˜๊ฒŒ if๋ฌธ์— ๊ฐ์‹ธ์ฃผ๊ธฐ.

@PostMapping("/regItem")			//์ด๋ฏธ์ง€ ๋ฐ›์•„์˜ค๋Š” ๊ฐ์ฒด, ๋ณ€์ˆ˜๋ช…์€ mainImg inputํƒœ๊ทธ์˜ name , subImg๋Š” ๋”ฐ๋กœ ๋„ฃ์–ด์ค˜์•ผํ•จ.
	public String regItem(ItemVO itemVO, MultipartFile mainImg) {
		//---ํŒŒ์ผ ์ฒจ๋ถ€---
		//๋ฉ”์ธ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ
		//์ฒจ๋ถ€ ๋์œผ๋ฉด(true) ํŒŒ์ผ ์—…๋กœ๋“œ ์ฝ”๋“œ ์‹คํ–‰.
		if(!mainImg.isEmpty()) {
			
			//์›๋ณธํŒŒ์ผ๋ช… ๋ฐ›์•„์˜ค๊ธฐ
			String originFileName = mainImg.getOriginalFilename();
			
			//์„œ๋ฒ„์— ์˜ฌ๋ผ๊ฐˆ(์ฒจ๋ถ€๋ ) ํŒŒ์ผ๋ช… ์ƒ์„ฑ(ํŒŒ์ผ๋ช…์ด ์ค‘๋ณต๋˜์ง€ ์•Š๊ฒŒ) 
			//UUID : ์ค‘๋ณตX ๋žœ๋คํ•œ ๋ฌธ์ž์—ด์„ ์ƒ์„ฑ 
			String uuid = UUID.randomUUID().toString();
			
			//์›๋ณธํŒŒ์ผ๋ช…์ด abc.jpg > ๋žœ๋ค๋ฌธ์ž์—ด.jpg์˜ ํ˜•์‹์œผ๋กœ ์ฒจ๋ถ€๋  ํŒŒ์ผ๋ช…์„ ์ƒ์„ฑ
			//์ฒจ๋ถ€๋œ ํŒŒ์ผ์˜ ํ™•์žฅ์ž ์ถ”์ถœ
			String extension = originFileName.substring(originFileName.lastIndexOf("."));  //๋งˆ์ง€๋ง‰ "."๋ฌธ์ž์—์„œ ๋๊นŒ์ง€
			
			//์„œ๋ฒ„์— ์˜ฌ๋ฆด(์ฒจ๋ถ€๋ ) ํŒŒ์ผ๋ช…
			String attachedFileName = uuid + extension;
			
			System.out.println("์›๋ณธํŒŒ์ผ๋ช… : " + originFileName);
			System.out.println("์ฒจ๋ถ€๋  ํŒŒ์ผ๋ช… : " + attachedFileName);
			
			//ํŒŒ์ผ ์—…๋กœ๋“œ			
			try {                    //๊ฒฝ๋กœ\\์ด๋ฏธ์ง€๋ช….ํ™•์žฅ์ž๋กœ ๋‚˜์™€์•ผ ํ•จ. \\ํ•„์š” > ๊ฒฝ๋กœ ๋ณ€์ˆ˜ ๋งˆ์ง€๋ง‰์— \\์ถ”๊ฐ€
				File file = new File(ConstVariable.UPLOAD_PATH + attachedFileName);
				mainImg.transferTo(file);
			} catch (Exception e) {
				e.printStackTrace();
			}		
			
		}
			
		//๋“ฑ๋ก๋  ์ƒํ’ˆ์ฝ”๋“œ ์กฐํšŒ
		String itemCode = adminService.getNextItemCode();
		itemVO.setItemCode(itemCode);
		
		//์ƒํ’ˆ ๋“ฑ๋ก ์ฟผ๋ฆฌ
		adminService.insertItem(itemVO);
					//์ƒํ’ˆ ๋“ฑ๋ก ํ›„์— ์„œ๋ธŒ ๋ฉ”๋‰ด์— ์ƒ‰ ์ฃผ๊ธฐ ์œ„ํ•ด subMenuCode ๊ฐ€์ ธ๊ฐ€๊ธฐ
		return "redirect:/admin/regItem?subMenuCode=SUB_MENU_002";
	}

 

ํ˜„์žฌ mainImg๋งŒ ๋ฐ›์•„์˜ด.

์ƒํ’ˆ ๋“ฑ๋ก ๋งค๊ฐœ๋ณ€์ˆ˜์— subImg๋„ ์ถ”๊ฐ€

subImg๋Š” ์ฒจ๋ถ€ํŒŒ์ผ์ด ์—ฌ๋Ÿฌ๊ฐœ ๋“ค์–ด์˜ฌ ์ˆ˜ ์žˆ์Œ.

MultipartFile์€ ํŒŒ์ผ ํ•˜๋‚˜๋งŒ ๋“ค์–ด์˜ฌ ์ˆ˜ ์žˆ์–ด์„œ ๋ฐฐ์—ด์ธ MultipartFile[]๋กœ ๋งŒ๋“ค์–ด์ค˜์•ผํ•จ.

๋งค๊ฐœ๋ณ€์ˆ˜ ์ถ”๊ฐ€ ํ›„ subImg ์ฒจ๋ถ€ ํŒŒ์ผ ์—…๋กœ๋“œ ์ฝ”๋“œ๋„ ์ž‘์„ฑ.

๋ฐฐ์—ด์ด๊ธฐ ๋•Œ๋ฌธ์— for๋ฌธ์œผ๋กœ subImg ํ•˜๋‚˜์”ฉ ๋นผ์ฃผ๋ฉด ๋จ.

//์„œ๋ธŒ ์ด๋ฏธ์ง€๋“ค ์—…๋กœ๋“œ (subImg๋Š” MultipartFile[]์ž„. ๊ฑฐ๊ธฐ์„œ img ํ•˜๋‚˜ ๋นผ๋ฉด ์ž๋ฃŒํ˜• MultipartFile๋กœ ๋ฐ›์•„์•ผ ํ•จ.
		for(MultipartFile img : subImg) {
			if(!img.isEmpty()) {
				//์›๋ณธ ํŒŒ์ผ๋ช…
				String originFileName = img.getOriginalFilename();
				
				//์„œ๋ฒ„์— ์˜ฌ๋ฆด(์ฒจ๋ถ€๋ ) ํŒŒ์ผ๋ช… ์ƒ์„ฑ
				String uuid = UUID.randomUUID().toString();
				String extension = originFileName.substring(originFileName.lastIndexOf("."));
				String attachedFileName = uuid + extension;
				
				try {
					File file = new File(ConstVariable.UPLOAD_PATH + attachedFileName);
					img.transferTo(file); //์‹ค์ œ ์—…๋กœ๋“œ.
				} catch (Exception e) {
					e.printStackTrace();
				}	
			}
		}

 

์œ„์ฒ˜๋Ÿผ Controller์— ํŒŒ์ผ ์ฒจ๋ถ€ ์ฝ”๋“œ ์ž‘์„ฑํ•ด๋„ ๋จ. ๊ทธ๋Ÿฌ๋‚˜ ๋ณด๊ธฐ ๋ณต์žกํ•จ.

** ์‚ฌ์ง„ ์—…๋กœ๋“œ ํ•  ๋•Œ๋งˆ๋‹ค ์ฝ”๋“œ ์ž‘์„ฑ ์—†์ด ๋ฉ”์†Œ๋“œ๋งŒ ๋ถˆ๋Ÿฌ์™€์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ UploadUtil ํด๋ž˜์Šค ์ƒ์„ฑ.

package com.study.shop.util;

import java.io.File;
import java.util.UUID;

import org.springframework.web.multipart.MultipartFile;

public class UploadUtil {
	//static : ์ „์—ญ๋ณ€์ˆ˜, ๊ฐ์ฒด ์ƒ์„ฑ์—†์ด ํด๋ž˜์Šค๋ช….๋ฉ”์†Œ๋“œ๋กœ ํ˜ธ์ถœ ๊ฐ€๋Šฅ!
	
	//๋‹จ์ผ ํŒŒ์ผ ์—…๋กœ๋“œ ๋ฉ”์†Œ๋“œ
	public static void uploadFile(MultipartFile img) {
		//์ฒจ๋ถ€ ๋์œผ๋ฉด(true) ํŒŒ์ผ ์—…๋กœ๋“œ ์ฝ”๋“œ ์‹คํ–‰.
		if (!img.isEmpty()) {

			// ์›๋ณธํŒŒ์ผ๋ช… ๋ฐ›์•„์˜ค๊ธฐ
			String originFileName = img.getOriginalFilename();

			// ์„œ๋ฒ„์— ์˜ฌ๋ผ๊ฐˆ(์ฒจ๋ถ€๋ ) ํŒŒ์ผ๋ช… ์ƒ์„ฑ(ํŒŒ์ผ๋ช…์ด ์ค‘๋ณต๋˜์ง€ ์•Š๊ฒŒ)
			// UUID : ์ค‘๋ณตX ๋žœ๋คํ•œ ๋ฌธ์ž์—ด์„ ์ƒ์„ฑ
			String uuid = UUID.randomUUID().toString();

			// ์›๋ณธํŒŒ์ผ๋ช…์ด abc.jpg > ๋žœ๋ค๋ฌธ์ž์—ด.jpg์˜ ํ˜•์‹์œผ๋กœ ์ฒจ๋ถ€๋  ํŒŒ์ผ๋ช…์„ ์ƒ์„ฑ
			// ์ฒจ๋ถ€๋œ ํŒŒ์ผ์˜ ํ™•์žฅ์ž ์ถ”์ถœ
			String extension = originFileName.substring(originFileName.lastIndexOf(".")); // ๋งˆ์ง€๋ง‰ "."๋ฌธ์ž์—์„œ ๋๊นŒ์ง€

			// ์„œ๋ฒ„์— ์˜ฌ๋ฆด(์ฒจ๋ถ€๋ ) ํŒŒ์ผ๋ช…
			String attachedFileName = uuid + extension;

			System.out.println("์›๋ณธํŒŒ์ผ๋ช… : " + originFileName);
			System.out.println("์ฒจ๋ถ€๋  ํŒŒ์ผ๋ช… : " + attachedFileName);

			// ํŒŒ์ผ ์—…๋กœ๋“œ
			try { // ๊ฒฝ๋กœ\\์ด๋ฏธ์ง€๋ช….ํ™•์žฅ์ž๋กœ ๋‚˜์™€์•ผ ํ•จ. \\ํ•„์š” > ๊ฒฝ๋กœ ๋ณ€์ˆ˜ ๋งˆ์ง€๋ง‰์— \\์ถ”๊ฐ€
				File file = new File(ConstVariable.UPLOAD_PATH + attachedFileName);
				img.transferTo(file);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
			
	//๋‹ค์ค‘ ํŒŒ์ผ ์—…๋กœ๋“œ ๋ฉ”์†Œ๋“œ
	public static void multiFileUpload(MultipartFile[] imgs) {
		for(MultipartFile img : imgs) {
			uploadFile(img); //๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ฒจ๋ถ€ํŒŒ์ผ ํ•˜๋‚˜ ๋“ค์–ด์˜ฌ ๋•Œ ์—…๋กœ๋“œ ์‹œ์ผœ์ฃผ๋Š” ๋ฉ”์†Œ๋“œ
		}
	}
}

์ƒํ’ˆ ๋“ฑ๋ก controller์—์„œ ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœํ•˜๋ฉด ๋จ.

	//์ƒํ’ˆ ๋“ฑ๋ก
	@PostMapping("/regItem")			//์ด๋ฏธ์ง€ ๋ฐ›์•„์˜ค๋Š” ๊ฐ์ฒด, ๋ณ€์ˆ˜๋ช…์€ mainImg inputํƒœ๊ทธ์˜ name , subImg๋Š” ๋”ฐ๋กœ ๋„ฃ์–ด์ค˜์•ผํ•จ.
	public String regItem(ItemVO itemVO, MultipartFile mainImg, MultipartFile[] subImg) {
		//---ํŒŒ์ผ ์ฒจ๋ถ€---
		//๋ฉ”์ธ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ
		UploadUtil.uploadFile(mainImg);
		
		//์„œ๋ธŒ ์ด๋ฏธ์ง€๋“ค ์—…๋กœ๋“œ
		UploadUtil.multiFileUpload(subImg);
			
		//๋“ฑ๋ก๋  ์ƒํ’ˆ์ฝ”๋“œ ์กฐํšŒ
		//String itemCode = adminService.getNextItemCode();
		//itemVO.setItemCode(itemCode);
		
		//์ƒํ’ˆ ๋“ฑ๋ก ์ฟผ๋ฆฌ
		//adminService.insertItem(itemVO);
					//์ƒํ’ˆ ๋“ฑ๋ก ํ›„์— ์„œ๋ธŒ ๋ฉ”๋‰ด์— ์ƒ‰ ์ฃผ๊ธฐ ์œ„ํ•ด subMenuCode ๊ฐ€์ ธ๊ฐ€๊ธฐ
		return "redirect:/admin/regItem?subMenuCode=SUB_MENU_002";
	}

 

์ฒจ๋ถ€ํŒŒ์ผ ์šฉ๋Ÿ‰ ์„ค์ •.

application.properties์— ์•„๋ž˜ ์ฝ”๋“œ ์ถ”๊ฐ€

#์—…๋กœ๋“œ์šฉ๋Ÿ‰ ์„ค์ •(๊ธฐ๋ณธ ๊ฐ’ : ์•ฝ 1MB)
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB

 

 

ํ˜„์žฌ๊นŒ์ง€ ์ƒํ’ˆ ์ด๋ฏธ์ง€ spring์— ์—…๋กœ๋“œ๋Š” ๋œ ์ƒํƒœ.

์ƒํ’ˆ ์ด๋ฏธ์ง€ DB insert ์ž‘์—… ํ•„์š”.

**์ฃผ์˜

์ƒํ’ˆ 1๊ฐœ insert ๋  ๋•Œ ์ด๋ฏธ์ง€๋Š” ์—ฌ๋Ÿฌ๊ฐœ insert ๋จ > ๋‹ค์ค‘ insert๋ฌธ ์‚ฌ์šฉํ•ด์•ผ ํ•จ.

UNION ALL์„ ๋„ฃ์–ด์„œ SELECT ์—ฌ๋Ÿฌ๋ฒˆ

์ด๋ฏธ์ง€ INSERT ์ฟผ๋ฆฌ ์ž‘์„ฑ

	<!-- ์ƒํ’ˆ ์ด๋ฏธ์ง€ ๋“ฑ๋ก -->
	<insert id="insertImgs">
		INSERT INTO ITEM_IMG (
			IMG_CODE
			, ORIGIN_FILE_NAME
			, ATTACHED_FILE_NAME
			, IS_MAIN
			, ITEM_CODE
		)								<!-- imgVO -->
		<foreach collection="imgList" item="img" separator="UNION ALL" index="i">
			SELECT (SELECT 'IMG_'||LPAD(NVL(MAX(TO_NUMBER(SUBSTR(IMG_CODE, 5))), 0) + 1 + #{i}, 3, '0') 
       				FROM ITEM_IMG)   		<!-- db์— IMG_002๊นŒ์ง€ ์žˆ๋‹ค๋ฉด ์ด๋ฏธ์ง€ insert ์‹œ 003, ๊ทธ๋Ÿฌ๋‚˜ ํ•œ๋ฒˆ์— ์—ฌ๋Ÿฌ๊ฐœ ์ฒจ๋ถ€ ํ•˜๋ฉด 003์œผ๋กœ ์ค‘๋ณต ๋จ -->
				, #{img.originFileName}		<!-- db IMG_CODE ์ตœ๋Œ€๊ฐ’ + 1 ๊ฐ’์— ๋˜ ์ฒจ๋ถ€ ์ˆ˜๋งŒํผ +1์”ฉ ์ฆ๊ฐ€ํ•ด์•ผ ํ•จ for๋ฌธ์˜ index ํ™œ์šฉํ•˜์—ฌ i๊ฐ’ ๋”ํ•ด์คŒ -->
				, #{img.attachedFileName}
				, #{img.isMain}
				, #{itemCode}
			FROM DUAL
		</foreach>
	</insert>

ImgVO๋Š” ์ฒจ๋ถ€๋œ ํŒŒ์ผ ํ•˜๋‚˜์˜ ์ •๋ณด๋ฅผ ๋‹ค ๋‹ด์Œ.

์ฒจ๋ถ€ํŒŒ์ผ ์ˆ˜๋งŒํผ ImgVO๊ฐ€ ํ•„์š”ํ•จ.

์ƒํ’ˆ ๋“ฑ๋ก ์‹œ ์—ฌ๋Ÿฌ๊ฐœ์˜ ์ฒจ๋ถ€ ํŒŒ์ผ์„ ๋‹ค ๋ฐ›์•„์˜ค๋ ค๋ฉด list๋กœ ๋ฐ์ดํ„ฐ ๋ฐ›์•„์™€์•ผ ํ•จ.

> ์ฒจ๋ถ€ํŒŒ์ผ์˜ ์ˆ˜๋งŒํผ ๋ฐ˜๋ณต ๋Œ๋ฉด์„œ ImgVO์ธ ๊ฐ๊ฐ ํ•˜๋‚˜์˜ ์ฒจ๋ถ€ ํŒŒ์ผ ์ •๋ณด ๋นผ์•ผ ํ•จ.

์ฟผ๋ฆฌ ๋นˆ๊ฐ’์„ ์ฑ„์šฐ๊ธฐ ์œ„ํ•ด controller์—์„œ ์‹ค์ œ ์ฒจ๋ถ€๋œ ImgVO ์ •๋ณด๊ฐ€ ํ•„์š”ํ•œ ์ƒํƒœ.

 

์ฒจ๋ถ€ํŒŒ์ผ ๋“ฑ๋ก ํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ imgVO ์ •๋ณด๋ฅผ controller์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•จ.

๋‹จ์ผ ํŒŒ์ผ ์—…๋กœ๋“œ ๋ฉ”์†Œ๋“œ ์ˆ˜์ •.

ImgVO ์ƒ์„ฑํ•˜์—ฌ ์ฒจ๋ถ€ํŒŒ์ผ ๋“ฑ๋ก ํ›„ imgVO(์ด๋ฏธ์ง€ ์ •๋ณด)๋ฅผ controller์— ๋ฆฌํ„ด์‹œ์ผœ์คŒ.

public class UploadUtil {
	//static : ์ „์—ญ๋ณ€์ˆ˜, ๊ฐ์ฒด ์ƒ์„ฑ์—†์ด ํด๋ž˜์Šค๋ช….๋ฉ”์†Œ๋“œ๋กœ ํ˜ธ์ถœ ๊ฐ€๋Šฅ!
	
	//๋‹จ์ผ ํŒŒ์ผ ์—…๋กœ๋“œ ๋ฉ”์†Œ๋“œ
	public static ImgVO uploadFile(MultipartFile img) {
		//imgVO ๋ฆฌํ„ดํ•˜๊ธฐ ์œ„ํ•ด ์„ ์–ธ(controller์—์„œ ์ฒจ๋ถ€๋œ ํŒŒ์ผ ์ •๋ณด ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•จ)
		ImgVO imgVO = null;
		
		//์ฒจ๋ถ€ ๋์œผ๋ฉด(true) ํŒŒ์ผ ์—…๋กœ๋“œ ์ฝ”๋“œ ์‹คํ–‰.
		if (!img.isEmpty()) {
			imgVO = new ImgVO(); //์ฒจ๋ถ€ํŒŒ์ผ์ด ์žˆ์œผ๋ฉด imgVO ๊ฐ์ฒด ์ƒ์„ฑ

			// ์›๋ณธํŒŒ์ผ๋ช… ๋ฐ›์•„์˜ค๊ธฐ
			String originFileName = img.getOriginalFilename();

			// ์„œ๋ฒ„์— ์˜ฌ๋ผ๊ฐˆ(์ฒจ๋ถ€๋ ) ํŒŒ์ผ๋ช… ์ƒ์„ฑ(ํŒŒ์ผ๋ช…์ด ์ค‘๋ณต๋˜์ง€ ์•Š๊ฒŒ)
			// UUID : ์ค‘๋ณตX ๋žœ๋คํ•œ ๋ฌธ์ž์—ด์„ ์ƒ์„ฑ
			String uuid = UUID.randomUUID().toString();

			// ์›๋ณธํŒŒ์ผ๋ช…์ด abc.jpg > ๋žœ๋ค๋ฌธ์ž์—ด.jpg์˜ ํ˜•์‹์œผ๋กœ ์ฒจ๋ถ€๋  ํŒŒ์ผ๋ช…์„ ์ƒ์„ฑ
			// ์ฒจ๋ถ€๋œ ํŒŒ์ผ์˜ ํ™•์žฅ์ž ์ถ”์ถœ
			String extension = originFileName.substring(originFileName.lastIndexOf(".")); // ๋งˆ์ง€๋ง‰ "."๋ฌธ์ž์—์„œ ๋๊นŒ์ง€

			// ์„œ๋ฒ„์— ์˜ฌ๋ฆด(์ฒจ๋ถ€๋ ) ํŒŒ์ผ๋ช…
			String attachedFileName = uuid + extension;

			System.out.println("์›๋ณธํŒŒ์ผ๋ช… : " + originFileName);
			System.out.println("์ฒจ๋ถ€๋  ํŒŒ์ผ๋ช… : " + attachedFileName);
			
			// ํŒŒ์ผ ์—…๋กœ๋“œ
			try { // ๊ฒฝ๋กœ\\์ด๋ฏธ์ง€๋ช….ํ™•์žฅ์ž๋กœ ๋‚˜์™€์•ผ ํ•จ. \\ํ•„์š” > ๊ฒฝ๋กœ ๋ณ€์ˆ˜ ๋งˆ์ง€๋ง‰์— \\์ถ”๊ฐ€
				File file = new File(ConstVariable.UPLOAD_PATH + attachedFileName);
				img.transferTo(file); //์‹ค์ œ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ
				
				//imgVO์— ์ด๋ฏธ์ง€ ์ •๋ณด ์ €์žฅ
				imgVO.setOriginFileName(originFileName);
				imgVO.setAttachedFileName(attachedFileName);
				imgVO.setIsMain("Y"); //๋ฉ”์ธ ์ด๋ฏธ์ง€ : Y **subImg ๋„ฃ์„ ๋•Œ๋„ ๋ฉ”์†Œ๋“œ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— subImg์—์„œ๋Š” N๋กœ ๋ฐ”๊ฟ”์ค˜์•ผํ•จ
				
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return imgVO; //์ด๋ฏธ์ง€ ์ •๋ณด ๋ฆฌํ„ด
	}

๋‹ค์ค‘ ํŒŒ์ผ ์—…๋กœ๋“œ ๋ฉ”์†Œ๋“œ ์ˆ˜์ •.

์ฒจ๋ถ€๋œ ์—ฌ๋Ÿฌ๊ฐœ์˜ ์ด๋ฏธ์ง€ ์ •๋ณด๋ฅผ ๋‹ด์„ ์ˆ˜ ์žˆ๋Š” list(ํ†ต)์„ ์ƒ์„ฑํ•˜์—ฌ

for๋ฌธ ๋Œ ๋•Œ ํ•˜๋‚˜์˜ ์ด๋ฏธ์ง€ ์ •๋ณด๋ฅผ ๋ฝ‘์•„ ๊ทธ ๋ฐ์ดํ„ฐ๋ฅผ imgVO vo์— ๋‹ด์•„์ฃผ๊ณ 

vo๋ฅผ ์ฒจ๋ถ€๋œ ์ด๋ฏธ์ง€ ์ •๋ณด๋ฅผ ๋‹ค ๋‹ด์„ ์ˆ˜ ์žˆ๋Š” list์— ๋ฐ์ดํ„ฐ ์„ธํŒ…ํ•˜์—ฌ controller๋กœ ๋ฆฌํ„ด.

	//๋‹ค์ค‘ ํŒŒ์ผ ์—…๋กœ๋“œ ๋ฉ”์†Œ๋“œ
	public static List<ImgVO> multiFileUpload(MultipartFile[] imgs) {
		//์ฒจ๋ถ€๋œ ํŒŒ์ผ ์ •๋ณด๋ฅผ ๋‹ค ๋‹ด์„ ์ˆ˜ ์žˆ๋Š” ํ†ต
		List<ImgVO> result = new ArrayList<>();
		
		for(MultipartFile img : imgs) {
			ImgVO vo = uploadFile(img); //๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ฒจ๋ถ€ํŒŒ์ผ ํ•˜๋‚˜ ๋“ค์–ด์˜ฌ ๋•Œ ์—…๋กœ๋“œ ์‹œ์ผœ์ฃผ๋Š” ๋ฉ”์†Œ๋“œ
			vo.setIsMain("N");
			result.add(vo); 
		}
		return result;
	}

controller๋กœ ๋Œ์•„์™€์„œ return๋œ ์ด๋ฏธ์ง€ ์ •๋ณด๋“ค ๋ฐ›์œผ๋ฉด ๋จ.

return๋œ List<ImgVO>๋Š” ์ฒจ๋ถ€๋œ ๋ชจ๋“  ์„œ๋ธŒ ์ด๋ฏธ์ง€๋“ค์˜ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ์Œ.

List<ImgVO> ์— ์ฒจ๋ถ€๋œ ๋ฉ”์ธ ์ด๋ฏธ์ง€ ์ •๋ณด๋ฅผ ์ถ”๊ฐ€๋กœ ๋ฐ์ดํ„ฐ ์„ธํŒ…ํ•˜๋ฉด List<ImgVO> imgList๋Š” ์ฒจ๋ถ€๋œ ๋ชจ๋“  ์ด๋ฏธ์ง€ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ฒŒ ๋จ.

ํ˜„์žฌ๊นŒ์ง€ controller์—์„œ ์ฟผ๋ฆฌ ๋นˆ ๊ฐ’ ์ค‘ ์ด๋ฏธ์ง€ ์ •๋ณด๋Š” imgList์— ์„ธํŒ… ๋˜์—ˆ๊ณ , itemCode๋งŒ ์„ธํŒ…ํ•˜๋ฉด ๋จ.

itemCode๊ฐ’์€ ์ด์ „์— ์ƒ์„ฑํ•œ ๋“ฑ๋ก๋  ์ƒํ’ˆ์ฝ”๋“œ ์กฐํšŒ ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์„ธํŒ… ๊ฐ€๋Šฅ.

imgList๋ฅผ for๋ฌธ ๋Œ๋ ค์„œ ํ•˜๋‚˜์˜ img ๋ฐ์ดํ„ฐ ๋นผ์„œ ๊ฐ๊ฐ itemCode ๊ฐ’ ์„ธํŒ….

imgList์—๋Š” ์ฒจ๋ถ€๋œ ๋ชจ๋“  ์ด๋ฏธ์ง€ ์ •๋ณด๊ฐ€ ๋‹ด๊ฒจ์žˆ์Œ.

//์ƒํ’ˆ ๋“ฑ๋ก
	@PostMapping("/regItem")			//์ด๋ฏธ์ง€ ๋ฐ›์•„์˜ค๋Š” ๊ฐ์ฒด, ๋ณ€์ˆ˜๋ช…์€ mainImg inputํƒœ๊ทธ์˜ name , subImg๋Š” ๋”ฐ๋กœ ๋„ฃ์–ด์ค˜์•ผํ•จ.
	public String regItem(ItemVO itemVO, MultipartFile mainImg, MultipartFile[] subImg) {
		//---ํŒŒ์ผ ์ฒจ๋ถ€---
		//๋ฉ”์ธ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ
		ImgVO attachedImgVO = UploadUtil.uploadFile(mainImg);
		//imgVO์— ์ฒจ๋ถ€ ์ด๋ฏธ์ง€ ์ •๋ณด ์ €์žฅ๋˜์–ด์žˆ์Œ. ์ฟผ๋ฆฌ ๋นˆ๊ฐ’ ์ฑ„์šฐ๊ธฐ ์œ„ํ•จ.
		
		//์„œ๋ธŒ ์ด๋ฏธ์ง€๋“ค ์—…๋กœ๋“œ
		List<ImgVO> attachedImgList = UploadUtil.multiFileUpload(subImg);
		
		//---์ƒํ’ˆ ์ •๋ณด DB ๋“ฑ๋ก---
			
		//๋“ฑ๋ก๋  ์ƒํ’ˆ์ฝ”๋“œ ์กฐํšŒ
		String itemCode = adminService.getNextItemCode();
		itemVO.setItemCode(itemCode);
		
		//---์ƒํ’ˆ ์ด๋ฏธ์ง€ DB ๋“ฑ๋ก---
		//์ƒํ’ˆ ์ด๋ฏธ์ง€ ๋“ฑ๋ก ์ฟผ๋ฆฌ ์‹คํ–‰ ์‹œ ๋ชจ๋“  ๋นˆ ๊ฐ’์„ ์ฑ„์›Œ์ค„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง„ ๋ฆฌ์ŠคํŠธ (imgCode, itemCode ์ œ์™ธ)
		List<ImgVO> imgList = attachedImgList; //๋‹ค์ค‘์œผ๋กœ ์ฒจ๋ถ€๋œ ํŒŒ์ผ ๋ฆฌ์ŠคํŠธ(์„œ๋ธŒ ์ด๋ฏธ์ง€)
		imgList.add(attachedImgVO); //๋ฉ”์ธ ์ด๋ฏธ์ง€ ์ฒจ๋ถ€ ์ •๋ณด๋ฅผ ์ถ”๊ฐ€๋กœ ๋ฆฌ์ŠคํŠธ์— ๋„ฃ์–ด์คŒ.
		
		//itemCode ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€
		for(ImgVO img : imgList) {
			img.setImgCode(itemCode); //๋“ฑ๋ก๋  ์ƒํ’ˆ ์ฝ”๋“œ ์กฐํšŒํ•œ ๊ฒƒ์œผ๋กœ ์„ธํŒ….
		}
					//์ƒํ’ˆ ๋“ฑ๋ก ํ›„์— ์„œ๋ธŒ ๋ฉ”๋‰ด์— ์ƒ‰ ์ฃผ๊ธฐ ์œ„ํ•ด subMenuCode ๊ฐ€์ ธ๊ฐ€๊ธฐ
		return "redirect:/admin/regItem?subMenuCode=SUB_MENU_002";
	}

 

์ƒํ’ˆ ํ•˜๋‚˜๋Š” ์ฒจ๋ถ€ํ•œ ์—ฌ๋Ÿฌ๊ฐœ์˜ ์ด๋ฏธ์ง€(๋ฉ”์ธ, ์„œ๋ธŒ ์ด๋ฏธ์ง€) ์ •๋ณด๋ฅผ ๋‹ค ๊ฐ€์ง„๋‹ค.

์ฆ‰, itemVO๋ฅผ ์ƒํ’ˆ์ด๋ฏธ์ง€ ๋“ฑ๋ก ํ•  ๋•Œ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ •๋ฆฌํ•˜์ž๋ฉด, ์ƒํ’ˆ ๋“ฑ๋ก controller์—์„œ itemVO ๋ฐ์ดํ„ฐ๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋„˜๊ฒจ์„œ ์ƒํ’ˆ์„ ๋“ฑ๋กํ•˜๋Š”๋ฐ

์ƒํ’ˆ ์ •๋ณด ๋“ฑ๋ก, ์ด๋ฏธ์ง€ ๋“ฑ๋ก์€ 1๊ฐœ์˜ ์ƒํ’ˆ์„ ๋“ฑ๋ก์„ ํ•  ๋•Œ ๊ฐ™์ด ์“ฐ์ด๋Š” ๊ธฐ๋Šฅ์ด๊ธฐ ๋•Œ๋ฌธ์— imgList๋ฅผ itemVO์— ์„ธํŒ…ํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๊ฐ™์ด ๋„˜๊ฒจ์คŒ.

๋ฐ์ดํ„ฐ ์„ธํŒ…์„ ์œ„ํ•ด itemVO์— List<ImgVO> ๋ณ€์ˆ˜ ์ถ”๊ฐ€.

private List<ImgVO> imgList; //์ƒํ’ˆ ํ•˜๋‚˜๋Š” imgVO๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ ๊ฐ€์ง€๊ณ  ์žˆ์Œ.

itemVO์— imgList ๋ฐ์ดํ„ฐ ์„ธํŒ….

//itemVO์— ์ƒํ’ˆ ๋“ฑ๋กํ•  ๋•Œ ํ•„์š”ํ•œ ๋ชจ๋“  ์ด๋ฏธ์ง€ ์ •๋ณด๋ฅผ ์„ธํŒ…
itemVO.setImgList(imgList);

 

์ƒํ’ˆ, ์ด๋ฏธ์ง€ ๋“ฑ๋ก ํŠธ๋žœ์ ์…˜ ์ฒ˜๋ฆฌ

์ƒํ’ˆ ์ •๋ณด ๋“ฑ๋ก , ์ด๋ฏธ์ง€ ๋“ฑ๋ก์€ 1๊ฐœ์˜ ์ƒํ’ˆ ๋“ฑ๋ก์‹œ ์ž‘๋™ํ•˜๋Š” ๊ธฐ๋Šฅ์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•˜๋‚˜๋กœ ๋ฌถ์–ด์ฃผ๋Š” ๊ฒŒ ์ข‹์Œ.

๋‘˜ ์ค‘ ํ•˜๋‚˜๋ผ๋„ ์—…๋กœ๋“œ ์‹คํŒจ ์‹œ ๋“ฑ๋ก ๊ธฐ๋Šฅ ์ž‘๋™ ์•ˆ ํ•˜๊ฒŒ ์ฒ˜๋ฆฌ.

AdminService์˜ ์ด๋ฏธ์ง€ ์ •๋ณด ๋ฉ”์†Œ๋“œ ์ƒ์„ฑํ•œ ๊ฒƒ ์‚ญ์ œํ•˜๊ณ 

AdminServiceImpl์—์„œ ์ƒํ’ˆ ์ •๋ณด ๋“ฑ๋ก ๋ฉ”์†Œ๋“œ ๊ตฌํ˜„ํ•  ๋•Œ ์ด๋ฏธ์ง€ ๋“ฑ๋ก ๋ฉ”์†Œ๋“œ ๊ฐ™์ด ๊ตฌํ˜„.

ํŠธ๋žœ์ ์…˜ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ์•„๋ž˜ ์–ด๋…ธํ…Œ์ด์…˜ ๋‹ฌ์•„์ฃผ๋ฉด ๋จ.

@Transactional(rollbackFor = Exception.class) 

	//์ƒํ’ˆ ๋“ฑ๋ก   @Transactional : ํ•ด๋‹น ๋ฉ”์†Œ๋“œ ๋‚ด์˜ ์ฟผ๋ฆฌ ์‹คํ–‰์€ ํŠธ๋žœ์ ์…˜ ์ฒ˜๋ฆฌ 
					//rollbackFor : ์–ธ์ œ ๋กค๋ฐฑ? (์–ด๋–ค ์˜ค๋ฅ˜๋ผ๋„ ๋ฐœ์ƒํ•˜๋ฉด ๋กค๋ฐฑ)
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void insertItem(ItemVO itemVO) {
		sqlSession.insert("adminMapper.insertItem", itemVO); //์ƒํ’ˆ ๋“ฑ๋ก
		sqlSession.insert("adminMapper.insertImgs", itemVO); //์ด๋ฏธ์ง€ ๋“ฑ๋ก
		
	}

์ƒํ’ˆ ๋“ฑ๋ก controller๋กœ ์™€์„œ ๋งจ ๋งˆ์ง€๋ง‰์— ์ƒํ’ˆ ๋“ฑ๋ก ์ฟผ๋ฆฌ ์‹คํ–‰์‹œ์ผœ์ฃผ๋ฉด ์ƒํ’ˆ ๋“ฑ๋ก ๊ธฐ๋Šฅ ์™„๋ฃŒ.

	//์ƒํ’ˆ ๋“ฑ๋ก
	@PostMapping("/regItem")			//์ด๋ฏธ์ง€ ๋ฐ›์•„์˜ค๋Š” ๊ฐ์ฒด, ๋ณ€์ˆ˜๋ช…์€ mainImg inputํƒœ๊ทธ์˜ name , subImg๋Š” ๋”ฐ๋กœ ๋„ฃ์–ด์ค˜์•ผํ•จ.
	public String regItem(ItemVO itemVO, MultipartFile mainImg, MultipartFile[] subImg) {
		//---ํŒŒ์ผ ์ฒจ๋ถ€---
		//๋ฉ”์ธ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ
		ImgVO attachedImgVO = UploadUtil.uploadFile(mainImg);
		//imgVO์— ์ฒจ๋ถ€ ์ด๋ฏธ์ง€ ์ •๋ณด ์ €์žฅ๋˜์–ด์žˆ์Œ. ์ฟผ๋ฆฌ ๋นˆ๊ฐ’ ์ฑ„์šฐ๊ธฐ ์œ„ํ•จ.
		
		//์„œ๋ธŒ ์ด๋ฏธ์ง€๋“ค ์—…๋กœ๋“œ
		List<ImgVO> attachedImgList = UploadUtil.multiFileUpload(subImg);
		
		//---์ƒํ’ˆ ์ •๋ณด DB ๋“ฑ๋ก---
			
		//๋“ฑ๋ก๋  ์ƒํ’ˆ์ฝ”๋“œ ์กฐํšŒ
		String itemCode = adminService.getNextItemCode();
		itemVO.setItemCode(itemCode);
		
		//---์ƒํ’ˆ ์ด๋ฏธ์ง€ DB ๋“ฑ๋ก---
		//์ƒํ’ˆ ์ด๋ฏธ์ง€ ๋“ฑ๋ก ์ฟผ๋ฆฌ ์‹คํ–‰ ์‹œ ๋ชจ๋“  ๋นˆ ๊ฐ’์„ ์ฑ„์›Œ์ค„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง„ ๋ฆฌ์ŠคํŠธ (imgCode, itemCode ์ œ์™ธ)
		List<ImgVO> imgList = attachedImgList; //๋‹ค์ค‘์œผ๋กœ ์ฒจ๋ถ€๋œ ํŒŒ์ผ ๋ฆฌ์ŠคํŠธ(์„œ๋ธŒ ์ด๋ฏธ์ง€)
		imgList.add(attachedImgVO); //๋ฉ”์ธ ์ด๋ฏธ์ง€ ์ฒจ๋ถ€ ์ •๋ณด๋ฅผ ์ถ”๊ฐ€๋กœ ๋ฆฌ์ŠคํŠธ์— ๋„ฃ์–ด์คŒ.
		
		//itemCode ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€
		for(ImgVO img : imgList) {
			img.setImgCode(itemCode); //๋“ฑ๋ก๋  ์ƒํ’ˆ ์ฝ”๋“œ ์กฐํšŒํ•œ ๊ฒƒ์œผ๋กœ ์„ธํŒ….
			
		}
		//itemVO์— ์ƒํ’ˆ ๋“ฑ๋กํ•  ๋•Œ ํ•„์š”ํ•œ ๋ชจ๋“  ์ด๋ฏธ์ง€ ์ •๋ณด๋ฅผ ์„ธํŒ…
		itemVO.setImgList(imgList);
		
		//์ƒํ’ˆ ๋“ฑ๋ก ์ฟผ๋ฆฌ(์ด๋ฏธ์ง€ ๊ฐ™์ด ๋“ฑ๋ก)
		adminService.insertItem(itemVO);
						//์ƒํ’ˆ ๋“ฑ๋ก ํ›„์— ์„œ๋ธŒ ๋ฉ”๋‰ด์— ์ƒ‰ ์ฃผ๊ธฐ ์œ„ํ•ด subMenuCode ๊ฐ€์ ธ๊ฐ€๊ธฐ
		return "redirect:/admin/regItem?subMenuCode=SUB_MENU_002";
	}