μμ
1.
κ°λ° νκ²½ μ€μΉ
a.
VS CODE μ€μΉ
b.
JDK μ€μΉ
c.
νμ₯ μ€μΉ
2.
μν€ν
μ² ν¨ν΄
a.
MVC
b.
REST API
3.
μ€μ΅
a.
κ²μν νλ‘μ νΈ
i.
MVC
ii.
REST
4.
μ§μμλ΅
κ°λ° νκ²½ μ€μΉ
1.
VS CODE μ€μΉ
2.
JDK μ€μΉ
3.
νμ₯ μ€μΉ
VS CODE μ€μΉ
VS CODE μ€ν νλ©΄
JDK μ€μΉ
νμ₯ μ€μΉ
1.
Java
2.
Spring
μν€ν μ² ν¨ν΄
1.
MVC
2.
REST API
MVC
μννΈμ¨μ΄λ₯Ό Model-View-Controller μ£Όμ ꡬμ±μμλ‘ λΆλ¦¬νμ¬ κ°λ°νλ λ°©λ²λ‘
β’
Model : λ°μ΄ν°μ λΉμ¦λμ€ λ‘μ§μ λ΄λΉ
β’
View : μ¬μ©μ μΈν°νμ΄μ€λ₯Ό νν
β’
Controller : λͺ¨λΈκ³Ό λ·°λ₯Ό μ μ΄νλ μν
μΉκ°λ°μμμ MVC ν¨ν΄
β’
Model: λ°μ΄ν°λ² μ΄μ€μ μνΈ μμ©νμ¬ λ°μ΄ν°λ₯Ό κ°μ Έμ€κ³ μ μ₯νλ λΆλΆ
β¦
Service
β¦
DTO
β¦
DAO
β’
View: μΉ νμ΄μ§λ₯Ό νννλ©°, μ¬μ©μμκ² λ³΄μ¬μ§λ λΆλΆ
β¦
jsp
β¦
html
β’
Controller: HTTP μμ²μ μ²λ¦¬νκ³ , μ μ ν λͺ¨λΈμ νΈμΆνμ¬ λ°μ΄ν°λ₯Ό κ°μ Έμ€κ³ , μ μ ν λ·°λ₯Ό μ ννμ¬, μ μ ν λ·° νμ΄μ§λ₯Ό μ ννμ¬ λ°ννλ λΆλΆ
β¦
Controller
Spring MVC ꡬ쑰
Spring Web MVC ꡬμ±μμ
1.
Dispatcher Servlet:
β’
μΉ μ ν리μΌμ΄μ
μ λͺ¨λ ν΄λΌμ΄μΈνΈ μμ²μ λ°μλ€μ΄κ³ μ²λ¦¬νλ ν΅μ¬ μλΈλ¦Ώμ
λλ€.
2.
Handler Mapping:
β’
ν΄λΌμ΄μΈνΈ μμ²μ μ²λ¦¬ν νΈλ€λ¬(컨νΈλ‘€λ¬)λ₯Ό κ²°μ νκΈ° μν κ·μΉμ μ μν©λλ€.
3.
Handler Adapter:
β’
μ νλ νΈλ€λ¬(컨νΈλ‘€λ¬)κ° μ€μ μμ²μ μ²λ¦¬νλ λ°©λ²μ κ²°μ νκ³ μ€νν©λλ€.
4.
View Resolver:
β’
νΈλ€λ¬(컨νΈλ‘€λ¬)μμ μ νλ λ·° μ΄λ¦μ λ·°λ‘ λ³ννκ³ μμ±νμ¬ ν΄λΌμ΄μΈνΈμ λ°νν©λλ€.
5.
Controller:
β’
ν΄λΌμ΄μΈνΈ μμ²μ λ°μλ€μ΄κ³ μ²λ¦¬νλ λΉμ¦λμ€ λ‘μ§μ ν¬ν¨νλ μ»΄ν¬λνΈμ
λλ€.
6.
Model:
β’
컨νΈλ‘€λ¬κ° μμ±ν λ°μ΄ν°λ₯Ό μ μ₯νκ³ λ·°μ μ λ¬νλ κ°μ²΄μ
λλ€.
7.
View:
β’
λ·° ν
νλ¦Ώ(μ: JSP, Thymeleaf)μ μ¬μ©νμ¬ λͺ¨λΈ λ°μ΄ν°λ₯Ό κΈ°λ°μΌλ‘ μ€μ μλ΅(HTML νμ΄μ§)μ μμ±νλ μ»΄ν¬λνΈμ
λλ€.
8.
Service:
β’
λΉμ¦λμ€ λ‘μ§μ ꡬννκ³ μ 곡νλ μλΉμ€ λ μ΄μ΄μ μ»΄ν¬λνΈμ
λλ€.
9.
Repository:
β’
λ°μ΄ν°λ² μ΄μ€μ μνΈμμ©νλ λ°μ΄ν° μ‘μΈμ€ λ μ΄μ΄μ μ»΄ν¬λνΈμ
λλ€. λ°μ΄ν°λ² μ΄μ€ μ°λ λ° λ°μ΄ν° κ΄λ¦¬λ₯Ό λ΄λΉν©λλ€.
MVC ν¨ν΄ λμ μμ
1.
ν΄λΌμ΄μΈνΈκ° μλ²μ μμ²μ νλ©΄, Front controllerμΈ DispatcherServlet ν΄λμ€κ° μμ²μ λ°λλ€.
2.
DispatcherServletμ νλ‘μ νΈ νμΌ λ΄μ servlet-context.xml νμΌμ @Controller μΈμλ₯Ό ν΅ν΄ λ±λ‘ν μμ² μμ 컨νΈλ‘€λ¬λ₯Ό μ°Ύμ λ©ν(mapping)λ 컨νΈλ‘€λ¬κ° μ‘΄μ¬νλ©΄ @RequestMappingμ ν΅ν΄ μμ²μ μ²λ¦¬ν λ©μλλ‘ μ΄λνλ€.
3.
컨νΈλ‘€λ¬λ ν΄λΉ μμ²μ μ²λ¦¬ν Service λ₯Ό λ°μ λΉμ¦λμ€ λ‘μ§μ μλΉμ€μκ² μμνλ€.
4.
Service λ μμ²μ νμν μμ
μ μννκ³ , μμ²μ λν΄ DBμ μ κ·Όν΄μΌνλ€λ©΄ DAOμ μμ²νμ¬ μ²λ¦¬λ₯Ό μμνλ€.
5.
DAOλ DBμ 보λ₯Ό DTOλ₯Ό ν΅ν΄ λ°μ μλΉμ€μκ² μ λ¬νλ€.
6.
μλΉμ€λ μ λ¬λ°μ λ°μ΄ν°λ₯Ό 컨νΈλ‘€λ¬μκ² μ λ¬νλ€.
7.
컨νΈλ‘€λ¬λ Model(λͺ¨λΈ) κ°μ²΄μκ² μμ²μ λ§λ View(λ·°) μ 보λ₯Ό λ΄μ DispatcherServletμκ² μ μ‘νλ€.
8.
DispatcherServletμ ViewResolverμκ² μ λ¬λ°μ View μ 보λ₯Ό μ λ¬νλ€.
9.
ViewResolverλ μλ΅ν Viewμ λν JSPλ₯Ό μ°Ύμ DispatcherServletμκ² μ λ¬νλ€.
10.
DispatcherServletμ μλ΅ν λ·°μ λ λλ§λ₯Ό μ§μνκ³ λ·°λ λ‘μ§μ μ²λ¦¬νλ€.
11.
DispatcherServletμ ν΄λΌμ΄μΈνΈμκ² λ λλ§λ λ·°λ₯Ό μλ΅νλ©° μμ²μ λ§μΉλ€.
REST API
REST (Representational State Transfer)
μν νν μ μ‘ μν€ν
μ²
present [prΙͺΛzent]
: 보μ¬μ£Όλ€
represent [ΛreprΙͺΛzent]
: λ€μ 보μ¬μ£Όλ€, λμ νννλ€
re-(λ€μ) + present(보μ¬μ£Όλ€) λ€μ 보μ¬μ£Όλ€, λννλ€, λλ³νλ€
representational [ ΛreprΙͺzenΛteΙͺΚnl ]
: νννλ, 보μ¬μ£Όλ
REST
μν νν μ μ‘ μν€ν μ²
μμμ μνλ₯Ό νννμ¬ μ λ¬νλ μν€ν
μ²
URI λ‘ μμμ λμ νμ¬ νννκ³ , μλ²κ° ν΄μΌ ν νμ(μλ²μ μν)λ₯Ό HTTP λ©μλλ‘ νννλ κ²μ μμΉμΌλ‘ νλ μν€ν
μ²
β’
λ€νΈμν¬ μν€ν
μ² μ€μ νλμ
λλ€.
β’
νλ‘ νΈμλ λ° λ°±μλμ λ
립μ±κ³Ό νμ₯μ± ν₯μμν΅λλ€.
Overview
β’
REST μμΈν μμ보기
β’
RESTful
β’
RESTful API
β’
CRUD
β’
RESTful CRUD
β’
REST μν€ν
μ²λ₯Ό μ¬μ©νλ μ΄μ
β’
Server Side Rendering (SSR)
β’
Client Side Rendering (CSR)
β’
Non-RESTful VS RESTful
β’
REST μν€ν
μ²μ 6κ°μ§ μμΉ
REST μμΈν μμ보기
2000 λ
λ‘μ΄ νλ© (Roy Fielding) μ λ°μ¬ λ
Όλ¬Έμμ μκ°λ κ°λ
μ΄λ€.
REST μν€ν
μ²λ₯Ό μ μν ν΅μ¬ μΈλ¬Ό μ€ ν λͺ
μΌλ‘, HTTP νλ‘ν μ½κ³Ό μλ μμ΄λ μΉ (WWW)μ ν΅μ¬ νμ€νμ κΈ°μ¬νμ΅λλ€. νλ©μ κ·Έμ λ°μ¬νμ λ
Όλ¬Έμμ REST(Representational State Transfer) μν€ν
μ²λ₯Ό μκ°νμ¬, λΆμ° νμ΄νΌλ―Έλμ΄ μμ€ν
μ μν μ€κ³ μμΉμ μ μνμ΅λλ€. μ΄ν λ§μ μΉ μλΉμ€μ APIκ° REST μν€ν
μ² μ€νμΌμ μ μ©νμ¬ κ΅¬μΆλμμ΅λλ€.
RESTλ Representational State Transferμ μ½μλ‘, μΉ κ°λ°μμ λ€νΈμν¬ μ ν리μΌμ΄μ
μ μ€κ³νλ λ° μμ£Ό μ¬μ©λλ μν€ν
μ² μ€νμΌμ
λλ€. RESTμ μμΉμ μ€μνλ RESTful APIλ λ€λ₯Έ μμ€ν
κ°μ HTTPλ₯Ό ν΅ν΄ ν΅μ νκ³ λ°μ΄ν°λ₯Ό κ΅νν μ μκ² ν΄μ€λλ€.
RESTλ κ°λ¨νκ³ μ μ°ν μν€ν
μ²λ‘, μμμ URI(Uniform Resource Identifier)λ‘ νννκ³ , HTTP λ©μλ(GET, POST, PUT, DELETE λ±)λ₯Ό μ¬μ©νμ¬ ν΄λΉ μμμ λν μ‘μ
μ μνν©λλ€. λν, RESTful APIλ μνλ₯Ό κ΄λ¦¬νμ§ μκ³ , μμ²μ νμν λͺ¨λ μ 보λ₯Ό μμ² μ체μ ν¬ν¨μν΅λλ€.
μ΄λ¬ν RESTful APIμ μ₯μ μ λ€μκ³Ό κ°μ΅λλ€:
β’
κ°κ²°μ±: μ§κ΄μ μ΄κ³ κ°κ²°ν μΈν°νμ΄μ€λ₯Ό μ 곡ν©λλ€.
β’
νμ₯μ±: μμ€ν
μ λμ¨νκ² κ²°ν©νμ¬ νμ₯μ΄ μ©μ΄ν©λλ€.
β’
κ°μμ±: μμμ λν νμ€νλ μΈν°νμ΄μ€λ₯Ό μ 곡νλ―λ‘, κ°λ°μλ€μ΄ APIλ₯Ό μ΄ν΄νκ³ μ¬μ©νκΈ° μ½μ΅λλ€.
λ°λΌμ, RESTful APIλ νλμ μΈ μΉ κ°λ°μμ λ§€μ° μ€μν μν μ λ΄λΉνκ³ μμΌλ©°, λ§μ μΉ μ ν리μΌμ΄μ
κ³Ό μλΉμ€κ° RESTλ₯Ό κΈ°λ°μΌλ‘ ꡬμΆλκ³ μμ΅λλ€.
RESTful
: REST μν€ν
μ²λ₯Ό λ°λ₯΄λ μμ€ν
λλ μλΉμ€λ₯Ό κ°λ¦¬ν€λ μ©μ΄μ
λλ€
RESTful API
REST μν€ν
μ² μμΉμ λ°λ₯΄λ APIλ‘, RESTful μλΉμ€λ₯Ό μν μΈν°νμ΄μ€μ
λλ€. μ΄ APIλ μΉ μλΉμ€λ₯Ό ꡬμΆνκ±°λ ν΅ν©νλ λ° μ¬μ©λ©λλ€.
μ£Όλ‘ HTTPλ₯Ό κΈ°λ°μΌλ‘ νλ©°, μμμ URLλ‘ νννκ³ HTTP λ©μλ(GET, POST, PUT, DELETE λ±)λ₯Ό μ¬μ©νμ¬ μμμ κ΄λ¦¬νλ©°, JSON λλ XMLκ³Ό κ°μ λ°μ΄ν° νμμ ν΅ν΄ λ°μ΄ν°λ₯Ό κ΅νν©λλ€.
RESTful APIλ κ°λ¨νκ³ μ§κ΄μ μ΄λ©°, μλ²μ ν΄λΌμ΄μΈνΈ μ¬μ΄μ ν΅μ μ ν¨μ¨μ μΌλ‘ μννλ λ° λμμ΄ λ©λλ€.
CRUD
CRUDλ λ°μ΄ν°μ κΈ°λ³Έμ μΈ μμ
μ λνλ΄λ μ½μ΄λ‘, Create(μμ±), Read(μ½κΈ°), Update(μμ ), Delete(μμ )μ λ€ κ°μ§ κΈ°λ³Έ μμ
μ λ§ν©λλ€. μ΄ λ€ κ°μ§ μμ
μ μ£Όλ‘ λ°μ΄ν°λ² μ΄μ€μ κ΄λ ¨λ μμ
μμ μ¬μ©λ©λλ€:
RESTful CRUD
CRUD μμ
| μμ² λ©μλ | μ€λͺ
|
Create | POST | μλ‘μ΄ λ°μ΄ν° λ μ½λλ₯Ό μμ± |
Read | GET | λ°μ΄ν°λ₯Ό μ½κ±°λ μ‘°ν |
Update | PUT/PATCH | λ°μ΄ν° λ μ½λλ₯Ό μμ λλ κ°±μ |
Delete | DELETE | λ°μ΄ν°λ₯Ό μμ |
RESTful APIλ μ΄λ¬ν HTTP λ©μλλ₯Ό μ¬μ©νμ¬ μλ²μ μμμ κ΄λ¦¬νλ λ° νμ©λ©λλ€. μλ₯Ό λ€μ΄, POST μμ²μ ν΅ν΄ μλ‘μ΄ λ°μ΄ν°λ₯Ό μμ±νκ³ , GET μμ²μ ν΅ν΄ λ°μ΄ν°λ₯Ό μ½κ±°λ μ‘°ννλ©°, PUT λλ PATCH μμ²μ ν΅ν΄ λ°μ΄ν°λ₯Ό μμ νκ³ , DELETE μμ²μ ν΅ν΄ λ°μ΄ν°λ₯Ό μμ ν μ μμ΅λλ€. μ΄λ¬ν HTTP λ©μλλ₯Ό μ΄μ©νμ¬ κ°κ°μ CRUD μμ
μ μννλ κ²μ΄ RESTful APIμ μ£Όμ νΉμ§ μ€ νλμ
λλ€.
REST μν€ν μ²λ₯Ό μ¬μ©νλ μ΄μ
RESTful APIλ μΌλ°μ μΌλ‘ HTTP νλ‘ν μ½μ λ°λ₯΄κ³ , μμ²κ³Ό μλ΅μ νμ€νλ λ°©μμΌλ‘ μ²λ¦¬ν¨μΌλ‘μ¨, λ€μν μΈμ΄λ νλ«νΌ κ°μ μνΈμ΄μ©μ±μ 보μ₯ν©λλ€. μ΄λ νλ‘ νΈμλμ λ°±μλλ₯Ό λΆλ¦¬νκ³ , κ° μμμ λ
립μ μΌλ‘ κ°λ°ν λ λ§€μ° μ μ©ν©λλ€. λ°λΌμ νλ‘ νΈμλμ λ°±μλλ₯Ό λ
립μ μΌλ‘ κ°λ°νλ κ²½μ° RESTful APIλ₯Ό μ¬μ©νλ κ²μ΄ μΌλ°μ μΌλ‘ κΆμ₯λ©λλ€.
REST λ λ€νΈμν¬ μν€ν
μ²μ μΌμ’
μ
λλ€.
μ£Όμ λ€νΈμν¬ μν€ν μ² μ’ λ₯
1.
κ³μΈ΅νλ μν€ν
μ²(Layered Architecture)
: λ€νΈμν¬ μμ€ν
μ΄ μ¬λ¬ κ³μΈ΅μΌλ‘ ꡬμ±λμ΄ μμΌλ©°, κ° κ³μΈ΅μ νΉμ ν μν κ³Ό μ±
μμ κ°μ΅λλ€. OSI 7κ³μΈ΅ λͺ¨λΈμ΄ μ΄λ¬ν κ³μΈ΅ν μν€ν
μ²μ ν μμ
λλ€.
2.
RESTful μν€ν
μ²(Representational State Transfer)
: RESTλ ν΄λΌμ΄μΈνΈμ μλ² κ°μ ν΅μ μ μν μΉ μν€ν
μ²μ ν ννλ‘, 리μμ€λ₯Ό URLμ ν΅ν΄ μλ³νκ³ HTTP λ©μλλ₯Ό μ¬μ©νμ¬ λ¦¬μμ€μ μ κ·Όνλ μν€ν
μ² μμΉμ
λλ€.
3.
λ§μ΄ν¬λ‘μλΉμ€ μν€ν
μ²(Microservices Architecture)
: μ΄ μν€ν
μ²λ μ ν리μΌμ΄μ
μ μ¬λ¬ μμ μλΉμ€λ‘ λΆν νμ¬ κ° μλΉμ€κ° λ
립μ μΌλ‘ ꡬμ±λκ³ μ€νλλλ‘ νλ ꡬ쑰λ₯Ό λ§ν©λλ€.
Server Side Rendering (SSR)
μλ² μΈ‘ λ λλ§(Server-Side Rendering, SSR)μ μ¬μ©μκ° μΉνμ΄μ§μ μ μνμ λ, μλ²μμ ν΄λΉ νμ΄μ§λ₯Ό μμ ν λ λλ§νκ³ μμ±λ HTML λ¬Έμλ‘ ν΄λΌμ΄μΈνΈμκ² μ 곡νλ κΈ°μ μ
λλ€. ν΄λΌμ΄μΈνΈμμλ μλ²λ‘λΆν° μ λ¬λ μμ±λ HTMLμ λ°μ νλ©΄μ νμνλ λ°©μμ
λλ€.
Client Side Rendering (CSR)
ν΄λΌμ΄μΈνΈ μΈ‘ λ λλ§ (Client-Side Rendering λλ CSR)μ μΉ μ ν리μΌμ΄μ
μ μ¬μ©μμ λΈλΌμ°μ μμ JavaScriptλ₯Ό μ¬μ©νμ¬ μμ ν λ λλ§νλ νλ‘μΈμ€λ₯Ό μλ―Έν©λλ€. μ΄ λ°©μμ μΉ μ ν리μΌμ΄μ
μ μ μ νμΌμ λ‘λνκ³ μ¬μ©μ μνΈ μμ©μ λ°λΌ APIμμ λ°μ΄ν°λ₯Ό κ°μ Έμ DOMμ μ‘°μνμ¬ λ΄μ©μ λμ μΌλ‘ νμν©λλ€.
CSR(Client-Side Rendering)μμλ μ£Όλ‘ JSON λλ XMLκ³Ό κ°μ λ°μ΄ν°λ₯Ό λ°μ μλ°μ€ν¬λ¦½νΈλ‘ λ λλ§νκ³ , React, Vue, Angular λ±μ νλ μμν¬ λλ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νμ¬ ν΄λΌμ΄μΈνΈ μΈ‘μμ μΉ μ ν리μΌμ΄μ
μ λ λλ§μ λ΄λΉν©λλ€. νμ΄μ§ λ‘λ© ν, νλ‘ νΈμλ λΌμ΄λΈλ¬λ¦¬κ° μλ²μμ λ°μ λ°μ΄ν°λ₯Ό λμ μΌλ‘ λ λλ§νμ¬ μ¬μ©μμκ² λ³΄μ¬μ€λλ€. μ΄ κ³Όμ μ ν΄λΌμ΄μΈνΈ μΈ‘μμ μ΄λ£¨μ΄μ§λ―λ‘ λΈλΌμ°μ μμ λΉ λ₯΄κ² νλ©΄μ νμν μ μμ΅λλ€.
Non-RESTful μμ€ν
Non-RESTful μμ€ν
μ REST μν€ν
μ²μ μμΉμ λ°λ₯΄μ§ μλ μμ€ν
μ μλ―Έν©λλ€. μ΄λ¬ν μμ€ν
μ RESTμ κΈ°λ³Έ μμΉ μ€ μΌλΆ λλ μ ν μ μ©λμ§ μμ μ μμ΅λλ€.
λΉRESTful μμ€ν
μμλ μμμ URIλ‘ νννλ κ²μ΄ λΆλͺ
ννκ±°λ μΌκ΄μ±μ΄ μμ μ μμ΅λλ€. λν, HTTP λ©μλλ₯Ό μ¬λ°λ₯΄κ² μ¬μ©νμ§ μκ±°λ, Hypermediaλ₯Ό νμ©νμ§ μλ λ± REST μν€ν
μ²μμ κ·μ ν μμΉμ λ°λ₯΄μ§ μλ νΉμ±μ λ³΄μΌ μ μμ΅λλ€.
RESTful μμ€ν
RESTful μμ€ν
μ RESTμ κΈ°λ³Έ μμΉμΈ μμ μλ³, μκΈ°μμ ν λ©μμ§, HATEOAS(νμ΄νΌλ―Έλμ΄ μ μ΄ μν) λ±μ μ μ©νλ μμ€ν
μ κ°λ¦¬ν΅λλ€. μ΄λ¬ν μμ€ν
μ μΌκ΄λ URI, HTTP λ©μλμ μ¬μ©, Hypermediaμ μ κ·Ήμ μΈ νμ©κ³Ό κ°μ REST μν€ν
μ²μ μμΉμ λ°λ₯΄λ©°, μ΄λ₯Ό ν΅ν΄ νμ₯μ±κ³Ό μ μ§λ³΄μμ±μ΄ ν₯μλ©λλ€.
Non-RESTful VS RESTful
REST μν€ν μ²μ 6κ°μ§ μμΉ
1.
μΈν°νμ΄μ€ μΌκ΄μ± (Uniform Interface)
2.
무μν (Stateless)
3.
μΊμ± κ°λ₯ (Cacheable)
4.
κ³μΈ΅ν (Layered System)
5.
Code on Demand
6.
ν΄λΌμ΄μΈνΈ/μλ² κ΅¬μ‘° (Client/Server Architecture)
μΈν°νμ΄μ€ μΌκ΄μ± (Uniform Interface)
μΌκ΄μ μΈ μΈν°νμ΄μ€λ‘ λΆλ¦¬λμ΄μΌ νλ€.
REST μΈν°νμ΄μ€λ μΌκ΄μ±μ κ°μ ΈμΌ ν©λλ€. μ΄λ 리μμ€μ μ κ·Όνλ λ°©λ²μ΄ μΌκ΄λμ΄μΌ ν¨μ μλ―Έν©λλ€. 리μμ€μ λν μ 보λ 리μμ€ μλ³μμ ν¨κ» μμ²λλ©°, μλ²λ 리μμ€ μνλ₯Ό ν΄λΌμ΄μΈνΈμκ² μ λ¬ν©λλ€.
무μν (Stateless)
κ° μμ² κ° ν΄λΌμ΄μΈνΈμ μ½ν
μ€νΈκ° μλ²μ μ μ₯λμ΄μλ μ λλ€
μμ² κ° μν μ 보λ₯Ό μ μ§νμ§ μλ μμΉμ
λλ€. κ° μμ²μ κ·Έ μμ² μ체μ νμν λͺ¨λ μ 보λ₯Ό ν¬ν¨ν΄μΌ νλ©°, μλ²λ κ° μμ²μ λ³κ°μ μμ²μΌλ‘ μ·¨κΈν΄μΌ ν©λλ€.
μΊμ± κ°λ₯ (Cacheable)
WWWμμμ κ°μ΄ ν΄λΌμ΄μΈνΈλ μλ΅μ μΊμ±ν μ μμ΄μΌ νλ€.
ν΄λΌμ΄μΈνΈλ μλ΅μ μΊμ±ν μ μμ΄μΌ ν©λλ€. μλ²λ μλ΅μ μΊμ μ μ΄ ν€λλ₯Ό μΆκ°νμ¬ μΊμ± λμμ μ‘°μ ν μ μμ΅λλ€.
μΊμ±
μΊμ±μ μμ£Ό μ¬μ©λλ λ°μ΄ν°λ₯Ό 미리 μ μ₯ν΄λκ³ νμν λλ§λ€ λΉ λ₯΄κ² μ¬μ©νλλ‘ νλ κΈ°μ μ
λλ€.
κ³μΈ΅ν (Layered System)
ν΄λΌμ΄μΈνΈλ λμ μλ²μ μ§μ μ°κ²°λμλμ§, μ°κ²°λμλμ§λ₯Ό μ μ μλ€.
RESTλ κ³μΈ΅νλ ꡬ쑰λ₯Ό κ°μ§λλ€. μλ²λ λ€μν κ³μΈ΅μΌλ‘ λλμ΄ μμΌλ©°, ν΄λΌμ΄μΈνΈλ μλ²μ μ§μ ν΅μ νμ§λ§, μ€μ μλ²κ° μ²λ¦¬λλ μμΉλ₯Ό μ νμκ° μμ΅λλ€.
Code on Demand
μλ²κ° ν΄λΌμ΄μΈνΈκ° μ€νμν¬ μ μλ λ‘μ§μ μ μ‘νμ¬ κΈ°λ₯μ νμ₯μν¬ μ μλ€.
"Code on Demand"λ 리μμ€κ° μλ²μμ ν΄λΌμ΄μΈνΈλ‘ 보λ΄μ§λ λμμ ν΄λΌμ΄μΈνΈμκ² μ€ν κ°λ₯ν μ½λλ₯Ό μ μ‘νμ¬, ν΄λΌμ΄μΈνΈκ° μ€νν μ μλ κΈ°λ₯μ νμ₯νλ μμΉμ κ°λ¦¬ν΅λλ€. ν΄λΌμ΄μΈνΈλ μ΄ μ½λλ₯Ό μ€νν μ μμ΄μΌ νλ©°, μΌλ°μ μΌλ‘ JavaScriptκ° κ°μ₯ μΌλ°μ μΈ μ¬μ© μ¬λ‘μ
λλ€.
ν΄λΌμ΄μΈνΈ/μλ² κ΅¬μ‘° (Client/Server Architecture)
ν΄λΌμ΄μΈνΈ-μλ²μ κ° ννΈκ° λ
립μ μΌλ‘ κ°μ λ μ μλλ‘ ν΄μ€λ€.
RESTλ ν΄λΌμ΄μΈνΈμ μλ²κ° λΆλ¦¬λμ΄μΌ νλ€λ μμΉμ
λλ€. μλ²λ λ°μ΄ν° μ μ₯, κ΄λ¦¬, λ°±μλ λ‘μ§μ μ²λ¦¬νκ³ , ν΄λΌμ΄μΈνΈλ μ¬μ©μ μΈν°νμ΄μ€λ₯Ό μ 곡νκ³ μ¬μ©μ μμ²μ μλ²λ‘ μ μ‘ν©λλ€.
REST μν€ν μ²μ URL λͺ λͺ κ·μΉ
λͺ μ¬ μ¬μ©
: URLμ 리μμ€λ₯Ό λνλ΄λ©°, 리μμ€μ λν λμμ HTTP λ©μλλ₯Ό ν΅ν΄ μνλλ―λ‘, λͺ
μ¬λ₯Ό μ¬μ©νμ¬ λ¦¬μμ€λ₯Ό λνλ΄λ κ²μ΄ μ’μ΅λλ€.
볡μν μ¬μ©
: 리μμ€λ₯Ό λνλΌ λ 볡μνμ μ¬μ©νλ κ²μ΄ μ’μ΅λλ€. μλ₯Ό λ€μ΄, /users, /postsμ κ°μ΄ 리μμ€ λ³΅μνμ μ¬μ©ν©λλ€.
νμ 리μμ€λ₯Ό μν μ€μ²© URL μ¬μ©
: κ΄κ³κ° μλ 리μμ€μ κ²½μ°, μ€μ²© URL ꡬ쑰 (/super/sub) λ₯Ό μ¬μ©νμ¬ κ΄κ³λ₯Ό λͺ
νν ν©λλ€.
νμ΄ν(-) λμ μΈλμ€μ½μ΄(_) μ¬μ©
: κ°λ
μ±μ λμ΄κ³ μλ³μ μ½κ² νκΈ° μν΄ μΈλ μ€μ½μ΄(_)λ₯Ό μ¬μ©νλ κ²μ΄ μ’μ΅λλ€.
(λ¨, 리μμ€ μ΄λ¦μ λμ΄μ°κΈ°λ νμ΄ν(-) μ¬μ©)
λ¨μνκ³ μ§κ΄μ μΈ URL
: URLμ 리μμ€λ₯Ό μλ³νλ λ° μ¬μ©λλ©°, μ΄κ²μ μ§κ΄μ μ΄κ³ λͺ
νν΄μΌ ν©λλ€. νλμ 리μμ€μ νλμ URL μ λμνλ κ²μ΄ μ’μΌλ©° νμΌ νμ₯μ (.html, .jsp λ±)λ₯Ό μ¬μ©νμ§ μμ΅λλ€.
μ€νλ§λΆνΈλ‘ RESTful API ꡬννκΈ°
1.
@RestController ν΄λμ€ μ μ
2.
GET, POST, PUT, DELETE 컨νΈλ‘€λ¬ λ©μλ μ μ
@RestController ν΄λμ€ μ μ
/**
* π’ RestFul
* κ²μν 컨νΈλ‘€λ¬
* - κ²μκΈ λͺ©λ‘ - [GET] - /board
* - κ²μκΈ μ‘°ν - [GET] - /board/10
* - κ²μκΈ λ±λ‘ μ²λ¦¬ - [POST] - /board
* - κ²μκΈ μμ μ²λ¦¬ - [PUT] - /board
* - κ²μκΈ μμ μ²λ¦¬ - [DELETE] - /board/10
*/
@Slf4j
@RestController
@RequestMapping("/posts")
public class RestBoardController {
}
Java
볡μ¬
GET, POST, PUT, DELETE 컨νΈλ‘€λ¬ λ©μλ μ μ
β’
κ²μκΈ λͺ©λ‘ - [GET] - /board
β’
κ²μκΈ μ‘°ν - [GET] - /board/10
β’
κ²μκΈ λ±λ‘ μ²λ¦¬ - [POST] - /board
β’
κ²μκΈ μμ μ²λ¦¬ - [PUT] - /board
β’
κ²μκΈ μμ μ²λ¦¬ - [DELETE] - /board/10
κ²μκΈ λͺ©λ‘ - [GET] - /board
/**
* κ²μκΈ λͺ©λ‘
* [GET]
* /board
* response : boardList
* @return
*/
@GetMapping()
public ResponseEntity<?> findAll() {
log.info("[GET] - /board");
try {
List<Board> boardList = boardService.list();
return new ResponseEntity<>(boardList, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Java
볡μ¬
κ²μκΈ μ‘°ν - [GET] - /board/10
/**
* κ²μκΈ μ‘°ν
* [GET]
* /board/{id}
* request : id
* response : board
* @param id - κ²μκΈ λ²νΈ
* @return
*/
@GetMapping("/{id}")
public ResponseEntity<?> find(@PathVariable Integer id) {
log.info("[GET] - /board/" + id);
try {
Board board = boardService.select(id);
return new ResponseEntity<>(board, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Java
볡μ¬
κ²μκΈ λ±λ‘ μ²λ¦¬ - [POST] - /board
/**
* κ²μκΈ λ±λ‘
* [POST]
* /board
* request : board
* response : β, β
* @param board
* @return
*/
@PostMapping()
public ResponseEntity<?> create(@RequestBody Board board) {
log.info("[POST] - /board");
try {
int result = boardService.insert(board);
if( result == 0 )
return ResponseEntity.badRequest().build();
return new ResponseEntity<>("CREATED", HttpStatus.CREATED);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Java
볡μ¬
κ²μκΈ μμ μ²λ¦¬ - [PUT] - /board
/**
* κ²μκΈ μμ
* [PUT]
* /board
* request : board
* response : β, β
* @param board
* @return
*/
@PutMapping()
public ResponseEntity<?> update(@RequestBody Board board) {
log.info("[PUT] - /board");
try {
int result = boardService.update(board);
if( result == 0 )
return ResponseEntity.badRequest().build();
return new ResponseEntity<>("UPDATED", HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Java
볡μ¬
κ²μκΈ μμ μ²λ¦¬ - [DELETE] - /board/10
/**
* κ²μκΈ μμ
* [DELETE]
* /board/{id}
* request : id
* response : β, β
* @param id
* @return
*/
@DeleteMapping("/{id}")
public ResponseEntity<?> delete(@PathVariable Integer id) {
log.info("[DELETE] - /board/" + id);
try {
int result = boardService.delete(id);
if( result == 0 )
return ResponseEntity.badRequest().build();
return ResponseEntity.ok().build();
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Java
볡μ¬
μ€μ΅
κ²μν νλ‘μ νΈ
1.
MVC
2.
REST
MVC κΈ°λ° κ²μν νλ‘μ νΈ
νλ‘μ νΈ κ΅¬μ‘°
π¦Β spring-mybatis
β
ββββπjava
β ββββπcom.aloha.springmybatis
β β
β ββββπcontroller
β β ββββπBoardController.java
β β
β ββββπdto
β β ββββπBoard.java
β β
β ββββπservice
β β β
β β ββββπBoardService.java
β β ββββπBoardServiceImpl.java
β β
β ββββπmapper
β ββββπBoardMapper.java
β
ββββπresources
β πapplication.properties
β πmybatis-config.xml
β
ββββπcom.aloha.springmybatis.mapper
βββββπBoardMapper.xml
Plain Text
볡μ¬
μ€νλ§ λΆνΈμμ MyBatis μ¬μ©
SpringBoot μμ MyBatisλ₯Ό μ¬μ©ν λμλ
μ£Όλ‘ Gradel λΉλλꡬμ μ€μ νμΌμ build.gradle λλ
Maven λΉλλꡬμ μ€μ νμΌμΈ pom.xml μ μμ‘΄μ±μ μΆκ°νμ¬ μ¬μ©ν©λλ€
μμ‘΄μ± μΆκ°
β’
build.gradle
β’
pom.xml
build.gradle
β’
mysql λλΌμ΄λ² μμ‘΄μ±
β’
MyBatis μμ‘΄μ±
β’
build.gradle μ 체μ½λ
mysql λλΌμ΄λ² μμ‘΄μ±
runtimeOnly 'com.mysql:mysql-connector-j'
Java
볡μ¬
MyBatis μμ‘΄μ±
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3'
testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:3.0.3'
Java
볡μ¬
springboot v3 λ²μ μ κΈ°μ€μΌλ‘ μ¬μ©ν μμ‘΄μ±μ
λλ€.
build.gradle
plugins {
id 'java'
id 'war'
id 'org.springframework.boot' version '3.2.5'
id 'io.spring.dependency-management' version '1.1.4'
}
group = 'com.aloha'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '17'
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:3.0.3'
}
tasks.named('test') {
useJUnitPlatform()
}
Java
볡μ¬
pom.xml
β’
mysql λλΌμ΄λ² μμ‘΄μ±
β’
MyBatis μμ‘΄μ±
β’
build.gradle μ 체μ½λ
mysql λλΌμ΄λ² μμ‘΄μ±
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
<scope>runtime</scope>
</dependency>
XML
볡μ¬
MyBatis μμ‘΄μ±
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter-test</artifactId>
<version>3.0.3</version>
<scope>test</scope>
</dependency>
XML
볡μ¬
springboot v3 λ²μ μ κΈ°μ€μΌλ‘ μ¬μ©ν μμ‘΄μ±μ
λλ€.
build.gradle
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.aloha</groupId>
<artifactId>your-artifact-id</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter-test</artifactId>
<version>3.0.3</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>3.2.5</version>
</plugin>
</plugins>
</build>
</project>
XML
볡μ¬
λ§μ΄λ°ν°μ€ μ€μ νμΌ - mybatis-config.xml
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- μ€μ -->
<settings>
<!-- μΈλμ€μ½μ΄ μΌμ΄μ€μΈ 컬λΌμ μΉ΄λ© μΌμ΄μ€λ‘ λ³ννλ μ€μ -->
<!-- board_no - boardNo -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!-- νμ
λ³μΉ μ€μ -->
<typeAliases>
<!-- ν
μ΄λΈκ³Ό 맀νν DTOκ° μλ ν¨ν€μ§ κ²½λ‘ μ§μ -->
<package name="com.aloha.springmybatis.dto"/>
</typeAliases>
</configuration>
XML
볡μ¬
mapUnderscoreToCamelCase
<settings>
<!-- μΈλμ€μ½μ΄ μΌμ΄μ€μΈ 컬λΌμ μΉ΄λ© μΌμ΄μ€λ‘ λ³ννλ μ€μ -->
<!-- board_no - boardNo -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
XML
볡μ¬
μΈλμ€μ½μ΄ μΌμ΄μ€(μ€λ€μ΄ν¬ μΌμ΄μ€)λ₯Ό μΉ΄λ© μΌμ΄μ€λ‘ μλ λ³νν΄μ£Όλ κΈ°λ₯ νμ±ν
μ΄λ κ² μμ±νλ©΄ λ°μ΄ν°λ² μ΄μ€μ μΈλμ€μ½μ΄ μΌμ΄μ€λ₯Ό λ³λλ‘ μλ°μ μΉ΄λ© μΌμ΄μ€λ‘ λ³ννμ§ μμλ μλμΌλ‘ ν
μ΄λΈμ 컬λΌλͺ
μ κ°μ²΄μ λ³μλ‘ λ§€ν ν μ μκ² λ³νν΄μ€λλ€.
typeAliases - package
<typeAliases>
<!-- ν
μ΄λΈκ³Ό 맀νν DTOκ° μλ ν¨ν€μ§ κ²½λ‘ μ§μ -->
<package name="com.aloha.springmybatis.dto"/>
</typeAliases>
XML
볡μ¬
resultType μμ±μμ dto κ°μ²΄ (ν¨ν€μ§.ν΄λμ€λͺ
) (ν΄λμ€λͺ
)
μ΄ μ€μ μ ꡬμ±νλ©΄ Mapper νμΌμμ resultType μμ±μ΄ ν¨ν€μ§λΆν° ν΄λμ€κΉμ§ λ€ μ§μ νμ§ μμλ, 맀νν κ°μ²΄κ° μλ ν¨ν€μ§λ₯Ό μ¬κΈ° μ€μ ν¨μΌλ‘μ¨, κ°μ²΄ μ΄λ¦λ§ μμ±ν΄λ μ‘°νμ κ²°κ³Όλ₯Ό κ°μ²΄μ λ°λ‘ 맀νν μ μμ΅λλ€.
<!-- κ²μκΈ μ‘°ν -->
<select id="select" resultType="com.aloha.springmybatis.dto.Board">
XML
볡μ¬
μ΄ μ€μ μ μ¬μ©νμ§ μμΌλ©΄ Β λ€μκ³Ό κ°μ΄ ν¨ν€μ§λΆν° ν΄λμ€λͺ
κΉμ§ resultType μμ±μ λ€ μμ±ν΄μΌ λμ§λ§, μ΄ μ€μ μ μ¬μ©νλ©΄ κ°μ²΄λͺ
λ§ μμ±ν΄λ λ©λλ€.
<!-- κ²μκΈ μ‘°ν -->
<select id="select" resultType="Board">
XML
볡μ¬
λ°λΌμ μ‘°ν κ²°κ³Όλ₯Ό 맀νν κ°μ²΄λ€μ΄ μλ ν¨ν€μ§λ€μ 미리 μ§μ ν΄ λμΌλ©΄ . λ€μκ³Ό κ°μ΄ κ°κ²°νκ² μμ± κ°μ μμ±ν μ μμ΅λλ€ .
νλ‘μ νΈ μ€μ - application.properties
DB λλΌμ΄λ²μ MyBatisμ μ€μ μ νλ‘μ νΈμ μλ €μ£ΌκΈ° μν΄μλ Β application.properties νμΌμ λ€μκ³Ό κ°μ΄ λ°μ΄ν° μμ€μ Mybatis κ΄λ ¨ μ€μ μ μμ±ν΄μΌ ν©λλ€.
application.properties λ μ€νλ§ λΆνΈμ νλ‘μ νΈ μ€μ νμΌμ
λλ€.
β’
λ°μ΄ν° μμ€ μ€μ
β’
mybatis-config.xml μ€μ
λ°μ΄ν° μμ€ μ€μ
# λ°μ΄ν° μμ€ - MySQL
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/aloha?serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true&useSSL=false&autoReconnection=true&autoReconnection=true
spring.datasource.username=aloha
spring.datasource.password=123456
Plain Text
볡μ¬
mybatis-config.xml μ€μ
# Mybatis μ€μ
# Mybatis μ€μ κ²½λ‘ : ~/resources/mybatis-config.xml
mybatis.config-location=classpath:mybatis-config.xml
# Mybatis λ§€νΌ νμΌ κ²½λ‘ : ~/λ©μΈν¨ν€μ§/mapper/**Mapper.xml
mybatis.mapper-locations=classpath:mybatis/mapper/**/**.xml
Plain Text
볡μ¬
β’
classpath: λΌκ³ μ§μ νλ©΄, ~/resources κ²½λ‘ νμλΆν° κ²½λ‘λ₯Ό μ§μ ν μ μλ€.
β’
classpath:mybatis/mapper/**/**.xml λΌκ³ μ§μ νλ©΄, ~/resources κ²½λ‘λΆν° λͺ¨λ κ²½λ‘μ λͺ¨λ νμ νμΌμ νμ₯μκ° .xml μ΄λ©΄ λ§μ΄λ°ν°μ€ 맀νΌ(SQL) νμΌλ‘ μΈμνλλ‘ μ§μ νλ€.
mybatis-config.xml μ€μ νμΌ μμ΄ μ μ©νκΈ°
# 컬λΌλͺ
μ λ³μλͺ
μΌλ‘ μλ맀ν : board_no β‘ boardNo
mybatis.configuration.map-underscore-to-camel-case=true
# resultType μμ±μμ dto κ°μ²΄ (ν¨ν€μ§.ν΄λμ€λͺ
) β‘ (ν΄λμ€λͺ
)
mybatis.type-aliases-package=com.aloha.springmybatis.dto
# Mybatis λ§€νΌ νμΌ κ²½λ‘ : ~/λ©μΈν¨ν€μ§/mapper/**Mapper.xml
mybatis.mapper-locations=classpath:mybatis/mapper/**/**.xml
Plain Text
볡μ¬
MyBatisμ μ€μ νμΌμ μ¬μ©ν΄μ λ§μ΄λ°ν°μ€μ μ€μ μ κ΄λ¦¬ν μλ μμ§λ§ . κΈ°λ³Έμ μΈ μ€μ λ€μ μ΄ν리μΌμ΄μ
νλ‘ν¬ν°μ€μμ λ°λ‘ μ€μ μ ν μλ μμ΅λλ€.
application.properties
spring.application.name=spring-mybatis
# λ°μ΄ν° μμ€ - MySQL
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/aloha?serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true&useSSL=false&autoReconnection=true&autoReconnection=true
spring.datasource.username=aloha
spring.datasource.password=123456
# Mybatis μ€μ
# Mybatis μ€μ κ²½λ‘ : ~/resources/mybatis-config.xml
# mybatis.config-location=classpath:mybatis-config.xml
# 컬λΌλͺ
μ λ³μλͺ
μΌλ‘ μλ맀ν : board_no β‘ boardNo
mybatis.configuration.map-underscore-to-camel-case=true
# resultType μμ±μμ dto κ°μ²΄ (ν¨ν€μ§.ν΄λμ€λͺ
) β‘ (ν΄λμ€λͺ
)
mybatis.type-aliases-package=com.aloha.springmybatis.dto
# Mybatis λ§€νΌ νμΌ κ²½λ‘ : ~/λ©μΈν¨ν€μ§/mapper/**Mapper.xml
mybatis.mapper-locations=classpath:mybatis/mapper/**/**.xml
Plain Text
볡μ¬
DB ꡬμΆ
μ΄λ² μ€μ΅μμλ MySQLμ λλΌμ΄λ²λ₯Ό μ¬μ©ν©λλ€ . MySQLμ μ€μΉκ° νμνκ±°λ . κΈ°λ³Έμ μΈ μ¬μ© λ°©λ²μ μκ³ μΆλ€λ©΄ μμ νμ΄μ§λ₯Ό μ°Έμ‘°ν΄ μ£ΌμΈμ .
β’
μ€ν€λ§ : aloha
β’
ν
μ΄λΈ μμ±
β¦
board
board
CREATE TABLE `board` (
`no` int NOT NULL AUTO_INCREMENT,
`title` varchar(100) NOT NULL,
`writer` varchar(100) NOT NULL,
`content` text,
`reg_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`upd_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`views` int NOT NULL DEFAULT '0',
PRIMARY KEY (`no`)
) COMMENT='κ²μν';
SQL
볡μ¬
λ‘μ§ μμ±
β’
DTO μμ±
β’
SQL Mapper μμ±
β’
Mapper μΈν°νμ΄μ€ μμ±
β’
Service μμ±
β’
Controller μμ±
β’
View μμ±
DTO μμ±
β’
Board.java
Board.java
Board dtoλ λ°μ΄ν°λ² μ΄μ€μ board ν
μ΄λΈκ³Ό 맀ννκΈ° μν λ°μ΄ν° μ μ‘ κ°μ²΄μ
λλ€
/**
* Board
* - κ²μκΈ μ 보
*/
@Data
public class Board {
private int no;
private String title;
private String writer;
private String content;
private Date regDate;
private Date updDate;
private int views;
}
Java
볡μ¬
SQL Mapper μμ±
SQL Mapperμλ λ°μ΄ν°λ² μ΄μ€μ μμ²μ 보λ΄κΈ° μν SQL 쿼리λ€μ xml νκ·Έ νμμΌλ‘ μ μν©λλ€
β’
κΈ°λ³Έ Mapper νμΌ νμ
β’
κΈ°λ³Έ CRUD Mapper νμΌ μ½λ
β’
BoardMapper.xml
κΈ°λ³Έ Mapper νμΌ νμ
Mybatis Mapper νμΌμλ μ΅μμ νκ·Έλ‘ <mapper> νκ·Έλ₯Ό μμ±νκ³ λ€μμ€νμ΄μ€ μμ±μ μμ±ν΄μ λνΌ μΈν°νμ΄μ€μ κ²½λ‘λ₯Ό μ§μ ν©λλ€.
namespace="λ§€νΌ μΈν°νμ΄μ€ κ²½λ‘"
namespaceμ μμ±ν Mapper μΈν°νμ΄μ€μ κ²½λ‘κ° μΈν°νμ΄μ€ νμΌμ κ²½λ‘μ μΌμΉ ν΄μΌν©λλ€.
<?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">
<!-- namespace="λ§€νΌ μΈν°νμ΄μ€ κ²½λ‘" -->
<mapper namespace="com.aloha.springmybatis.mapper.XXXMapper">
</mapper>
XML
볡μ¬
κΈ°λ³Έ CRUD Mapper νμΌ μ½λ
SQL νκ·Έ
<select id="select" resultType="base">
Mapper μΈν°νμ΄μ€ λ©μλ
public Base select(int baseNo) throws Exception;
κ° SQL νκ·Έμ id μμ±κ°μ΄ Mapper μΈν°νμ΄μ€μ λ©μλ λͺ
κ³Ό μΌμΉν΄μΌν©λλ€.
λ‘μ§μ ν΅ν΄μ Mapper μΈν°νμ΄μ€μ λ©μλκ° νΈμΆμ΄ λλ©΄, μ΄μ 맀νλμ΄ μλ SQL mapper νμΌμ ν΄λΉ λ©μλλͺ
κ³Ό μΌμΉνλ μμ΄λλ₯Ό κ°μ§ SQL νκ·Έκ° μ€νλ©λλ€
<?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">
<!-- namespace="λ§€νΌ μΈν°νμ΄μ€ κ²½λ‘" -->
<mapper namespace="com.aloha.springmybatis.mapper.BaseMapper">
<!-- κΈ°λ³Έ λ±λ‘ -->
<insert id="insert">
INSERT INTO base( base_id, base_name )
VALUES ( #{baseId}, #{baseName} )
</insert>
<!-- κΈ°λ³Έ μ‘°ν -->
<select id="select" resultType="base">
SELECT *
FROM base
WHERE base_no = #{baseNo}
</select>
<!-- κΈ°λ³Έ μμ -->
<update id="update">
UPDATE base
SET base_id = #{baseId}
,base_name = #{baseName}
WHERE base_no = #{baseNo}
</update>
<!-- κΈ°λ³Έ μμ -->
<delete id="delete">
DELETE FROM base
WHERE base_no = #{baseNo}
</delete>
</mapper>
XML
볡μ¬
BoardMapper.xml
μ΄λ² μ€μ΅μμλ κ²μκΈ λ°μ΄ν°λ₯Ό κΈ°λ³Έμ μΌλ‘ λ±λ‘ μ‘°ν μμ μμ νλ 쿼리λ€μ λ€μκ³Ό κ°μ΄ SQL νκ·Έλ‘ μμ±ν΄ λ΄
λλ€.
<?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">
<!-- namespace="λ§€νΌ μΈν°νμ΄μ€ κ²½λ‘" -->
<mapper namespace="com.aloha.springmybatis.mapper.BoardMapper">
<!-- κ²μκΈ λͺ©λ‘ -->
<select id="list" resultType="Board">
SELECT *
FROM board
ORDER BY reg_date DESC
</select>
<!-- κ²μκΈ μ‘°ν -->
<select id="select" resultType="Board">
SELECT *
FROM board
WHERE no = #{no}
</select>
<!-- κ²μκΈ λ±λ‘ -->
<insert id="insert">
INSERT INTO board( title, writer, content)
VALUES ( #{title}, #{writer}, #{content} )
</insert>
<!-- κ²μκΈ μμ -->
<update id="update">
UPDATE board
SET title = #{title}
,writer = #{writer}
,content = #{content}
WHERE no = #{no}
</update>
<!-- κ²μκΈ μμ -->
<delete id="delete">
DELETE FROM board
WHERE no = #{no}
</delete>
<!-- κ²μκΈ λ²νΈ μ΅λκ° -->
<select id="maxPk" resultType="int">
SELECT MAX(no)
FROM board
</select>
</mapper>
XML
볡μ¬
Mapper μΈν°νμ΄μ€ μμ±
λ§μ΄λ°ν°μ€ λ§€νΌ μΈν°νμ΄μ€μ λ©μλλͺ
μ λ§€νΌ νμΌμ id μμ±κ°κ³Ό μΌμΉν΄μΌνλ€.
- ν΄λΉ λ©μλκ° νΈμΆλλ©΄, λ§€νΌ XML νμΌμ SQLλ₯Ό μ€ννλ€.
β’
BoardMapper.java
BoardMapper.java
@Mapper
public interface BoardMapper {
// κ²μκΈ λͺ©λ‘
public List<Board> list() throws Exception;
// κ²μκΈ μ‘°ν
public Board select(int no) throws Exception;
// κ²μκΈ λ±λ‘
public int insert(Board board) throws Exception;
// κ²μκΈ μμ
public int update(Board board) throws Exception;
// κ²μκΈ μμ
public int delete(int no) throws Exception;
// κ²μκΈ λ²νΈ(κΈ°λ³Έν€) μ΅λκ°
public int maxPk() throws Exception;
}
Java
볡μ¬
λ§€νΌ νμΌμ idμ μΌμΉνλ λ©μλλͺ
μ μμ±νκ³ , λ§€νΌ νμΌμ SQL νκ·Έμ μ λ¬ν΄ μ€ νλΌλ―Έν°λ€μ 맀κ°λ³μλ‘ μμ±ν©λλ€.
λν μ‘°ν 쿼리μ κ²½μ°μλ μ‘°ν κ²°κ³Όλ₯Ό 맀ν λ°μ κ°μ²΄ νΉμ 컬λ μ
μ λ°ν νμ
μΌλ‘ μμ±νκ³ , λ±λ‘, μμ , μμ , 쿼리μ κ²½μ°μλ λ°μ΄ν°λ² μ΄μ€μμ μ²λ¦¬λ νμ μλ₯Ό λ°νλ°κΈ° μνμ¬ int νμ
μΌλ‘ μμ±ν©λλ€
Service μμ±
μ΄μ μλΉμ€ μΈν°νμ΄μ€μ ꡬν ν΄λμ€λ₯Ό μμ±ν©λλ€.
β’
BoardService.java
β’
BoardServiceImpl.java
BoardService.java
μλΉμ€ μΈν°νμ΄μ€λ₯Ό ν΅ν΄μ λΉμ¦λμ€ λ‘μ§μμ μ¬μ©ν κΈ°λ₯μ λν λ©μλμ ννλ₯Ό μ μν©λλ€. μ΄λ κ² μΈν°νμ΄μ€λ‘ λ©μλ ννλ₯Ό μ μν¨μΌλ‘μ¨, μ€μ λ‘ κ΅¬νν μ½λμ λν΄μ λ€νμ±κ³Ό νμ₯μ±μ μ 곡ν©λλ€.
public interface BoardService {
// κ²μκΈ λͺ©λ‘
public List<Board> list() throws Exception;
// κ²μκΈ μ‘°ν
public Board select(int no) throws Exception;
// κ²μκΈ λ±λ‘
public int insert(Board board) throws Exception;
// κ²μκΈ μμ
public int update(Board board) throws Exception;
// κ²μκΈ μμ
public int delete(int no) throws Exception;
}
Java
볡μ¬
BoardServiceImpl.java
ꡬν ν΄λμ€μμλ λ§€νΌ μΈν°νμ΄μ€μ μ μ ν λ©μλλ‘ νΈμΆν¨μΌλ‘μ¨ λ°μ΄ν°μ λνμ¬ μ‘°ν, λ±λ‘, μμ , μμ μμ²μ λ³΄λΌ μ μλλ‘ μ½λλ₯Ό μμ±ν©λλ€. λν κ° λ©μλμμλ μλΉμ€μ κ° κΈ°λ₯μ λν μΆκ° λ‘μ§μ νμ₯νκ±°λ κ΄λ ¨λ λ‘κ·Έ λ° μ²λ¦¬λ€μ ν μ μμ΅λλ€.
@Service // μλΉμ€ μν μ μ€νλ§ λΉ
public class BoardServiceImpl implements BoardService {
@Autowired
private BoardMapper boardMapper;
/**
* κ²μκΈ λͺ©λ‘ μ‘°ν
*/
@Override
public List<Board> list() throws Exception {
// TODO : boardMapper λ‘ list() νΈμΆ
/*
* β‘ List<Board> boardList λ‘ λ°μμ΄
* β‘ return boardList
*/
List<Board> boardList = boardMapper.list();
return boardList;
}
/**
* κ²μκΈ μ‘°ν
* - no 맀κ°λ³μλ‘ κ²μκΈ λ²νΈλ₯Ό μ λ¬λ°μμ
* λ°μ΄ν°λ² μ΄μ€μ μ‘°ν μμ²
*/
@Override
public Board select(int no) throws Exception {
// TODO : boardMapper λ‘ select(no) νΈμΆ
/*
* β‘ Board board λ‘ λ°μμ΄
* β‘ return board
*/
Board board = boardMapper.select(no);
return board;
}
/**
* κ²μκΈ λ±λ‘
*/
@Override
public int insert(Board board) throws Exception {
// TODO : boardMapper λ‘ insert(Board) νΈμΆ
/*
* β‘ int result λ‘ λ°μ΄ν° μ²λ¦¬ ν(κ°μ) λ°μμ΄
* β‘ return result
*/
int result = boardMapper.insert(board);
return result;
}
/**
* κ²μκΈ μμ
*/
@Override
public int update(Board board) throws Exception {
// TODO : boardMapper λ‘ update(Board) νΈμΆ
/*
* β‘ int result λ‘ λ°μ΄ν° μ²λ¦¬ ν(κ°μ) λ°μμ΄
* β‘ return result
*/
int result = boardMapper.update(board);
return result;
}
/**
* κ²μκΈ μμ
*/
@Override
public int delete(int no) throws Exception {
// TODO : boardMapper λ‘ delete(no) νΈμΆ
/*
* β‘ int result λ‘ λ°μ΄ν° μ²λ¦¬ ν(κ°μ) λ°μμ΄
* β‘ return result
*/
int result = boardMapper.delete(no);
return result;
}
}
Java
볡μ¬
Controller μμ±
컨νΈλ‘€λ¬μμλ μμ² κ²½λ‘λ₯Ό 맀ννμ¬ ν΄λΌμ΄μΈνΈμ μμ²μ λνμ¬ μ μ ν μλΉμ€ λ‘μ§ λ° λ°μ΄ν°λ₯Ό μ²λ¦¬νκ³ , ν΄λΌμ΄μΈνΈμκ² μλ΅ν λ·° νμ΄μ§λ₯Ό μ§μ ν©λλ€.
μμ² κ²½λ‘ λ§€ν
λ°μ΄ν° μμ²
λ·° νμ΄μ§ μ§μ
BoardController.java
package com.aloha.springmybatis.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.aloha.springmybatis.dto.Board;
import com.aloha.springmybatis.service.BoardService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestBody;
/**
* /board κ²½λ‘λ‘ μμ² μμ λ μ²λ¦¬
* [GET] - /board/list : κ²μκΈ λͺ©λ‘ νλ©΄
* [GET] - /board/read : κ²μκΈ μ‘°ν νλ©΄
* [GET] - /board/insert : κ²μκΈ λ±λ‘ νλ©΄
* [POST] - /board/insert : κ²μκΈ λ±λ‘ μ²λ¦¬
* [GET] - /board/update : κ²μκΈ μμ νλ©΄
* [POST] - /board/update : κ²μκΈ μμ μ²λ¦¬
* [POST] - /board/delete : κ²μκΈ μμ μ²λ¦¬
*/
@Slf4j // λ‘κ·Έ μ΄λ
Έν
μ΄μ
@Controller // 컨νΈλ‘€λ¬ μ€νλ§ λΉμΌλ‘ λ±λ‘
@RequestMapping("/board") // ν΄λ μ€ λ 벨 μμ² κ²½λ‘ λ§€ν
// - /board/~ κ²½λ‘μ μμ²μ μ΄ μ»¨νΈλ‘€λ¬μμ μ²λ¦¬
public class BoardController {
// βλ°μ΄ν° μμ²κ³Ό νλ©΄ μΆλ ₯
// Controller --> Service (λ°μ΄ν° μμ²)
// Controller <-- Service (λ°μ΄ν° μ λ¬)
// Controller --> Model (λͺ¨λΈ λ±λ‘)
// View <-- Model (λ°μ΄ν° μΆλ ₯)
@Autowired // μμ‘΄μ± μλ μ£Όμ
private BoardService boardService; // @Serviceλ₯Ό --Impl μ λ±λ‘
/**
* κ²μκΈ λͺ©λ‘ μ‘°ν νλ©΄
* @return
* @throws Exception
*/
@GetMapping("/list")
public String list(Model model) throws Exception {
// λ°μ΄ν° μμ²
List<Board> boardList = boardService.list();
// λͺ¨λΈ λ±λ‘
model.addAttribute("boardList", boardList);
// λ·° νμ΄μ§ μ§μ
return "/board/list"; // resources/templates/board/list.html
}
/**
* κ²μκΈ μ‘°ν νλ©΄
* - /board/read?no=π
* @param no
* @return
* @throws Exception
*/
// @RequestParam("νλΌλ―Έν°λͺ
")
// - μ€νλ§ λΆνΈ 3.2λ²μ μ΄ν, μλ΅ν΄λ μλ 맀νλλ€.
// - μ€νλ§ λΆνΈ 3.2λ²μ μ΄μ, νμλ‘ λͺ
μν΄μΌ 맀νλλ€.
@GetMapping("/read")
public String read(@RequestParam("no") int no, Model model) throws Exception {
// λ°μ΄ν° μμ²
Board board = boardService.select(no);
// λͺ¨λΈ λ±λ‘
model.addAttribute("board", board);
// λ·°νμ΄μ§ μ§μ
return "/board/read";
}
/**
* κ²μκΈ λ±λ‘ νλ©΄
* @return
*/
@GetMapping("/insert")
public String insert() {
return "/board/insert";
}
/**
* κ²μκΈ λ±λ‘ μ²λ¦¬
* @param board
* @return
* @throws Exception
*/
@PostMapping("/insert")
public String insertPro(Board board) throws Exception {
// λ°μ΄ν° μμ²
int result = boardService.insert(board);
// 리λ€μ΄λ νΈ
// β λ°μ΄ν° μ²λ¦¬ μ±κ³΅
if( result > 0 ) {
return "redirect:/board/list";
}
// β λ°μ΄ν° μ²λ¦¬ μ€ν¨
return "redirect:/board/insert?error";
}
/**
* κ²μκΈ μμ νλ©΄
* @param no
* @param model
* @return
* @throws Exception
*/
@GetMapping("/update")
public String update(@RequestParam("no") int no, Model model) throws Exception {
Board board = boardService.select(no);
model.addAttribute("board", board);
return "/board/update";
}
/**
* κ²μκΈ μμ μ²λ¦¬
* @param board
* @return
* @throws Exception
*/
@PostMapping("/update")
public String updatePro(Board board) throws Exception {
int result = boardService.update(board);
if( result > 0 ) {
return "redirect:/board/list";
}
int no = board.getNo();
return "redirect:/board/update?no="+ no + "&error";
}
/**
* κ²μκΈ μμ μ²λ¦¬
* @param no
* @return
* @throws Exception
*/
@PostMapping("/delete")
public String delete(@RequestParam("no") int no) throws Exception {
int result = boardService.delete(no);
if( result > 0 ) {
return "redirect:/board/list";
}
return "redirect:/board/update?no=" + no + "&error";
}
}
Java
볡μ¬
View μμ±
β’
board
β¦
list.html
β¦
insert.html
β¦
read.html
β¦
update.html
β’
index.html
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>λ©μΈ νλ©΄</title>
</head>
<body>
<h1>SpringBoot x MyBatis</h1>
<h3>κ²μν νλ‘μ νΈ</h3>
<ul>
<li>Spring Boot 3.x</li>
<li>Thymeleaf</li>
<li>MySQL 8.x</li>
<li>MyBatis 3.0</li>
</ul>
<div>
<a href="/board/list">κ²μν</a>
</div>
</body>
</html>
HTML
볡μ¬
β’
board
list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>κ²μκΈ λͺ©λ‘</title>
</head>
<body>
<h1>κ²μκΈ λͺ©λ‘</h1>
<a href="/board/insert">κΈμ°κΈ°</a>
<table border="1">
<tr>
<th width="50">λ²νΈ</th>
<th width="300">μ λͺ©</th>
<th width="100">μμ±μ</th>
<th width="200">λ±λ‘μΌμ</th>
<th width="200">μμ μΌμ</th>
<th widht="100">μ‘°νμ</th>
</tr>
<th:block th:each="board : ${boardList}">
<tr>
<td align="center" th:text="${board.no}"></td>
<td>
<!-- th:???="|λ¬Έμμ΄+${ννμ}|" -->
<a th:href="|/board/read?no=${board.no}|"
th:text="${board.title}"></a>
</td>
<td align="center" th:text="${board.writer}"></td>
<!--
μ νΈλ¦¬ν°κ°μ²΄.λ©μλ()
#dates.format( λ μ§κ°μ²΄λͺ
, 'λ μ§ν¬λ§·' )
- #dates.format( board.regDate, 'yyyy-MM-dd HH:mm:ss' )
-->
<td align="center">
<span th:text="${ #dates.format( board.regDate, 'yyyy-MM-dd HH:mm:ss' ) }"></span>
</td>
<td align="center">
<span th:text="${ #dates.format( board.updDate, 'yyyy-MM-dd HH:mm:ss' ) }"></span>
</td>
<td align="center" th:text="${board.views}"></td>
</tr>
</th:block>
</table>
</body>
</html>
HTML
볡μ¬
insert.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>κ²μκΈ λ±λ‘</title>
</head>
<body>
<h1>κ²μκΈ λ±λ‘</h1>
<form action="/board/insert" method="post">
<input type="text" name="title" id="title">
<input type="text" name="writer" id="writer">
<input type="text" name="content" id="content">
<input type="submit" value="λ±λ‘">
</form>
</body>
</html>
HTML
볡μ¬
read.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>κ²μκΈ μ‘°ν</title>
</head>
<body>
<h1>κ²μκΈ μ‘°ν</h1>
<form action="/board/delete" method="post">
<input type="hidden" name="no" th:value="${board.no}">
<table>
<tr>
<td>μ λͺ©</td>
<td>
<input type="text" name="title" th:value="${board.title}">
</td>
</tr>
<tr>
<td>μμ±μ</td>
<td>
<input type="text" name="writer" th:value="${board.writer}">
</td>
</tr>
<tr>
<td colspan="2">
<textarea name="content" id="content" cols="40" rows="5"
th:text="${board.content}"></textarea>
</td>
</tr>
</table>
<div>
<button type="button" onclick="moveUpdate()">μμ </button>
<button type="button" onclick="moveList()">λͺ©λ‘</button>
</div>
</form>
<script>
// π©βπ» λͺ¨λΈ κ°μ²΄λ₯Ό μλ°μ€ν¬λ¦½νΈλ‘ κ°μ Έμ€λ λ°©λ²
let no = "[[${board.no}]]"
// μμ νλ©΄ μ΄λ
function moveUpdate() {
location.href = '/board/update?no=' + no
}
// λͺ©λ‘ νλ©΄ μ΄λ
function moveList() {
location.href = '/board/list'
}
</script>
</body>
</html>
HTML
볡μ¬
update.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>κ²μκΈ μμ </title>
</head>
<body>
<h1>κ²μκΈ μμ </h1>
<form id="form" action="/board/update" method="post">
<input type="hidden" name="no" th:value="${board.no}">
<table>
<tr>
<td>μ λͺ©</td>
<td>
<input type="text" name="title" th:value="${board.title}">
</td>
</tr>
<tr>
<td>μμ±μ</td>
<td>
<input type="text" name="writer" th:value="${board.writer}">
</td>
</tr>
<tr>
<td colspan="2">
<textarea name="content" id="content" cols="40" rows="5"
th:text="${board.content}"></textarea>
</td>
</tr>
</table>
<div>
<button type="submit">μμ </button>
<button type="button" onclick="actionDelete()">μμ </button>
<button type="button" onclick="moveList()">λͺ©λ‘</button>
</div>
</form>
<script>
let form = document.getElementById('form')
// π©βπ» λͺ¨λΈ κ°μ²΄λ₯Ό μλ°μ€ν¬λ¦½νΈλ‘ κ°μ Έμ€λ λ°©λ²
let no = "[[${board.no}]]"
// μμ νλ©΄ μ΄λ
function moveUpdate() {
location.href = '/board/update?no=' + no
}
// μμ μμ²
function actionDelete() {
let check = confirm('μ λ§λ‘ μμ νμκ² μ΅λκΉ?')
if( check ) {
form.action = '/board/delete'
form.submit()
}
}
// λͺ©λ‘ νλ©΄ μ΄λ
function moveList() {
location.href = '/board/list'
}
</script>
</body>
</html>
HTML
볡μ¬
κΈ°λ₯ λͺ
μΈμ
β’
κ²μκΈ λ±λ‘
β’
κ²μκΈ λͺ©λ‘ μ‘°ν
β’
κ²μκΈ μ‘°ν
β’
κ²μκΈ μμ
β’
κ²μκΈ μμ
κ²μκΈ λ±λ‘
κ²μκΈ λ±λ‘ μ, μ¬μ©μκ° /board/insert.html μμ κ²μκΈ μ 보 (μ λͺ©, μμ±μ, λ΄μ©)λ₯Ό μ
λ ₯νκ³ , μ¬λ¬ νμΌμ 첨λΆνμ¬ μμ²νλ€.
β’
κ²μκΈ μ 보 λ±λ‘
β’
νμΌ μ
λ‘λ
κ²μκΈ μ 보 λ±λ‘
β’
Model
β¦
BoardService.java
βͺ
insert(Board)
β¦
BoardServiceImpl.java
βͺ
insert(Board)
β’
κ²μκΈ μ 보 λ±λ‘
β¦
BoardMapper μ insert(Board) νΈμΆ
β’
νμΌ μ
λ‘λ
β¦
FileService μ upload(List<Files>) νΈμΆ
β¦
BoardMapper.java
βͺ
insert(Board)
β’
BoardMapper.xml μ id=βinsertβ 쿼리μ μ°κ²°
β¦
BoardMapper.xml
βͺ
<insert id=βinsertβ β¦ >
β’
μ μ©λ λ°μ΄ν° νμ μλ₯Ό λ°ν ( 0 λλ 1 )
β’
View
β¦
~/board/insert.html
βͺ
[POST] λ°©μμΌλ‘ FORM μμ²
β’
νλΌλ―Έν°
β¦
μ λͺ© : title
β¦
μμ±μ : writer
β¦
λ΄μ© : content
β¦
νμΌ : file
β’
Controller
β¦
BoardController.java
βͺ
@GetMapping(β/board/insertβ)
β’
μλ΅
β¦
/board/insert
βͺ
@PostMapping(β/board/insertβ)
β’
@RequestBody Board board
β’
BoardService μ insert() λ©μλ μμ²
β’
μλ΅
β¦
μμ² μ±κ³΅ : (redirect) /board/list
β¦
μμ² μ€ν¨ : (redirect) /board/insert?error
κ²μκΈ λͺ©λ‘ μ‘°ν
κ²μκΈ μ μ 체 λͺ©λ‘μ μ‘°νν©λλ€.
β’
κ²μκΈ λͺ©λ‘ μ 체 μ‘°ν
κ²μκΈ λͺ©λ‘ - MVC
β’
Model : BoardService
β’
View : /board/list.html
β’
Controller : BoardController.java
κ²μκΈ λͺ©λ‘ μ‘°ν
β’
Model
β¦
BoardService.java
βͺ
list()
β¦
BoardServiceImpl.java
βͺ
list()
β¦
BoardMapper.java
βͺ
list()
β’
BoardMapper.xml μ id=βlistβ 쿼리μ μ°κ²°
β¦
BoardMapper.xml
βͺ
<seledct id=βlistβ resultType=βBoardβ β¦ >
β’
resultType=βBoardβ
β¦
μ‘°νλ board ν
μ΄λΈμ Board κ°μ²΄λ‘ 맀ν
β’
View
β¦
~/board/list.html
β’
Controller
β¦
BoardController.java
βͺ
@GetMapping(β/board/listβ)
β’
Model boardList
β’
μλ΅
β¦
/board/list
κ²μκΈ μ‘°ν
κ²μκΈ μ 보 ν 건μ μ‘°νν©λλ€.
β’
κ²μκΈ μ 보 μ‘°ν
β’
μ²¨λΆ νμΌ λͺ©λ‘ μ‘°ν
κ²μκΈ μ 보 μ‘°ν
β’
Model
β¦
BoardService.java
βͺ
select(no)
β¦
BoardServiceImpl.java
βͺ
select(no)
β¦
BoardMapper.java
βͺ
select(no)
β’
BoardMapper.xml μ id=βselectβ 쿼리μ μ°κ²°
β¦
BoardMapper.xml
βͺ
<seledct id=βselectβ resultType=βBoardβ β¦ >
β’
resultType=βBoardβ
β¦
μ‘°νλ board ν
μ΄λΈμ Board κ°μ²΄λ‘ 맀ν
β’
View
β¦
~/board/read.html
β’
Controller
β¦
BoardController.java
βͺ
@GetMapping(β/board/readβ)
β’
Model board
β’
μλ΅
β¦
/board/read
κ²μκΈ μμ
κ²μκΈ μ 보 ν 건μ μμ ν©λλ€.
β’
κ²μκΈ μ 보 μμ
β’
νμΌ μμ (AJAX)
κ²μκΈ μ 보 μμ
β’
Model
β¦
BoardService.java
βͺ
update(board)
β¦
BoardServiceImpl.java
βͺ
update(board)
β¦
BoardMapper.java
βͺ
update(board)
β’
BoardMapper.xml μ id=βupdateβ 쿼리μ μ°κ²°
β¦
BoardMapper.xml
βͺ
<update id=βupdateβ β¦ >
β’
μ μ©λ λ°μ΄ν° νμ μλ₯Ό λ°ν ( 0 λλ 1 )
β’
View
β¦
~/board/update.html
β’
Controller
β¦
BoardController.java
βͺ
@GetMapping(β/board/updateβ)
β’
Model board
β’
μλ΅
β¦
/board/update
βͺ
@PostMapping(β/board/updateβ)
β’
@RequestBody Board board
β’
BoardService μ update() λ©μλ μμ²
β’
μλ΅
β¦
μμ² μ±κ³΅ : (redirect) /board/list
β¦
μμ² μ€ν¨ : (redirect) /board/update?error
κ²μκΈ μμ
κ²μκΈ μ 보 ν 건μ μμ ν©λλ€.
β’
κ²μκΈ μμ
β’
μ²¨λΆ νμΌ μμ
κ²μκΈ μμ
β’
Model
β¦
BoardService.java
βͺ
delete(no)
β¦
BoardServiceImpl.java
βͺ
delete(no)
β¦
BoardMapper.java
βͺ
delete(no)
β’
BoardMapper.xml μ id=βdeleteβ 쿼리μ μ°κ²°
β¦
BoardMapper.xml
βͺ
<delete id=βdeleteβ β¦ >
β’
μ μ©λ λ°μ΄ν° νμ μλ₯Ό λ°ν ( 0 λλ 1 )
β’
View
β¦
~/board/update.html μμ [μμ ] λ²νΌμΌλ‘ μμ²
β’
Controller
β¦
BoardController.java
βͺ
@GetMapping
β’
βͺ
@PostMapping(β/board/deleteβ)
β’
@RequestBody Board board
β’
BoardService μ delete() λ©μλ μμ²
β’
μλ΅
β¦
μμ² μ±κ³΅ : (redirect) /board/list
β¦
μμ² μ€ν¨ : (redirect) /board/update?error