SQL Injction์ด๋ž€

    - ์•…์˜์ ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ๋ณด์•ˆ ์ƒ์˜ ์ทจ์•ฝ์ ์„ ์˜๋„์ ์œผ๋กœ ์ด์šฉํ•˜์—ฌ ์•…์˜์ ์ธ SQL๋ฌธ์„ ์ฃผ์ž…ํ•˜๊ณ  ์‹คํ–‰๋˜๊ฒŒ

      ํ•˜์—ฌ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ํ–‰์œ„

SQL Injection์˜ ์ข…๋ฅ˜

 

    Error based SQL Injection4

         - ๋…ผ๋ฆฌ์  ์—๋Ÿฌ๋ฅผ ์ด์šฉํ•œ SQL Injection

         - ๊ฐ€์žฅ ๋Œ€์ค‘์ ์ธ ๊ณต๊ฒฉ ๊ธฐ๋ฒ•์ด๋‹ค.

         ex)

         SELECT * FROM Users WHERE id = 'INPUT1' AND password = 'INPUT2'

         ๋ผ๋Š” SQL ๊ตฌ๋ฌธ์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž.

         ๋งŒ์•ฝ ์‚ฌ์šฉ์ž๊ฐ€ ์—ฌ๊ธฐ์—

         'OR 1=1 -- 

         ๋ผ๋Š” SQL ๋ฌธ์„ ์ฃผ์ž…ํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ์ด ์‚ฌ์šฉ์ž๋Š” Users ๋””๋น„์— ์žˆ๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๊ฒŒ ๋œ๋‹ค.

         ๋˜ํ•œ ๋ณดํ†ต ๊ด€๋ฆฌ์ž ๊ณ„์ •์„ ์ œ์ผ ๋จผ์ € ๋งŒ๋“ค๊ธฐ ๋•Œ๋ฌธ์— 2์ฐจ ํ”ผํ•ด๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

         SELECT * FROM Users WHERE id = ''OR 1=1 -- ' AND password = 'INPUT2'

         ํ•ด์„ : 'OR1=1 ์„ ์ฃผ์ž…ํ•ด์คŒ์œผ๋กœ์จ ๊ตฌ๋ฌธ์ด ํ•ญ์ƒ ์ฐธ์ด ๋˜๋„๋ก ํ•˜๊ณ  -- ์„ ์ฃผ์ž…ํ•ด์คŒ์œผ๋กœ์จ ๋’ท ๊ตฌ๋ฌธ๋“ค์„

                   ๋ชจ๋‘ ์ฃผ์„์ฒ˜๋ฆฌ์‹œํ‚จ๋‹ค.

         ๊ฒฐ๊ณผ : ์•…์˜์ ์ธ ์‚ฌ์šฉ์ž๊ฐ€ DB ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋‘ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค.

      

 

    Union based SQL Injection

         - Union ๋ช…๋ น์–ด๋ฅผ ์ด์šฉํ•œ SQL Injection

         - ๋‘ ๊ฐœ์˜ ์ฟผ๋ฆฌ๋ฌธ์„ ํ†ตํ•ฉํ•ด์„œ ํ•˜๋‚˜์˜ ํ…Œ์ด๋ธ”๋กœ ๋ณด์—ฌ์ค€๋‹ค. 

         - Union ํ•˜๋Š” ๋‘ ํ…Œ์ด๋ธ”์˜ ์ปฌ๋Ÿผ ์ˆ˜์™€ ๋ฐ์ดํ„ฐ ํ˜•์ด ๊ฐ™์•„์•ผํ•œ๋‹ค.

         ex)

         SELECT * FROM Board WHERE title LIKE '%INPUT%' OR contents '%INPUT%'

         ์ด๋ผ๋Š” ๊ตฌ๋ฌธ์— ์•…์˜์ ์ธ ์‚ฌ์šฉ์ž๊ฐ€ 

         'UNION SELECT null,id,passwd FROM Users-- 

         ๋ผ๋Š” ๊ตฌ๋ฌธ์„ ์ฃผ์ž…ํ–ˆ๋‹ค๋ฉด ์‚ฌ์šฉ์ž์˜ ๊ฐœ์ธ ์ •๋ณด๊ฐ€ ๊ฒŒ์‹œ๊ธ€๊ณผ ํ•จ๊ป˜ ํ™”๋ฉด์— ๋ณด์—ฌ์ง€๊ฒŒ ๋œ๋‹ค.

         SELECT * FROM Board WHERE title LIKE '% 'UNION SELECT null,id,passwd FROMUsers --

        %'AND contents '% UNION SELECT null,id,passwd FROM Users -- %'

         ํ•ด์„ : ์‹ฑ๊ธ€์ฟผํ„ฐ๋ฅผ ๋‹ซ์•„์ฃผ๊ธฐ ์œ„ํ•œ ' ์‚ฝ์ž… , Union ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ๋‘ ์ฟผ๋ฆฌ๋ฌธ์„ ํ•ฉ์ณ์คŒ์œผ๋กœ์จ ํ•˜๋‚˜์˜ ํ…Œ์ด

                   ๋ธ”๋กœ ๋ณด์—ฌ์ง€๊ฒŒ ๋œ๋‹ค. 

         ๊ฒฐ๊ณผ : ์‚ฌ์šฉ์ž์˜ ๊ฐœ์ธ ์ •๋ณด๊ฐ€ ๊ฒŒ์‹œ๊ธ€๊ณผ ํ•จ๊ป˜ ํ™”๋ฉด์— ๋ณด์—ฌ์ง€๊ฒŒ ๋œ๋‹ค.

      

 

    Blind SQL Injection

  •   Boolean based SQL

          -  ํŠน์ •ํ•œ ๊ฐ’์ด๋‚˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌ๋ฐ›์ง€ ์•Š๊ณ , ๋‹จ์ˆœํžˆ ์ฐธ๊ณผ ๊ฑฐ์ง“์˜ ์ •๋ณด๋งŒ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

          ex)

          SELECT * FROM Users WHERE id = 'INPUT1' AND password = 'INPUT2'

          ๋ผ๋Š” ๊ตฌ๋ฌธ์— ์•…์˜์ ์ธ ์‚ฌ์šฉ์ž๊ฐ€,

          abc123' and ASCII(SUBSTR(SELECT name FROM INFORMATION_SCHEMA.tables WHERE 

          table_type = 'base table' limit 0,1),1,1) > 100 --

          ๋ผ๋Š” ๊ตฌ๋ฌธ์„ ์ฃผ์ž…ํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž.

          ์ด๊ฒƒ์€ ์กฐํšŒ๋˜๋Š” ํ…Œ์ด๋ธ” ๋ช…์˜ ์ฒซ ๊ธ€์ž๋งŒ ๋”ฐ์„œ 100์ด๋ผ๋Š” ๊ฐ’๊ณผ ๋น„๊ตํ•ด์ฃผ๋Š” ๊ตฌ๋ฌธ์ด๋‹ค.

          ๋งŒ์•ฝ ํ…Œ์ด๋ธ”์˜ ์ฒซ๋ฒˆ์งธ ๊ฐ’์ด 100์ด์ƒ์ด๋ผ๋ฉด ๋กœ๊ทธ์ธ ์„ฑ๊ณต์ด ๋ ๊ฒƒ์ด๊ณ  , ์•„๋‹ˆ๋ผ๋ฉด ์‹คํŒจํ•  ๊ฒƒ์ด๋‹ค.

          ์ด ๊ณผ์ •์„ ์ž๋™ํ™” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ†ตํ•ด ๋น ๋ฅด๊ฒŒ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

          SELECT * FROM Users WHERE id = 'abc123' and ASCII(SUBSTR(SELECT name FROM 

          INFORMATION_SCHEMA.tables WHERE table_type = 'base table' limit 0,1),1,1) > 100 --' AND                password = 'INPUT2'

          ํ•ด์„ : ์กฐํšŒ๋˜๋Š” ํ…Œ์ด๋ธ”์˜ ์ฒซ๋ฒˆ์งธ ๊ฐ’๋งŒ ์•„์Šคํ‚ค ์ฝ”๋“œ์™€ ๋น„๊ตํ•ด์„œ ์ฐธ, ๊ฑฐ์ง“์„ ํŒ๋ณ„ํ•œ๋‹ค.

          ๊ฒฐ๊ณผ : ์ž๋™ํ™” ์Šคํฌ๋ฆฝํฌ๋ฅผ ํ†ตํ•ด ๋น ๋ฅด๊ฒŒ ํ…Œ์ด๋ธ” ๋ช…์„ ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

 

  • Time based SQL

           - ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์ฐธ ๊ฑฐ์ง“์„ ์‘๋‹ต๋ฐ›์•„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์œ ์ถ”

           ex)

           SELECT * FROM Users WHERE id = 'INPUT1' AND password = 'INPUT2'

           ๋ผ๋Š” ๊ตฌ๋ฌธ์— ์•…์˜์ ์ธ ์‚ฌ์šฉ์ž๊ฐ€,

           abc123' OR (LENGTH(DATABASE())=1 AND SLEEP(2)) --

           ๋ผ๋Š” ๊ตฌ๋ฌธ์„ ์ฃผ์ž…ํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž.

           ์ด ๊ฒฝ์šฐ ๊ตฌ๋ฌธ์—์„œ ์„ค์ •ํ•œ๋Œ€๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๊ธธ์ด๊ฐ€ 1์ด๋ฉด SLEEP(2) ๊ฐ€ ๋™์ž‘ํ•จ์œผ๋กœ์จ ์‹คํ–‰์„ ์ง€์—ฐ             ์‹œํ‚ค๊ณ , ๊ฑฐ์ง“์ด๋ฉด ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค.

           SELECT * FROM Users WHERE id = 'abc123' OR (LENGTH(DATABASE())=1 AND SLEEP(2)) --           AND password = 'INPUT2'

           ํ•ด์„ : ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๊ธธ์ด๊ฐ€ ๋งž์œผ๋ฉด SLEEP() ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์‹คํ–‰์„ ์ง€์—ฐ์‹œํ‚จ๋‹ค.

           ๊ฒฐ๊ณผ : ์•…์˜์ ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๊ธธ์ด๋ฅผ ์œ ์ถ”ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

