Spring Boot(JSP,Mybatis)

상품 등록

작성자
vita
작성일
2023-11-19 23:13
조회
96

상품 등록

상품 등록의 전반적인 흐름은 아래와 같습니다.





 

1. list.jsp에서 [상품등록] 버튼을 누르면 http://localhost/write 주소를 요청합니다.

2. ProductController의 write() method가 호출됩니다.

3. write.jsp 페이지로 이동합니다.

4. write.jsp 페이지에서 내용을 작성한 후 다시 Controller로 보냅니다.

5. Controller에서 받은 입력값을 DAO에 보냅니다.

6. DAO는 mapper에 자료를 전달하여 테이블의 레코드가 추가됩니다.

7. Controller에서 다시 http://localhost/list 로 이동하여 상품목록 화면에 반영됩니다.

 

 

1. list.jsp

빨간색 부분만 추가하시면 됩니다.

 


[코드 생략]

<body>

<h2>상품목록</h2>

[코드 생략]

<button type="button" onclick="location.href='write'">상품등록</button>

<hr>

등록된 상품개수: ${fn:length(list)}

[코드 생략]

</body>

</html>


 

[해설]

 


<button type="button" onclick="location.href='write'">상품등록</button>


 

버튼을 누르면 http://localhost/write 으로 이동하게 됩니다.  onclick은 버튼을 누를 때 실행한다는 뜻입니다.  

 

 

2. ProductController.java

write() method를 작성합니다.

 


package com.example.product;

@Controller

public class ProductController {

[코드 생략]

   @RequestMapping("/list")

   public ModelAndView list(@RequestParam(defaultValue="") String product_name, ModelAndView mav) {

[생략]

   }

   @RequestMapping("/write")

   public String write() {

       return "write";

   }

}


 

[해설]

 


<button type="button" onclick="location.href='write'">상품등록</button>


 

list.jsp에서 버튼을 클릭하면 http://localhost/write 으로 이동하게 됩니다.




    @RequestMapping("/write")

    public String write() {

        return "write";

    }


 

여기서의 return은 값 자체를 리턴하는 것이 아니고 write.jsp 페이지로 이동하는 것입니다.

 

 

3. write.jsp


<%@ page language="java" contentType="text/html; charset=UTF-8"

   pageEncoding="UTF-8"%>

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>Insert title here</title>

</head>

<body>

   <h2>상품 등록</h2>

   <form name="form1" method="post"

       enctype="multipart/form-data" action="insert">

       <table>

           <tr>

            <td>상품명</td>

            <td><input type="text" name="product_name"></td>

           </tr>

           <tr>

            <td>가격</td>

            <td><input type="number" name="price"></td>

           </tr>

           <tr>

               <td>상품설명</td>

               <td><textarea rows="5" cols="60" name="description"></textarea></td>

           </tr>

           <tr>

               <td>상품이미지</td>

               <td><input type="file" name="img"></td>

           </tr>

           <tr>

               <td colspan="2" align="center">

                   <input type="submit" value="등록">

                   <input type="button" value="목록" onclick="location.href='list'">

               </td>

           </tr>

       </table>

   </form>

</body>

</html>


 

[해설]

 


<form name="form1" method="post"

       enctype="multipart/form-data" action="insert">


 

웹에서는 데이터를 서버로 보낼 때 form 을 사용합니다.

name은 폼의 이름입니다.




   <form name="form1" method="post"

       enctype="multipart/form-data" action="insert">


 

method는 대표적으로 get과 post가 있습니다.

get은 주로 자료를 요청할 때 사용합니다.  post는 서버에 데이터를 보낼 때 사용합니다. 여기서는 서버에 자료를 보내야 하므로 post를 사용했습니다.




<form name="form1" method="post"

       enctype="multipart/form-data" action="insert">


 

파일 첨부를 하려면 enctype="multipart/form-data" 코드가 꼭 필요합니다.  이 옵션이 없으면 파일 첨부가 되지 않습니다.




   <form name="form1" method="post"

       enctype="multipart/form-data" action="insert">


 

action 속성에는 데이터를 받을 서버의 주소를 입력합니다.

action="insert" 라고 했으므로 http://localhost/insert 로 데이터가 전달되게 됩니다.




