Framework/Spring Framework

(22.12.22)Spring ํ”„๋ ˆ์ž„์›Œํฌ: Mybatis ๋‹ค์ด๋‚˜๋ฏนSQL, ์ฒจ๋ถ€ํŒŒ์ผ ์—…๋กœ๋“œ ๋‹ค์šด๋กœ๋“œ ๊ธฐ๋Šฅ ๋งŒ๋“ค๊ธฐ

ํ”„๋กœ๊ทธ๋ž˜๋จธ ์˜ค์›” 2022. 12. 22.

โ—โ—์ด๋ฆ„ ๋˜๋Š” ๋ถ€์„œ๋ฒˆํ˜ธ ํ•˜๋‚˜๋กœ ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ธฐ๋Šฅ ๋งŒ๋“ค๊ธฐ(๋‹ค์ด๋‚˜๋ฏน sql ) โ—โ—

 

 

 

MybatisEmpController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ezen.spring.web.mapper.CRUDMapper;
import com.ezen.spring.web.mapper.EmpMapper;
import com.ezen.spring.web.vo.Emp;
import lombok.extern.slf4j.Slf4j;
 
@Controller
@RequestMapping("/mybatis/emp")
@Slf4j
public class MybatisEmpController {
    @Autowired
    private EmpMapper dao;
    
    @Autowired
    private CRUDMapper dao2;
    