http ํ”„๋กœํ† ์ฝœ์ด๋ž€?

    - ์›น์—์„œ ์ด๋ฃจ์–ด์ง€๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ ๊ตํ™˜์˜ ๊ธฐ์ดˆ์ด๋ฉฐ , ํด๋ผ์ด์–ธํŠธ ์„œ๋ฒ„ ํ”„๋กœํ† ์ฝœ

ํŠน์ง•

http์˜ ํŠน์ง•์€ ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

    1. ๋น„์—ฐ๊ฒฐ ์ง€ํ–ฅ(Connectionless)

    - ์›น ์„œ๋ฒ„์—๊ฒŒ ์š”์ฒญํ•œ ์„œ๋น„์Šค๋ฅผ ์ œ๊ณต๋ฐ›์œผ๋ฉด ํด๋ผ์ด์–ธํŠธ๋Š” ์—ฐ๊ฒฐ์„ ์ข…๋ฃŒ์‹œํ‚จ๋‹ค.

      * HTTP 1.1 ๋ถ€ํ„ฐ๋Š” Keep-Alive ์†์„ฑ์„ ํ†ตํ•ด ์—ฐ๊ฒฐ์„ ์ง€์†์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

 

    2. ์ƒํƒœ์ •๋ณด ์ €์žฅ ์•ˆ ํ•จ(Stateless)

    - ์ƒํƒœ ์ •๋ณด๋ฅผ ์œ ์ง€ํ•˜์ง€์•Š๋Š”๋‹ค. ์ฆ‰ , ํด๋ผ์ด์–ธํŠธ์˜ ์ •๋ณด๋ฅผ ๊ธฐ์–ตํ•˜์ง€ ๋ชปํ•œ๋‹ค.

    - ์š”์ฒญ ๊ฐ„ ์˜์กด๊ด€๊ณ„๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ™์€ ์œ ์ €์ธ์ง€ ์ง€์†์ ์œผ๋กœ ์ธ์ฆ์„ ํ•ด์ค˜์•ผํ•œ๋‹ค.

 

๋”ฐ๋ผ์„œ HTTP์˜ ์ด๋Ÿฌํ•œ ํŠน์ง• ๋•Œ๋ฌธ์— ์ฟ ํ‚ค์™€ ์„ธ์…˜์„ ์‚ฌ์šฉํ•œ๋‹ค.