<input type="text" name="product_name">


 

input 태그는 서버에 보낼 텍스트를 입력할 때 사용하는 태그입니다.  name 속성에 지정한 값이 변수명이 됩니다.




<textarea rows="5" cols="60" name="description"></textarea>


 

한줄이 아니라 여러줄의 텍스트를 입력하려면 textarea 태그를 사용합니다.

textarea 태그의 형식은 아래와 같습니다.

<textarea rows="행의 수" cols="열의 수" name="변수명">텍스트의 내용</textarea>

input 태그와 달리 닫는 태그도 필요합니다.




<input type="file" name="img">


 

서버에 파일을 보내기 위해서는 <input type="file">을 사용합니다.




<input type="submit" value="등록">


 

submit 버튼을 누르면 폼 양식에 입력한 값들을 서버에 보내게 됩니다.




<input type="button" value="목록" onclick="location.href='list'">


 

[목록] 버튼을 누르면 http://localhost/list 로 다시 이동하게 됩니다.                    

 

 

 

4. ProductDAO.java

dao에 insert() method를 작성합니다.

 


package com.example.product;

@Repository

public class ProductDAO {

   @Autowired

   SqlSession sqlSession;

   public List<Map<String, Object>> list(String product_name) {

       return sqlSession.selectList("product.list", "%" + product_name + "%");

   }

   public void insert(Map<String, Object> map) {

       sqlSession.insert("product.insert", map);

   }

}


 

[해설]

 


   public void insert(Map<String, Object> map) {

       sqlSession.insert("product.insert", map);

   }


 

namespace가 product이고 id가 insert인 태그에 map 데이터가 전달됩니다.

 

 

5. product.xml

<insert> 태그를 작성합니다.

 