    @GetMapping("/list")
    public String list() {
        return dao.getlist().toString();
    }
    @GetMapping("/listByDeptno/{deptno}")
    public String listByDeptno(@PathVariable(name="deptno"int deptno) {
        return dao.listByDeptno(deptno).toString();
    }
    @GetMapping("/deleteByEmpno/{empno}")
    public Boolean deleteByEmpno(@PathVariable(name="empno"int empno) {
        Emp emp = new Emp();
        emp.setEmpno(empno);
        return dao.deleteByEmpno(emp)>0?true:false;
    }
    /*
     * @GetMapping("/deleteByEmpno")   ์ฃผ์†Œ์ฐฝ์— /mybatis/emp/deleteByEmpno?empno=7369
        public Boolean deleteByEmpno(Emp emp) {
        return dao.deleteByEmpno(emp)>0?true:false;
    }
     */
    @GetMapping("/updateByDeptno/{deptno}/{sal}")
    public Boolean updateByDeptno(@PathVariable Map<String,Integer> map) {
        return dao.updateByDeptno(map)>0?true:false;
    }
    @GetMapping("/getListWithDeptno")
    public String getListWithDeptno() {
        return dao.getListWithDeptno().toString();
    }
    @GetMapping("/searchform")
    public String search() {
        return "/emp/SearchEMP";
    }
    @PostMapping("/search")//๋ฆฌํ€˜์ŠคํŠธ๋ฐ”๋””๋ฅผ ํผ๋ฐ์ดํ„ฐ ์ž์ฒด๋กœ ๋ฐ›๊ฒ ๋‹ค. ๋ฉ€๋งต์€ ์ž๋ฐ” ํ‘œ์ค€์ด ์•„๋‹ˆ๊ณ  ์Šคํ”„๋ง์—๋งŒ ์žˆ๋‹ค.
    @ResponseBody
    public String search(@RequestBody MultiValueMap<String,Object> mulmap) {
                                    //ํ•˜๋‚˜์˜ ์ด๋ฆ„์œผ๋กœ ๋‹ค์ค‘ ๊ฐ’์„ ๊ฐ€์ง„ ํŒŒ๋ผ๋ฏธํ„ฐ๋„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•จ
        Map<String,Object> map = mulmap.toSingleValueMap();
        log.info(map.toString());
        return dao2.search(map).toString();
    }
}
 
cs

 

 

 

CRUDMapper.java

1
2
3
4
5
6
7
8
9
10
11
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Mapper;
import com.ezen.spring.web.vo.Emp;
 
@Mapper
public interface CRUDMapper {
    List<Emp> search(Map<String,Object> map);
    void addBoardAndAttach(Map<String,Object> map);
}
 
cs

 

 

 

CRUDMapper.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?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="com.ezen.spring.web.mapper.CRUDMapper">
     <select id="search" 
       resultType="com.ezen.spring.web.vo.Emp"
       parameterType="map">
        SELECT * FROM emp2 
        <!--WHERE deptno =#{deptno} AND ename=#{ename}-->
        <where>
            <if test="deptno!=''">AND deptno =#{deptno}</if>
            <if test="ename!=''">AND ename =#{ename}</if>
        </where>
    </select>
</mapper>
cs

 

 

 

SearchEMP.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>์‚ฌ์šฉ์ž ๊ฒ€์ƒ‰</title>
<style type="text/css">
    main {width:fit-content; margin:1em auto; }
    main h3{ text-align: center;}
    form {border:1px solid black; padding:1em;}
    label {display:inline-block; width:3em; text-align: right; padding-right:1em; }
    div.btn { width:fit-content; margin: 0.5em auto; }
</style>
<script src="https://code.jquery.com/jquery-3.6.1.min.js" 
integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous">
</script>
</head>
<body>
<main>
<h3>์‚ฌ์šฉ์ž ๊ฒ€์ƒ‰</h3>
<form id="loginForm" method="post" action="/mybatis/emp/search">
    
    <div><label for="ename">์ด๋ฆ„์œผ๋กœ ๊ฒ€์ƒ‰</label>
        <input type="text" id="ename" name="ename" value="">
    </div>
    <div><label for="deptno">๋ถ€์„œ๋ฒˆํ˜ธ๋กœ ๊ฒ€์ƒ‰</label>
        <input type="text" id="deptno" name="deptno" value="">
    </div>
    <div class="btn">
        <button type="reset">์ทจ์†Œ</button>
        <button type="submit">๊ฒ€์ƒ‰</button>
    </div>
</form>
</main>
</body>
</html>
cs

 

์‹คํ–‰๊ฒฐ๊ณผ : 

๋ถ€์„œ๋ฒˆํ˜ธ 10๋ฒˆ์œผ๋กœ ๊ฒ€์ƒ‰

 

 

๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ

 

 

 


 

 

 

โ—โ—์ฒจ๋ถ€ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ/์—…๋กœ๋“œ ๊ธฐ๋Šฅ ๋งŒ๋“ค๊ธฐโ—โ—

 

 

UploadController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import java.io.File;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
 
@Controller
@RequestMapping("/files")
public class UploadController 
{
   @Autowired
   ResourceLoader resourceLoader;
 
   @GetMapping("/upload")
   public String getForm() 
   {
      return "files/upload_form";
   }
   
   @PostMapping("/upload")
   @ResponseBody
   public String upload(@RequestParam("files")MultipartFile[] mfiles,
                     HttpServletRequest request,
                     @RequestParam("author"String author) 
   {
      ServletContext context = request.getServletContext();
      String savePath = context.getRealPath("/WEB-INF/files");
 
      /* static/upload ๋””๋ ‰ํ† ๋ฆฌ์— ์—…๋กœ๋“œํ•˜๋ ค๋ฉด, ์•„๋ž˜์ฒ˜๋Ÿผ ์ ˆ๋Œ€๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค
      * Resource resource = resourceLoader.getResource("classpath:/static");
      * String absolutePath = resource.getFile().getAbsolutePath();
      */ 
      try {
         for(int i=0;i<mfiles.length;i++) {
            mfiles[i].transferTo(
              new File(savePath+"/"+mfiles[i].getOriginalFilename()));
            /* MultipartFile ์ฃผ์š” ๋ฉ”์†Œ๋“œ
            String cType = mfiles[i].getContentType();
            String pName = mfiles[i].getName();
            Resource res = mfiles[i].getResource();
            long fSize = mfiles[i].getSize();
            boolean empty = mfiles[i].isEmpty();
            */
         }
         String msg = String.format("ํŒŒ์ผ(%d)๊ฐœ ์ €์žฅ์„ฑ๊ณต(์ž‘์„ฑ์ž:%s)", mfiles.length,author);
         return msg;
      } catch (Exception e) {
         e.printStackTrace();
         return "ํŒŒ์ผ ์ €์žฅ ์‹คํŒจ:";
      }
   }
   
   @GetMapping("/download/{filename}")
   public ResponseEntity<Resource> download(
                              HttpServletRequest request,
                              @PathVariable String filename)
   {
      Resource resource = resourceLoader.getResource("WEB-INF/files/"+filename);
      System.out.println("ํŒŒ์ผ๋ช…:"+resource.getFilename());
        String contentType = null;
        try {
            contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
        } catch (IOException e) {
            e.printStackTrace();
        }
 
        if(contentType == null) {
            contentType = "application/octet-stream"//http ํ”„๋กœํ† ์ฝœ ์•ฝ์†
        }
 
        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType(contentType))
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
                .body(resource);
   }
}
cs

 

 

 

upload_form.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ํŒŒ์ผ ์—…๋กœ๋“œ ํ…Œ์ŠคํŠธ</title>
</head>
<body>
<h3>Spring boot ํŒŒ์ผ ์—…๋กœ๋“œ ํ…Œ์ŠคํŠธ</h3>
<form action="/files/upload" method="post" enctype="multipart/form-data">
   ์ž‘์„ฑ์ž <input type="text" name="author" value="smith"><br>
   File <input type="file" name="files" multiple="multiple"><br>
   <button type="submit">์—…๋กœ๋“œ</button>
</form>
</body>
</html>
cs

 

 

 

 

application.properties๋ฅผ ์„ค์ • ํ•ด์ค˜์•ผํ•œ๋‹ค.

 

 

 

์ปจํŠธ๋กค์—์„œ ์ง€์ •ํ•ด๋‘” ํŒŒ์ผ ๊ฒฝ๋กœ์— ๋งž๊ฒŒ ํด๋”๋ฅผ ์„ค์น˜ ํ•ด์ค˜์•ผํ•œ๋‹ค.

 

 

 

์‹คํ–‰ ๊ฒฐ๊ณผ : 

์ปดํ“จ๋„ˆ ๋‚ด์— ์žˆ๋˜ ํŒŒ์ผ ์—…๋กœ๋“œ

 

 

 

์—…๋กœ๋“œ์— ์„ฑ๊ณตํ•˜์—ฌ ํด๋”์— ์‚ฌ์ง„์ด ์ €์žฅ๋˜์—ˆ๋‹ค.

 

 

๋‹ค์šด๋กœ๋“œ

get๋ฐฉ์‹์œผ๋กœ url์„ ์น˜๋ฉด ํŒŒ์ผ์ด ์ €์žฅ๋œ๊ฑธ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

 

DB์— ์ €์žฅํ•ด์•ผ ํ•  ๋ฐ์ดํ„ฐ

์ž‘์„ฑ์ž, ์ž‘์„ฑ์ผ, ์ œ๋ชฉ, ๋‚ด์šฉ, ํŒŒ์ผ๋ช…, ํŒŒ์ผ์‚ฌ์ด์ฆˆ

 

๊ธ€ ์ž‘์„ฑ์‹œ ์ฒจ๋ถ€ํŒŒ์ผ์ด ์—†๋‹ค๋ฉด? -> ์ปฌ๋Ÿผ๊ฐ’์ด ๋น„์–ด์žˆ๊ฒŒ ๋œ๋‹ค.

๊ธ€์€ ํ•˜๋‚˜์ธ๋ฐ ์ฒจ๋ถ€ํŒŒ์ผ์ด 2๊ฐœ๋ผ๋ฉด -> ํ•œ๊ธ€์— ์ฒจ๋ถ€ํŒŒ์ผ ํ–‰์ด ๋‘๊ฐœ๊ฐ€ ํ•„์š”ํ•ด์ง„๋‹ค.

์›์ž์„ฑ : ํ•œ๊ฐœ์˜ ์ปฌ๋Ÿผ์—๋Š” ํ•œ๊ฐœ์˜ ๊ฐ’๋งŒ ์ €์žฅํ•ด์•ผ ํ•œ๋‹ค.

 

board (์ž‘์„ฑ์ž, ์ž‘์„ฑ์ผ, ์ œ๋ชฉ, ๋‚ด์šฉ)

attach(ํŒŒ์ผ๋ช…, ํŒŒ์ผ์‚ฌ์ด์ฆˆ)

 

๊ธ€ ํ•œ๊ฐœ๋ฅผ ์ €์žฅํ•  ๋•Œ ์ฒจ๋ถ€ํŒŒ์ผ์ด 2๊ฐœ ํฌํ•จ๋œ ๊ฒฝ์šฐ

-board ํ…Œ์ด๋ธ”์— ํ•œ ํ–‰ ์ถ”๊ฐ€(๊ธ€๋ฒˆํ˜ธ 1)

-attach ํ…Œ์ด๋ธ”์— 2๊ฐœ ํ–‰ ์ถ”๊ฐ€(๊ธ€๋ฒˆํ˜ธ 1 ํŒŒ์ผ๋ช…1 ํŒŒ์ผ์‚ฌ์ด์ฆˆ1 / ๊ธ€๋ฒˆํ˜ธ1 ํŒŒ์ผ๋ช…2 ํŒŒ์ผ์‚ฌ์ด์ฆˆ2) JOIN๋ฌธ ์ด์šฉ

 

DB Normalization(์ •๊ทœํ™”)

-๋ฌด๊ฒฐ์„ฑ ํ™•๋ณด

์ œ 1 ์ •๊ทœํ˜• : ์›์ž์„ฑ์„ ๊ฐ–๊ฒŒํ•œ๋‹ค.

์ œ 2 ์ •๊ทœํ˜• : pk๊ฐ€ ๋‹ค์ˆ˜๊ฐœ์˜ ์ปฌ๋Ÿผ์œผ๋กœ ๊ตฌ์„ฑ๋œ ๊ฒฝ์šฐ์— ์ ์šฉ

            -pk์— ๋ชจ๋“  ๋‹ค๋ฅธ ์†์„ฑ์ด ์ข…์†๋˜์–ด์•ผ ํ•œ๋‹ค.

            -pk์˜ ์ผ๋ถ€์— ์ข…์†๋˜๋Š” ๊ฒฝ์šฐ(๋ถ€๋ถ„ ํ•จ์ˆ˜ ์ข…์†์„ฑ)๊ฐ€ ์—†์–ด์•ผ ํ•œ๋‹ค.

์ œ 3 ์ •๊ทœํ˜• : pk ์ด์™ธ์˜ ์†์„ฑ์— ๋‹ค๋ฅธ ์†์„ฑ์ด ์ข…์†๋˜๋Š” ๊ฒฝ์šฐ(์ดํ–‰ํ•จ์ˆ˜ ์ข…์†์„ฑ)๊ฐ€ ์—†์–ด์•ผ ํ•œ๋‹ค.

 

์ข…์†์„ฑ : ์–ด๋–ค ์†์„ฑ 'a' ๋ฅผ ์•Œ๋ฉด ๋‹ค๋ฅธ ์†์„ฑ 'b'์˜ ๊ฐ’์ด ์œ ์ผํ•˜๊ฒŒ ์ •ํ•ด์ง€๋Š” ๊ด€๊ณ„

์˜ˆ์‹œ) ์ฃผ๋ฏผ๋“ฑ๋ก๋ฒˆํ˜ธ๋ฅผ ์•Œ๋ฉด ๊ทธ์‚ฌ๋žŒ์˜ ์ด๋ฆ„์€ ์œ ์ผํ•˜๊ฒŒ ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

SQL ํ‘œ์ค€ ๊ฒ€์ƒ‰

SELECT * FROM emp2 WHERE ename LIKE '%SM%' // ๋ถ€๋ถ„ ์ผ์น˜ ๊ฒ€์ƒ‰(ํŒจํ„ด ๊ฒ€์ƒ‰)
SELECT * FROM emp2 WHERE ename='SM' //์™„์ „์ผ์น˜ ๊ฒ€์ƒ‰

 

์˜ค๋ผํด,  MyBatis ์—์„œ ๊ฒ€์ƒ‰์€ ํ‘œ์ค€๊ณผ ์กฐ๊ธˆ ๋‹ค๋ฅด๋‹ค

ename LIKE '%'||#{ ์ฐพ์„ ๋ฌธ์ž์—ด (ex :  SM)}||'%'

 

 

๋Œ“๊ธ€