์ฟ ํ‚ค

    ์ฟ ํ‚ค๋ž€ ?

    -์„œ๋ฒ„์— ์ €์žฅ๋˜์ง€ ์•Š๊ณ  ๊ฐœ๋ณ„ ํด๋ผ์ด์–ธํŠธ์— ์ €์žฅ๋˜๋Š” ๋ฐฉ์‹-

    -์„œ๋ฒ„์™€ ํ†ต์‹ (Request) ์‹œ์— ์ƒํƒœ์ •๋ณด๋ฅผ HTTP ํ—ค๋”์— ๋‹ด์•„์„œ ์ „์†ก !

    -์œ ํšจ์‹œ๊ฐ„์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์„ค์ •ํ•œ ์œ ํšจ์‹œ๊ฐ„์ด ๋๋‚˜์ž ์•Š์œผ๋ฉด ๋ธŒ๋ผ์šฐ์ €๋ฅผ ๋‹ซ์•„๋„  

     ์ธ์ฆ์ด ์œ ์ง€๋œ๋‹ค.

 

    ๊ตฌ์„ฑ์š”์†Œ

      - ์ด๋ฆ„๊ณผ ๊ฐ’์œผ๋กœ ์ด๋ฃจ์–ด์ ธ์žˆ๋‹ค.

Name Value
Id Abcd1234

           Ex)

 

    ๋‹จ์ 

      - ๋ธŒ๋ผ์šฐ์ €์—์„œ ์กฐ์ž‘์ด ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ค‘์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์„ ์ˆ˜ ์—†๋‹ค.

 

์„ธ์…˜ 

  

    ์„ธ์…˜์ด๋ž€ ?

     - ๋ธŒ๋ผ์šฐ์ €์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ์ฟ ํ‚ค์™€ ๋‹ฌ๋ฆฌ ์„œ๋ฒ„์—์„œ ๊ด€๋ฆฌํ•œ๋‹ค.

     - ์„œ๋ฒ„์—์„œ๋Š” ํด๋ผ์ด์–ธํŠธ์–ธํŠธ๋ฅผ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•ด SessionID ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

     - Session cookie ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•˜๋ฏ€๋กœ , ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด ์ธ์ฆ์ด ๋๋‚œ๋‹ค.

.

    ์„ธ์…˜ID๋Š” ๋ญ์•ผ?

     - ์„œ๋ฒ„์—์„œ ํด๋ผ์ด์–ธํŠธ๋ฅผ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๊ฐ’์ด๋‹ค.

     - ํด๋ผ์ด์–ธํŠธ๋งˆ๋‹ค ๋ถ€์—ฌ๋˜๋Š” ์œ ์ผํ•œ ๊ฐ’์ด๋‹ค.

     - ์„œ๋ฒ„์—์„œ๋Š” ์„ธ์…˜ID๋ฅผ ํ†ตํ•ด ์„ธ์…˜DB ์™€ ๋น„๊ตํ•จ์œผ๋กœ์จ ์‚ฌ์šฉ์ž๋ฅผ ์‹๋ณ„ํ•œ๋‹ค.

    ์–ด๋–ป๊ฒŒ ์ „์†กํ•ด?

     - ์„œ๋ฒ„ ์‘๋‹ต ์‹œ ์„œ๋ฒ„์— Request ์‹œ ์ฟ ํ‚ค๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ๋œ๋‹ค

       Set−Cookie: SESSIONID=qwe3121

     - ์ดํ›„ ์š”์ฒญ๋งˆ๋‹ค ์ฟ ํ‚ค๋ฅผ HTTP ํ—ค๋”์— ๋„ฃ์–ด์„œ ์ „์†กํ•œ๋‹ค.

 

     ์„ธ์…˜ID๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ์žฅ์ , ๋‹จ์ 

     - ๋ชจ๋“  ์„ธ์…˜DB๋ฅผ ์ €์žฅํ•จ์œผ๋กœ์จ ์„œ๋ฒ„์— ๋ถ€๋‹ด์ด ์ปค์งˆ ์ˆ˜ ์žˆ๋‹ค.

       -> ๋•Œ๋ฌธ์— Redis ๋ผ๋Š” ๋น ๋ฅด๊ณ  ์ €๋ ดํ•œ DB๋ฅผ ์ฃผ๋กœ ์ด์šฉ

 

     - ์„œ๋ฒ„์— ๋ˆ„๊ฐ€ ๋กœ๊ทธ์ธ ํ–ˆ๋Š” ์ง€ ์ €์žฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๊ธฐ๋Šฅ์ด ๊ตฌํ˜„ ๊ฐ€๋Šฅํ•˜๋‹ค.

       -> ์‚ฌ์šฉ์ž ๊ด€๋ฆฌ , ๋กœ๊ทธ์ธ ๊ด€๋ฆฌ

 

๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค

 

๊ด€๊ณ„ํ˜• DB๋Š” ํ…Œ์ด๋ธ”๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์œผ๋ฉฐ , ํ…Œ์ด๋ธ”์€ ํ‚ค์™€ ๊ฐ’์˜ ๊ด€๊ณ„๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.

์ด์ฒ˜๋Ÿผ ๊ด€๊ณ„ํ˜• DB๋Š” ์ข…์†์„ฑ์„ ๊ด€๊ณ„๋กœ ํ‘œํ˜„ํ•œ๋‹ค.

 

์—ฌ๊ธฐ์„œ ๋งํ•˜๋Š” ํ‚ค(key)๋ž€ ํ–‰์˜ ์‹๋ณ„์ž๋กœ ์ด์šฉ๋˜๋Š” ์—ด์„ ๋งํ•œ๋‹ค ex) ID

 

๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์˜ ํ™œ์šฉ

 

๋งŒ์•ฝ ์—ฌ๋Ÿฌ ์œ ํŠœ๋ฒ„๋“ค์˜ ์˜์ƒ์„ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์—

ํ‘œํ˜„ํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž

 

 

์œ„์˜ ํ‘œ์ฒ˜๋Ÿผ ๋‹ค๋ฅธ ์˜์ƒ์ž„์—๋„ ๊ฐ™์€ ์œ ํŠœ๋ฒ„์˜ ์ฐฝ์ž‘๋ฌผ์ธ ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.

์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ํšจ๊ณผ์ ์œผ๋กœ DB๋ฅผ ์„ค๊ณ„ํ•  ์ˆ˜ ์žˆ์„๊นŒ ?

์ด๋Ÿฐ ์‹์œผ๋กœ ์œ ํŠœ๋ฒ„์˜ ์ฝ”๋“œ๋งŒ์„ ๋”ฐ๋กœ ํ…Œ์ด๋ธ”๋กœ ๋งŒ๋“ค์–ด์„œ DB๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์‹ค์Šต์„ ํ•ด๋ณผ ๊ฒƒ์ด๋‹ค.

๋จผ์ € video๋ผ๋Š” DB๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•ด์ฃผ์—ˆ๋‹ค.

๋‘ ๊ฐœ์˜ ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•ด์ค€ ํ›„ ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ์–ด์ค€๋‹ค.