<?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="product">

   <select id="list" resultType="java.util.Map">

       select * from product

       where product_name like #{product_name}

       order by product_name

   </select>

   <insert id="insert">

       insert into product (product_name, description, price, filename)

       values

       (#{product_name}, #{description}, #{price}, #{filename})

   </insert>

   

   

</mapper>


 

[해설]

 

insert 태그에는 아래와 같이 parameterType 이라는 속성이 생략되어 있습니다.  레코드를 저장하려면 전달되는 변수의 자료형이 필요합니다. 여기서는 map이 전달되었습니다.




<insert id="insert" parameterType="java.util.Map">


 

map에 저장된 product_name, description, price, filename 변수들이 매핑되어 레코드가 추가됩니다.

jsp 페이지에서 Controller로, Controller에서 dao로, dao에서 mapper로 자료가 어떻게 전달되는지 잘 살펴보시기 바랍니다.

jsp 페이지에서 입력한 값들은 아래와 같습니다. 여기서 name에 지정한 변수명을 잘 확인하시기 바랍니다.  이 변수명을 테이블의 필드명과 동일하게 지정해야 정확히 매핑이 됩니다.




<input type="text" name="product_name">

<input type="number" name="price">

<textarea rows="5" cols="60" name="description"></textarea>

<input type="file" name="img">


 

product_name, price, description 변수는 Controller의 Map에 전달이 되어 저장됩니다.




public String insert(@RequestParam Map<String, Object> map, @RequestParam MultipartFile img, HttpServletRequest request)


 

폼에 입력한 값들이 맵에 저장되는 과정이 내부적으로 자동으로 처리됩니다.  




map.put("product_name", product_name);

map.put("price", price);

map.put("description", description);


 

첨부파일은 MultipartFile에 전달되고 파일은 디렉토리에 저장되고 파일이름만 map에 추가됩니다.

dao의 insert method에 map 데이터가 전달됩니다.

dao는 mapper에 map을 전달합니다.




    public void insert(Map<String, Object> map) {

        sqlSession.insert("product.insert", map);

    }


 

mapper에 map 데이터가 전달됩니다.  parameterType은 작성하지 않아도 됩니다.  #{변수명}에는 map에 저장된 변수명을 사용합니다.




<insert id="insert" parameterType="java.util.Map">

insert into product

      (product_name, description, price, filename)

values

       ( #{product_name},#{description},#{price},#{filename} )

   </insert>



6. ProductController.java

insert() method를 추가합니다.

 


package com.example.product;

@Controller

public class ProductController {

   [코드 생략]

   @RequestMapping("/write")

   public String write() {

       return "write";

   }

   @RequestMapping("/insert")

   public String insert(@RequestParam Map<String, Object> map, @RequestParam MultipartFile img,

           HttpServletRequest request) {

       String filename = "-";

       if (img != null && !img.isEmpty()) {

           filename = img.getOriginalFilename();

           try {

               ServletContext application = request.getSession().getServletContext();

               String path = application.getRealPath("/resources/images/");

               img.transferTo(new File(path + filename));

           } catch (Exception e) {

               e.printStackTrace();

           }

       }

       map.put("filename", filename);

       productDao.insert(map);

       return "redirect:/list";

   }

}


 

[해설]

 


@RequestMapping("/insert")

public String insert(@RequestParam Map<String, Object> map, @RequestParam MultipartFile img, HttpServletRequest request) {

 

}


 

write.jsp 에서 입력한 값들이 Map에 전달됩니다.

Map의 형식은 아래와 같습니다.

Map<key의 자료형, value의 자료형>

Map<String, Object> 이라고 했으므로 key는 스트링, value는 모든 자료형이라는 뜻입니다.




@RequestMapping("/insert")

public String insert(@RequestParam Map<String, Object> map, @RequestParam MultipartFile img, HttpServletRequest request) {

 

}


 

첨부 파일은 Map에 저장되지 않으므로 MultipartFile 변수를 별도로 작성해야 합니다.

write.jsp 에서 file 태그의 name을 img 라고 했으므로 Controller에서도 img 라고 해야 정확이 전달이 됩니다.




<input type="file" name="img">


 


@RequestMapping("/insert")

public String insert(@RequestParam Map<String, Object> map, @RequestParam MultipartFile img, HttpServletRequest request) {

}


 

HttpServletRequest 자료형은 사용자의 요청 사항을 처리하는 객체입니다.  




       String filename = "-";


 

첨부파일이 없는 경우도 있으므로 – 으로 빈값임을 표시했습니다.




       if (img != null && !img.isEmpty()) {


 

첨부파일이 null이 아니고 빈값이 아니면




           filename = img.getOriginalFilename();


 

파일 이름을 가져옵니다.




try {

       ServletContext application = request.getSession().getServletContext();

       String path = application.getRealPath("/resources/images/");

       img.transferTo(new File(path + filename));

} catch (Exception e) {

               e.printStackTrace();

}


 

Java에서 파일 입출력은 반드시 예외처리를 해야 하므로 try ~ catch 로 처리를 했습니다.

request.getSession().getServletContext(); 명령어로 application 객체를 가져옵니다.  application은 웹서버의 정보를 조회할 수 있는 객체입니다.

application.getRealPath("/resources/images/"); 명령어는 현재 실행중인 웹프로젝트의 실제 서비스 경로를 구합니다.

http://localhost/resources/images 디렉토리가 서버에 실제로 저장된 물리적인 경로를 구하게 됩니다.




       map.put("filename", filename);


 

맵에 filename 변수를 추가합니다.




       productDao.insert(map);


 

dao에 자료를 보내서 저장합니다.




       return "redirect:/list";


 

http://localhost/list 로 이동하면서 화면에 반영이 됩니다.

 

 

7. 상품 등록 실행 결과 확인

코드가 바뀌면 Spring Boot Project를 재시작을 해야 합니다.

재시작을 하기 전에 현재 실행중인 웹서비스를 꺼야 합니다.  Console 화면에서 빨간색 사각형을 누르면 현재 실행중인 웹서비스가 꺼지게 됩니다.





 

다시 프로젝트에서 우클릭을 하고 Run As > spring boot app을 클릭하면 웹서버가 시작됩니다.

Console에 에러가 없으면 정상적으로 실행된 것입니다.

웹브라우저를 실행하신 후 주소창에 http://localhost를 입력하면 상품목록을 볼 수 있습니다.

[상품등록] 버튼을 누르면 상품등록 페이지가 출력됩니다.





 

상품 정보를 입력하고 [등록] 버튼을 누르면 테이블에 저장되고 화면에 상품 목록이 출력됩니다.





 

상품목록은 한 줄에 5개씩 출력됩니다.




Scroll to Top