์ด์ œ๋Š” join์œผ๋กœ ํ…Œ์ด๋ธ”์„ ํ•ฉ์น  ์ฐจ๋ก€๋‹ค.

๊ธฐ๋ณธ์ ์ธ LEFT JOIN ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด์„œ ํ…Œ์ด๋ธ”์„ ํ•ฉ์ณ์ฃผ์—ˆ๋‹ค.

 

ํ•˜์ง€๋งŒ ์ฝ”๋“œ ์—ด์ด ์ค‘๋ณต๋˜์–ด ์žˆ์–ด์„œ ํ•˜๋‚˜๋งŒ ๋‚˜์˜ค๋„๋ก ์„ค์ •ํ•ด์ค„ ํ•„์š”๊ฐ€ ์žˆ๋‹ค.

 

AS ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด์„œ video ํ…Œ์ด๋ธ”์˜ ์ฝ”๋“œ๋งŒ ์ถœ๋ ฅ๋˜๋„๋ก ํ•˜์˜€๋‹ค.

 

์˜คํžˆ๋ ค ๋” ๋ณต์žกํ•ด์ง€๋Š” ๊ฑฐ ๊ฐ™์€๋ฐ, ์ด๋ ‡๊ฒŒ ๊ด€๊ณ„ํ˜• DB๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์žฅ์ ์ด ๋ญ˜๊นŒ?

 

๊ด€๊ณ„ํ˜• DB๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด,

1. ๋ฐ์ดํ„ฐ์˜ ๋ถ„๋ฅ˜, ์ •๋ ฌ, ํƒ์ƒ‰ ์†๋„๊ฐ€ ๋น ๋ฅด๋‹ค

 

2. ์˜ค๋žซ๋™์•ˆ ์‚ฌ์šฉ๋œ ๋งŒํผ ์‹ ๋ขฐ์„ฑ์ด ๋†’๊ณ , ์–ด๋–ค ์ƒํ™ฉ์—์„œ๋„ ๋ฐ์ดํ„ฐ์˜ ๋ฌด๊ฒฐ์„ฑ์„ ๋ณด์žฅํ•ด์ค€๋‹ค.

 

ํ•˜์ง€๋งŒ,

๊ธฐ์กด์— ์ž‘์„ฑ๋œ ์Šคํ‚ค๋งˆ๋ฅผ ์ˆ˜์ •ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต๊ณ  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ถ€ํ•˜๋ฅผ ๋ถ„์„ํ•˜๋Š” ๊ฒƒ์ด ์–ด๋ ต๋‹ค๋ผ๋Š”

๋‹จ์ ์ด ์žˆ๋‹ค.

 

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ž€ ,

 

 

 


๊ตฌ์กฐํ™”๋œ ์ •๋ณด ๋˜๋Š” ๋ฐ์ดํ„ฐ์˜ ์กฐ์งํ™”๋œ ๋ชจ์Œ์œผ๋กœ์จ ์ผ๋ฐ˜์ ์œผ๋กœ ์ปดํ“จํ„ฐ ์‹œ์Šคํ…œ ๋‚ด์— ์ „์ž์ ์œผ๋กœ ์ €์žฅ

 

๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์˜ ๊ตฌ์กฐ

 

์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ๋Š” ํ‘œ๋“ค๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค.

์ด ๋ฐ์ดํ„ฐ๋“ค์„ ์—ฐ๊ด€ ๋œ ํ•ญ๋ชฉ์— ๋งž๊ฒŒ ๊ทธ๋ฃนํ™” ์‹œํ‚ค๋Š” ๋ฐ ์ด๊ฒƒ์„ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค ํ˜น์€ ์Šคํ‚ค๋งˆ ๋ผ๊ณ  ํ•œ๋‹ค.

๋˜ ์Šคํ‚ค๋งˆ๋“ค์ด ๋ชจ์ธ ๊ฒƒ์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„œ๋ฒ„๊ฐ€ ๋œ๋‹ค.

 

SQL(strutured query language)

 

์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด์ง„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„œ๋ฒ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์–ป์œผ๋ ค๋ฉด SQL ์ด๋ž€๊ฒƒ์„ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.

Sql์„ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ๋ฐ์ดํ„ฐ๋ฅผ ์ฟผ๋ฆฌ , ์กฐ์ž‘ ์ •์˜ํ•˜๊ณ  ์•ก์„ธ์Šค๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

์Šคํ”„๋ ˆ๋“œ ์‹œํŠธ vs ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค

 

์—‘์…€์˜ ์Šคํ”„๋ ˆ๋“œ ์‹œํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋˜๋Š”๋ฐ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ์–ป๋Š” ์ด์ ์€ ๋ญ˜๊นŒ ?

 

- ๋ฐ์ดํ„ฐ ์ €์žฅ ๋ฐ ์กฐ์ž‘ ๋ฐฉ๋ฒ•

- ๋ฐ์ดํ„ฐ์— ์•ก์„ธ์Šค ํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ๋žŒ

- ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ ์–‘

 

์Šคํ”„๋ ˆํŠธ ์‹œํŠธ๋Š” ๋‹ค์–‘ํ•œ ์‚ฌ์šฉ์ž์— ๋งž๊ฒŒ ์„ค๊ณ„๋œ ๊ฒƒ์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ์ž๊ฐ€ ์ ๊ฑฐ๋‚˜ ๋ฐ์ดํ„ฐ์˜ ์–‘์ด ๋งŽ์ง€ ์•Š์€ ๊ฒฝ์šฐ์— ์ ํ•ฉํ•˜๋‹ค.

 

ํ•˜์ง€๋งŒ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค๋Š” ์—ฌ๋Ÿฌ ์‚ฌ์šฉ์ž๋“ค์—๊ฒŒ ๋‹ค์–‘ํ•œ ๊ถŒํ•œ์„ ์ค„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๋Ÿฌ ์‚ฌ์šฉ์ž๊ฐ€ ๋™์‹œ์— ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ‘๊ทผํ•˜์—ฌ ์•ˆ์ „ํ•˜๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

 

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„œ๋ฒ„์— ์ ‘์†ํ•˜๊ธฐ

 

 

DB ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๊ณ  ์‹ถ์œผ๋ฉด ๋จผ์ € DB์„œ๋ฒ„์— ์ ‘์†์„ ํ•ด์•ผํ•œ๋‹ค.

 

Mysql์ด ์„ค์น˜๋˜์žˆ๋Š” ๊ฒฝ๋กœ๋กœ ๊ฐ€์„œ

Mysql –uroot –p ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•ด์ค€๋‹ค.

๊ทธ๋ฆฌ๊ณ  mysql ์„ค์น˜ ์‹œ ์„ค์ •ํ–ˆ๋˜ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ๋ฉด ์„œ๋ฒ„๋กœ ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

Mysql ์‹ค์Šต

 

DB์™€ ํ…Œ์ด๋ธ”

 

DB ๋ช…๋ น์–ด

CREATE DATABASE ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

DROP DATABASE ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๋‹ค.

SHOW DATABASES ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ˜„์žฌ ๋งŒ๋“ค์–ด์ ธ ์žˆ๋Š” ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค๋ฅผ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค..

Ex)

 

topic ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋งŒ๋“ค๋ ค๊ณ  ํ–ˆ์ง€๋งŒ , ์ด๋ฏธ ์กด์žฌํ•˜์˜€๋‹ค.

๋”ฐ๋ผ์„œ DROP ๋ช…๋ น์–ด๋ฅผ ์ด์šฉํ•˜์—ฌ ํ•ด๋‹น DB๋ฅผ ์‚ญ์ œํ•˜๊ณ  ๋‹ค์‹œ ๋งŒ๋“ค์–ด์ฃผ์—ˆ๋‹ค.

์ด์ œ use topic ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด์„œ ํ•ด๋‹น DB๋ฅผ ์ด์šฉํ•ด์ฃผ๋„๋ก ํ•˜์ž

 

TABLE ๋ช…๋ น์–ด ๋ฐ ์ƒ์„ฑ ์‹ค์Šต

 

๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค๋ฅผ ๋งŒ๋“ค์—ˆ์œผ๋ฉด ๊ฑฐ๊ธฐ์— ๋“ค์–ด๊ฐˆ ํ…Œ์ด๋ธ”๋“ค์„ ๋งŒ๋“ค์–ด ์ฃผ์–ด์•ผํ•œ๋‹ค.

ํ…Œ์ด๋ธ”์„ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ฒƒ์€ CREATE TABLE ์„ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค.

์ด์ œ ์ด ํ…Œ์ด๋ธ”๋“ค์„ ์ด์šฉํ•˜์—ฌ CRUD ์‹ค์Šต์„ ์ง„ํ–‰ํ•ด๋ณผ๊ฒƒ์ด๋‹ค.

 

 

CRUD ๋ž€?

DB์˜ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ด ๋˜๋Š” ๊ฒƒ์œผ๋กœ

Create

Read

Update

Delete ๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

 

Create

 

ํ…Œ์ด๋ธ”์— ์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ๊ณ  ์‹ถ์„ ๋•Œ, INSERT ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ์„ ์ˆ˜ ์žˆ๋‹ค.

Ex) INSERT INTO topic1(ID,col1,col2,created) VALUES("1","ROW1","ROW2",NOW());

Read

 

ํ…Œ์ด๋ธ”์˜ ์ •๋ณด๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ณ  ์‹ถ์„ ๋•Œ , SELECT ๋ช…๋ น์œผ๋กœ ํ…Œ์ด๋ธ”์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค,

Ex) SELECT * FROM topic1;

   SELECT id,col1 FROM topic1;

*  ๋งŒ์ผ ์กฐ๊ฑด์— ๋งž๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ณ  ์‹ถ์œผ๋ฉด where๋ฌธ์„ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค.

UPDATE

 

ํ…Œ์ด๋ธ”์˜ ๋ฐ์ดํ„ฐ ์ •๋ณด๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  ์‹ถ์„ ๋•Œ , UPDATE ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

 

DELETE

 

ํ…Œ์ด๋ธ”์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œํ•ด์•ผ ํ•  ๋•Œ, DELETE ๋ช…๋ น์œผ๋กœ ํ…Œ์ด๋ธ”์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๋‹ค.

* WHERE ๋’ค์— ์กฐ๊ฑด๋ฌธ์„ ๊ผญ ๋‹ฌ์•„์ฃผ์–ด์•ผํ•œ๋‹ค !

 

 

 ์ฐธ๊ณ ) ์ƒํ™œ์ฝ”๋”ฉ Mysql

 https://www.youtube.com/watch?v=h_XDmyz--0w&list=PLuHgQVnccGMCgrP_9HL3dAcvdt8qOZxjW

 

 

@RequestParam ์—์„œ @ModelAttribute๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๊นŒ์ง€์˜ ๋ณ€ํ™”๋ฅผ ์•Œ์•„๋ณด์ž

 

 

 

1.@RequestParam ์„ ํ†ตํ•ด ํŒŒ๋ผ๋ฏธํ„ฐ ์ง์ ‘ ๋ฐ›๊ธฐ

 

@PostMapping("/add")
public String addItemV1(@RequestParam String itemName,
                        @RequestParam int price,
                        @RequestParam Integer quantity,
                        Model model) {
    Item item = new Item();
    item.setItemName(itemName);
    item.setPrice(price);
    item.setQuantity(quantity);
    itemRepository.save(item);
    model.addAttribute("item", item);
    return "basic/item";
}

 

ํ•ด๋‹น ๋ณ€์ˆ˜ ์ด๋ฆ„์— ๋งž๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ง์ ‘ ๋ฐ›๊ณ  itemRepository์— ์ €์žฅํ•œ๋‹ค.

ํ•ด๋‹น item ๊ฐ์ฒด๋ฅผ ๋ชจ๋ธ์— ์ „๋‹ฌํ•œ๋‹ค.

 

 

2.@ModelAttribute๋ฅผ ํ†ตํ•œ ์ฃผ์ž…

 

@PostMapping("/add")
public String addItemV2(@ModelAttribute("item") Item item, Model model) {
    itemRepository.save(item);
    //model.addAttribute("item", item); //์ž๋™ ์ถ”๊ฐ€, ์ƒ๋žต ๊ฐ€๋Šฅ
    return "basic/item";
}

 

@RequestParam ์„ ์ƒ๋žตํ•ด๋„ @ModelAttribute๊ฐ€ ์•Œ์•„์„œ ์ƒ์„ฑ์ž๋ฅผ ์ž…๋ ฅํ•ด์ค€๋‹ค.

๊ฒŒ๋‹ค๊ฐ€ ์ด๋ ‡๊ฒŒ ๋„˜์–ด์˜จ item ๊ฐ’์„ ์ž๋™์œผ๋กœ ๋ชจ๋ธ์— ๋„˜๊ฒจ์ฃผ๊ธฐ ๋•Œ๋ฌธ์— 

model.addAttribute ์ฝ”๋“œ๋ฅผ ์ƒ๋žตํ•ด๋„ ๋œ๋‹ค.

๋”ฐ๋ผ์„œ ์ฝ”๋“œ๋ฅผ ๋” ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์งค ์ˆ˜ ์žˆ๋‹ค.

๋งŒ์•ฝ @ModelAttribute("item2")๋ผ๊ณ  ์ž…๋ ฅํ•ด์ค€๋‹ค๋ฉด, ๋ชจ๋ธ์— "item2"๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ๋„˜๊ฒจ์ค€๋‹ค.

 

3.@ModelAttribute์˜ ์ด๋ฆ„ ์ƒ๋žต

 

@PostMapping("/add")
public String addItemV3(@ModelAttribute Item item) {
    itemRepository.save(item);
    return "basic/item";
}

 

@ModelAttribute์˜ ์ด๋ฆ„์„ ์ƒ๋žตํ•ด๋„ ์ƒ๊ด€์—†๋‹ค.

์ด ๊ฒฝ์šฐ item ํด๋ž˜์Šค์˜ Item์„ ์•ž ๊ธ€์ž๋งŒ ์†Œ๋ฌธ์ž๋กœ ๋ณ€๊ฒฝ ํ›„ ๋ชจ๋ธ ์ด๋ฆ„์œผ๋กœ ๋„˜๊ฒจ์ค€๋‹ค.

 

model.addAttribute("item",item);

 

4. @ModelAttribute๊นŒ์ง€ ์ƒ๋žต

 

@PostMapping("/add")
public String addItemV4(Item item) {
    itemRepository.save(item);
    return "basic/item";
}

 

@ModelAttribute ๊นŒ์ง€ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋‹ค. 

์ด ๊ฒฝ์šฐ์—๋„ ์œ„์™€ ๋˜‘๊ฐ™์ด ๋™์ž‘ํ•œ๋‹ค.

ํ•˜์ง€๋งŒ ์ง๊ด€์„ฑ์ด ๋„ˆ๋ฌด ๋–จ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ์„ ๊ถŒํ•˜์ง€ ์•Š๋Š”๋‹ค.

๊ฐ•์˜ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ์ฐธ๊ณ ํ•ด๋ณด๋ ค๋Š”๋ฐ ์ด๋Ÿฐ ์˜ค๋ฅ˜๋“ค์ด ๋‚˜ํƒ€๋‚ฌ๋‹ค.

"Cannot resolve symbol"

 

์—ฌ๋Ÿฌ๋ฒˆ์˜ ๊ตฌ๊ธ€๋ง ๋์— ์ฐพ์•„๋‚ธ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

ํ•ด๋‹น ์†Œ์Šค์ฝ”๋“œ ํŒŒ์ผ ๊ฒฝ๋กœ์˜ .idea ํด๋”๋ฅผ ์‚ญ์ œํ•œ๋‹ค.

๊ทธ ๋‹ค์Œ ์ธํ…”๋ฆฌ์ œ์ด๋กœ ๋‹ค์‹œ build.gradle์„ ์—ด์–ด์ค€๋‹ค.

 

๋นŒ๋“œ๊ฐ€ ๋๋‚œ ํ›„, file -> Project Structure ๋กœ ์ด๋™ํ•ด์ค€๋‹ค.

 

๋‚˜๋Š” SDK 17 ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค.

SDK ๋ฒ„์ „ํ™•์ธ ํ›„ , Project ํƒญ์—์„œ SDK ๋ฒ„์ „์„ ์„ ํƒํ•ด์ค€๋‹ค.

 

๊ทธ ๋‹ค์Œ ํ™•์ธ์„ ํ•ด์ฃผ๋ฉด...!

 

๋” ์ด์ƒ ์˜ค๋ฅ˜๊ฐ€ ๋œจ์ง€ ์•Š๋Š”๋‹ค !!

"Redirect๋ฅผ ์™œ ํ•„์š”ํ• ๊นŒ?"

 

PRG๋ฅผ ์•Œ์•„๋ณด๊ธฐ ์ „์— ๋จผ์ € Rediect์˜ ํ•„์š”์„ฑ์„ ์•Œ ํ•„์š”๊ฐ€ ์žˆ๋‹ค.

 

๋งŒ์•ฝ ์ƒํ’ˆ์„ ์ˆ˜์ •, ๊ฐœ๋ฐœํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐœ๋ฐœํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ณด์ž 

 

@PostMapping("/addForm")
public String addCafe(@ModelAttribute Cafe cafe){
    cafeRepository.save(cafe);
    return "basicCafe/cafe";
}

์นดํŽ˜ ์ •๋ณด๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ถ”๊ฐ€๋ฅผ ์™„๋ฃŒํ•œ ๋’ค ์ƒˆ๋กœ ๊ณ ์นจ์„ ๋ˆ„๋ฅด๊ฒŒ ๋œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?

 

๋˜‘๊ฐ™์€ ์ •๋ณด๋“ค์ด ๊ณ„์†ํ•ด์„œ ์ž…๋ ฅ๋  ๊ฒƒ์ด๋‹ค.

์ด๋Š” Redirect๋ฅผ ์„ค์ •ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ธ๋ฐ, ์ด๋ ‡๊ฒŒ๋˜๋ฉด ๋งˆ์ง€๋ง‰์œผ๋กœ ์„œ๋ฒ„์— ์ „์†กํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ์ถ”๊ฐ€ ๋ฉ”์„œ๋“œ๋ฅผ ๊ณ„์† ์‹คํ–‰์‹œํ‚จ๋‹ค.

POST, Redirect Get

 

PRG๋Š” ์ƒˆ๋กœ๊ณ ์นจ ์‹œ ๋˜‘๊ฐ™์€ ๋ฉ”์„œ๋“œ๊ฐ€ ๊ณ„์†ํ•ด์„œ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ๋ง‰์•„์ค€๋‹ค.

๋ง ๊ทธ๋Œ€๋กœ ๊ฒฝ๋กœ๋ฅผ ์šฐํšŒํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค. 

๋ฉ”์„œ๋“œ ์‹คํ–‰ ์™„๋ฃŒ ํ›„ ๋‹ค๋ฅธ ๊ฒฝ๋กœ๋กœ ํ˜ธ์ถœํ•ด์คŒ์œผ๋กœ์จ ์„œ๋ฒ„๋Š” ๋” ์ด์ƒ ๋˜‘๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ๋ฐ˜๋ณตํ•˜์ง€ ์•Š๊ฒŒ ๋œ๋‹ค!

 

 

๊ทธ๋Ÿผ ์ด์ œ ์œ„์—์„œ ๋ฌธ์ œ๋ฅผ ์ผ์œผ์ผฐ๋˜ ์ถ”๊ฐ€ ๋ฉ”์„œ๋“œ๋ฅผ ์ˆ˜์ •ํ•ด๋ณด์ž

 

@PostMapping("/addForm")
public String addCafe(@ModelAttribute Cafe cafe){
    cafeRepository.save(cafe);
    return "redirect:/basicCafe/cafes"+ cafe.getId();
}

 ์ด๋ ‡๊ฒŒ ๋ฉ”์„œ๋“œ๋ฅผ ์ˆ˜์ •ํ•ด์ฃผ๋ฉด ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ๋ฅผ ์ ์šฉ์‹œํ‚ด์œผ๋กœ์จ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ

"cafe.getId() ์ฒ˜๋Ÿผ URL์— ๋ณ€์ˆ˜๋ฅผ ๋”ํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ URL ์ธ์ฝ”๋”ฉ์ด ์•ˆ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์œ„ํ—˜ํ•˜๋‹ค."

์‰ฝ๊ฒŒ ์„ค๋ช…ํ•˜์ž๋ฉด ๋ณ€์ˆ˜์— ๋„์›Œ์“ฐ๊ธฐ๋‚˜ ํ•œ๊ธ€์ด ํฌํ•จ๋  ๊ฒฝ์šฐ ์„œ๋ฒ„๊ฐ€ ์ธ์‹ํ•  ์ˆ˜ ์žˆ๊ฒŒ url์ธ์ฝ”๋”ฉ์„ ํ•ด์ฃผ์–ด์•ผํ•˜๋Š”๋ฐ 

์ด๊ฒƒ์ด ์•ˆ๋œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

 

๊ฒฐ๊ตญ ๋˜ ๋‹ค๋ฅธ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ด๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋‘๊ฐ€์ง€ ํ•ด๊ฒฐ์ฑ…์ด ์ œ์‹œ๋˜์—ˆ๋‹ค.

 

์ฒซ๋ฒˆ์งธ, @PathVariable ์‚ฌ์šฉ

 

@PostMapping("/edit/{cafeId}")
public String edit(@PathVariable Long cafeId,@ModelAttribute Cafe cafe){
    cafeRepository.update(cafeId,cafe);
    return "redirect:/basic/items/{cafeId}";
}

 

@PathVariable ์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ์ปจํŠธ๋กค๋Ÿฌ์— ๋งคํ•‘๋œ ๊ฐ’๋„ Redirect ๊ฐ’์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

๋‘๋ฒˆ์งธ, RedirectAttributes ์‚ฌ์šฉ

 

@PostMapping("/addForm")
public String addCafe(@ModelAttribute Cafe cafe, RedirectAttributes redirectAttributes){
    Cafe savedCafe = cafeRepository.save(cafe);
    redirectAttributes.addAttribute("cafeId",savedCafe.getId());
    redirectAttributes.addAttribute("status",true);
    return "redirect:/basicCafe/items/{cafeId}";
}

 

RedirectAttributes ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด, URL ์ธ์ฝ”๋”ฉ๋„ ํ•ด์ฃผ๊ณ , pathVarible , ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ๊นŒ์ง€ ์ฒ˜๋ฆฌํ•ด์ค€๋‹ค.

์ด ๋ฉ”์„œ๋“œ๋Š” 

localhost:8080/basic/cafes/3?status=true

๋ฅผ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค.

 

๊ตณ์ด PathVariable์„ ์“ธ ํ•„์š”๋„ ์—†๊ณ  url ์ธ์ฝ”๋”ฉ ๊ฑฑ์ •๋„ ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. 

๊ฒŒ๋‹ค๊ฐ€ status ํŒŒ๋ผ๋ฏธํ„ฐ๊นŒ์ง€ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค !! (๋ฐ”์ธ๋”ฉ ๋˜์ง€ ์•Š์•˜์„ ๊ฒฝ์šฐ)

ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ํƒ€์ž„๋ฆฌํ”„ ๋ฌธ๋ฒ•์—์„œ ${param.status}๋กœ ์กฐํšŒ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค

 

ํƒ€์ž„๋ฆฌํ”„ ์‚ฌ์šฉ๋ฒ•

 

์ด ์‚ฌ์ง„์ฒ˜๋Ÿผ ํƒ€์ž„๋ฆฌํ”„ ์„ ์–ธ์„ ํ•ด์ฃผ์–ด์•ผํ•œ๋‹ค.

 

<html xmlns:th="http://www.thymeleaf.org">
th:href="@{/css/bootstrap.min.css}" 

ํƒ€์ž„๋ฆฌํ”„ ์„ ์–ธ์„ ํ•ด์ฃผ์–ด์•ผ ๋น„๋กœ์†Œ ํƒ€์ž„๋ฆฌํ”„ ๋ฌธ๋ฒ•์„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.

 

ํƒ€์ž„๋ฆฌํ”„๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด,

th:xx ์†์„ฑ์ด ๋ถ™์€ ๋ถ€๋ถ„์€ ์„œ๋ฒ„์‚ฌ์ด๋“œ์—์„œ ๋ Œ๋”๋ง ๋˜๋ฉฐ , ๊ธฐ์กด html ์†์„ฑ์ด ๋Œ€์ฒด๋œ๋‹ค.(th ์†์„ฑ์ด ์—†์œผ๋ฉด html ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ)

ํ•˜์ง€๋งŒ html ์„ ํŒŒ์ผ๋กœ ์ง์ ‘ ์—ด์—ˆ์„๋• th ์†์„ฑ์€ ๋ฌด์‹œ๋œ๋‹ค.

 

1.URL ๋งํฌ ํ‘œํ˜„์‹

th:onclick="|location.href='@{/basicCafe/items/edit/{cafeId}(cafeId=${cafe.id})}'|"

ํƒ€์ž„๋ฆฌํ”„๋Š” url๋งํฌ๋ฅผ @{...}๋กœ ํ‘œํ˜„ํ•œ๋‹ค.

์ด ๊ฒฝ์šฐ ์„œ๋ธ”๋ฆฟ ์ปจํ…์ŠคํŠธ๋ฅผ ์ž๋™์œผ๋กœ ํฌํ•จํ•œ๋‹ค.

 

2.๋ฆฌํ„ฐ๋Ÿด ๋Œ€์ฒด ๋ฌธ๋ฒ•

location.href='/basic/items/add'
th:onclick="'location.href=' + '\'' + @{/basic/items/add} + '\''"
th:onclick="|location.href='@{/basic/items/add}'|"

๋ฆฌํ„ฐ๋Ÿด ๋Œ€์ฒด ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ณต์žกํ•œ ํ‘œํ˜„์‹์„ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

3.๋ฐ˜๋ณต์ถœ๋ ฅ

์‚ฌ์šฉ์˜ˆ์‹œ

 

<tr th:each="item : ${items}">

<tr th:each="cafe:${cafes}">
    <td><a href="cafe.html" th:href="@{/basicCafe/items/{itemId}(itemId=${cafe.id})}" th:text="${cafe.id}">1</a></td>
    <td><a href="cafe.html" th:href="@{|/basicCafe/items/${cafe.id}|}" th:text="${cafe.cafeName}">ํ…Œ์ŠคํŠธ ์ƒํ’ˆ1</a></td>
    <td th:text="${cafe.open}">10000</td>
    <td th:text="${cafe.close}">10</td>
    <td th:text="${cafe.mocaPrice}">10</td>

</tr>

์ปฌ๋ ‰์…˜์˜ ์ˆ˜๋งŽ์€ <tr>,</tr> ํ•˜์œ„ ํƒœ๊ทธ๋“ค์„ ํฌํ•จํ•ด์„œ ์ƒ์„ฑ๋œ๋‹ค.

 

4.๋ณ€์ˆ˜ ํ‘œํ˜„์‹

th:text="${cafe.id}">1</a></td>

๋‚ด์šฉ์˜ ๊ฐ’์„ th:text ๊ฐ’์œผ๋กœ ๋ณ€๊ฒฝํ•ด์ค€๋‹ค.

 

5.๋งํฌ ํ‘œํ˜„์‹

th:href="@{/basic/items/{itemId}(itemId=${item.id})}
th:href="@{|/basic/items/${item.id}|}"

๋ฆฌํ„ฐ๋Ÿด ๋Œ€์ฒด ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ณต์žกํ•œ ๋งํฌ ํ‘œํ˜„์‹์„ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

"์ˆœ์ˆ˜ HTML์„ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•˜๋ฉด์„œ ๋ทฐ ํ…œํ”Œ๋ฆฟ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํƒ€์ž„๋ฆฌํ”„์˜ ํŠน์ง•์„ ๋„ค์ธ„๋Ÿด ํ…œํ”Œ๋ฆฟ์ด๋ผ ํ•œ๋‹ค."

'mvc ์›น ๊ฐœ๋ฐœ' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

ํ”„๋ก ํŠธ ์ปจํŠธ๋กค๋Ÿฌ  (0) 2022.02.08

์‹ค๋ฌด์—์„œ๋Š” printLn ์ด ์•„๋‹Œ ๋กœ๊น…์„ ํ†ตํ•˜์—ฌ ์ •๋ณด๋ฅผ ์ถœ๋ ฅํ•ด์•ผํ•œ๋‹ค.

 


@RestController
public class LogTestController {
    private final Logger log = LoggerFactory.getLogger(getClass());

    @RequestMapping("/log-test")
    public String logTest(){
        String name = "spring";

        log.trace("trace log = {}", name);
        log.debug("debug log = {}", name);
        log.info("info log = {}", name);
        log.warn("warn log = {}", name);
        log.error("error log = {}", name);

        log.debug("debug log={}",name);

        return "ok";
        
    }

 

๋จผ์ € ํด๋ž˜์Šค ๋ ˆ๋ฒจ์— ๋ถ™์€ @RestController ์—๋…ธํ…Œ์ด์…˜์€ ๋ฆฌํ„ด ๊ฐ’์„ Http ๋ฐ”๋””์— ๋ฐ”๋กœ ์ž…๋ ฅํ•ด์ค€๋‹ค.

(@Controller ๋Š” ๋ฐ˜ํ™˜๊ฐ’์„ ๋ทฐ ์ด๋ฆ„์œผ๋กœ ์ธ์‹ํ•œ๋‹ค.)

 

@Slf4j
@RestController
public class LogTestController {
    //private final Logger log = LoggerFactory.getLogger(getClass());

๋˜ํ•œ @sLf4j ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ๋กœ๊ทธ ์„ ์–ธ์„ ํ•ด์ค„ ํ•„์š”๊ฐ€ ์—†๋‹ค.

 

๋กœ๊ทธ๋ฅผ ๋ณด๋ฉด trace์™€ debug ๋กœ๊ทธ๊ฐ€ ์ฐํžˆ์ง€ ์•Š์€ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๋ฐ, ์ด๋Š” application.properties ์˜ ๊ธฐ๋ณธ ์„ค์ •๊ณผ ๊ด€๋ จ์ด ์žˆ๋‹ค.

 

# ๊ธฐ๋ณธ ์„ค์ •
logging.level.root=info
#debug ์ดํ•˜์˜ ๊ฐ’์„ ์ถœ๋ ฅํ•ด์ค€๋‹ค.
logging.level.hello.springmvc=debug

 

์ด๋ ‡๊ฒŒ ์„ค์ •์„ ํ•˜๊ณ  ๋‹ค์‹œ ๋กœ๊ทธ๋ฅผ ์ฐ์–ด๋ณด์ž

 

์ด๋Ÿฐ์‹์œผ๋กœ ๋กœ๊ทธ ์ถœ๋ ฅ ๋‹จ๊ณ„๋ฅผ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ๋‹ค.

(TRACE > DEBUG > INFO > WARN > ERROR)

 

log.debug("debug log={}"+name);

์ฐธ๊ณ ๋กœ ์ด์™€ ๊ฐ™์€ ์ถœ๋ ฅ ํ˜•์‹์€ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

์ถœ๋ ฅ ์—ฌ๋ถ€์™€ ๊ด€๊ณ„์—†์ด ๋ฌธ์ž์—ด + ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”๋ชจ๋ฆฌ ๋‚ญ๋น„๊ฐ€ ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

๋” ๋งŽ์€ ๊ธฐ๋Šฅ์€?

SLF4J

 

SLF4J

Simple Logging Facade for Java (SLF4J) The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for various logging frameworks (e.g. java.util.logging, logback, log4j) allowing the end user to plug in the desired logging framewor

www.slf4j.org

Logback Home (qos.ch)

 

Logback Home

Logback Project Logback is intended as a successor to the popular log4j project, picking up where log4j 1.x leaves off. Logback's architecture is quite generic so as to apply under different circumstances. At present time, logback is divided into three mod

logback.qos.ch

Core Features (spring.io)

 

Core Features

Spring Boot lets you externalize your configuration so that you can work with the same application code in different environments. You can use a variety of external configuration sources, include Java properties files, YAML files, environment variables, an

docs.spring.io

 

+ Recent posts