
JPA๋ฅผ ์ฌ์ฉํด์ ๊ฐ๋ฐCookie/Session์ ํ์ฉ๋จ๋ฐฉํฅ, ์ ๋ง ํ์ํ ๊ฒฝ์ฐ๋ ์๋ฐฉํฅ ์ฌ์ฉSQL query ์์ฑ
์ค์นํ ๋ฐ์ดํฐ๋ฒ ์ด์ค(MySQL)์ ERD๋ฅผ ๋ฐ๋ผ ํ ์ด๋ธ ์์ฑ
root(์ต์์) ๊ฒฝ๋ก์ schedule.sqlํ์ผ์ ๋ง๋ค๊ณ ํ
์ด๋ธ์ ์์ฑ์ ํ์ํ query ์์ฑ
์ผ์ ํ๋ : ์์ฑ ์ ์ ๋ช
, ํ ์ผ ์ ๋ชฉ, ํ ์ผ ๋ด์ฉ, ์์ฑ์ผ, ์์ ์ผ
์์ฑ์ผ, ์์ ์ผ ํ๋๋ JPA Auditing ํ์ฉ ์ ์ ํ๋ : ์ ์ ๋ช
, ์ด๋ฉ์ผ, ์์ฑ์ผ, ์์ ์ผ
์์ฑ์ผ, ์์ ์ผ ํ๋๋ JPA Auditiin ํ์ฉ
์ฐ๊ด๊ด๊ณ : ์ ์ ๋ช
ํ๋ ๋์ ์ ์ ๊ณ ์ ์๋ณ์ ํ๋๋ก ๋ณ๊ฒฝ
์ ์ ์ ๋น๋ฐ๋ฒํธ ํ๋ ์ถ๊ฐ
์์ด๋ : ์ด๋ฉ์ผ, ๋น๋ฐ๋ฒํธ ์ฌ์ฉํด์ ํ์๊ฐ์
๊ตฌํ
์ด๋ฉ์ผ, ๋น๋ฐ๋ฒํธ์ ํ์ฉํด ๋ก๊ทธ์ธ ๊ธฐ๋ฅ ๊ตฌํ
์ธํฐํ์ด์ค : HttpServletRequest ํ์ฉ
Cookie/Session ํ์ฉํ์ฌ ๋ก๊ทธ์ธ ๊ธฐ๋ฅ ๊ตฌํ
Filter ํ์ฉํ์ฌ ์ธ์ฆ ์ฒ๋ฆฌ
Filter ์ธํฐํ์ด์ค ์์ํ์ฌ ์ฌ์ฉ
doFilter() ์ค๋ฒ๋ผ์ด๋ฉ ํ์ฌ ์ฌ์ฉ
ํ์๊ฐ์ , ๋ก๊ทธ์ธ ์์ฒญ์ ์ธ์ฆ ์ฒ๋ฆฌ์์ ์ ์ธ
@Comfiguration ํ์ฉํ์ฌ ํํฐ ๋ฑ๋ก
HTTP CODE 401 ๋ฐํValidation์ ํ์ฉํด ๋ค์ํ ์์ธ์ฒ๋ฆฌ ์ ์ฉ
@pattern ์ฌ์ฉ ๋ฑ๋น๋ฐ๋ฒํธ ์ํธํ
PasswordEncoder ์ฌ์ฉbuild.gradle ์์กด์ฑ ์ถ๊ฐ
implementation 'at.favre.lib:bcrypt:0.10.2'
config ํจํค์ง์
PasswordEncoderํด๋์ค ์ถ๊ฐimport at.favre.lib.crypto.bcrypt.BCrypt; import org.springframework.stereotype.Component; @Component public class PasswordEncoder { public String encode(String rawPassword) { return BCrypt.withDefaults().hashToString(BCrypt.MIN_COST, rawPassword.toCharArray()); } public boolean matches(String rawPassword, String encodedPassword) { BCrypt.Result result = BCrypt.verifyer().verify(rawPassword.toCharArray(), encodedPassword); return result.verified; } }
์์ฑํ ์ผ์ ์ ๋๊ธ์ ๋จ๊น
๋๊ธ๊ณผ ์ผ์ ์ ์ฐ๊ด๊ด๊ณ๋ฅผ ๊ฐ์ง
๋๊ธ๊ณผ ์ ์ ๋ ์ฐ๊ด๊ด๊ณ๋ฅผ ๊ฐ์ง
๋๊ธ ํ๋ : ๋๊ธ ๋ด์ฉ, ์์ฑ์ผ, ์์ ์ผ, ์ ์ ๊ณ ์ ์๋ณ์, ์ผ์ ๊ณ ์ ์๋ณ์
์์ฑ์ผ, ์์ ์ผ ํ๋๋ JPA Auditing ํ์ฉERD, schedule.sql์ ๋๊ธ ์ถ๊ฐ
๋ฐ์ดํฐ๋ฒ ์ด์ค
offset / limit : SELECT ์ฟผ๋ฆฌ์ ์ ์ฉํด์ ๋ฐ์ดํฐ๋ฅผ ์ ํ ๋ฒ์์ ๋ง๊ฒ ์กฐํ ๊ฐ๋ฅํ์ด์ง
Pageable : Spring Data JPA์์ ์ ๊ณต๋๋ ํ์ด์ง ๊ด๋ จ ์ธํฐํ์ด์ค
PageRequest : Spring Data JPA์์ ์ ๊ณต๋๋ ํ์ด์ง ์์ฒญ ๊ด๋ จ ํด๋์ค
Page<T>๋ Spring Data JPA์์ ์ ๊ณตํ๋ ํ์ด์ง ๊ฒฐ๊ณผ๋ฅผ ๋ด๋ ์ธํฐํ์ด์ค
Pageable๊ณผ Page ์ธํฐํ์ด์ค๋ฅผ ํ์ฉํ์ฌ ํ์ด์ง๋ค์ด์
๊ตฌํํ ์ผ ์ ๋ชฉ, ํ ์ผ ๋ด์ฉ, ๋๊ธ ๊ฐ์, ์ผ์ ์์ฑ์ผ, ์ผ์ ์์ ์ผ, ์ผ์ ์์ฑ ์ ์ ๋ช
์กฐํ์์ ์ผ ๊ธฐ์ค์ผ๋ก ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ๋ฌธ์ ์
List<Entity> -> List<ResponseDTO> ํ์
๋ณ๊ฒฝ ๋ฌธ์ ํด๊ฒฐ๋ฐฉ๋ฒ
๋ฌธ์ ์
๋น๋ฐ๋ฒํธ ํ๋๋ฅผ ์ถ๊ฐ ๋ผ๋ ๋ง๋ง ์กด์ฌํ์ฌํด๊ฒฐ๋ฐฉ๋ฒ
๋น๋ฐ๋ฒํธ ํ๋๋ง ๊ตฌํํ๊ณ ๋ก์ง์ ์์ฑํ์ง ์๊ณ [LV4๏ธโฃ]๋ก ๋์ด๊ฐ๋๋ฐ๋ฌธ์ ์
Cookie, Session, Filter์ ๋ํด ์ด๋ก ์ ์ดํดํ์ผ๋ ์ด๋ป๊ฒ ์ ์ฉ์ ํด์ผํ๋์ง ์ดํด๊ฐ ๋์ง ์์์ํด๊ฒฐ๋ฐฉ๋ฒ
๋ฌธ์ ์
@valid ๊ฒ์ฆ ์ด๋
ธํ
์ด์
์ฌ์ฉ ํํด๊ฒฐ๋ฐฉ๋ฒ
Controller์์ ๊ฒ์ฆํ DTO๋ฅผ Service ์์ญ์์ ์ฌ์ฉํ๊ธฐ์
์ถ๊ฐ ๊ฒ์ฆ์ด ํ์์๋ค๋ ๊ฒ์ ํ์ตํจ
๋จ Controller์์ ๊ฒ์ฆ๋์ง ์์ DTO์ผ ๊ฒฝ์ฐ Service ์์ญ์์ ๊ฒ์ฆ์ด ํ์ํจ
๋ฌธ์ ์
PasswordEncoder ํด๋์ค ์กด์ฌํ๋ ๋ฉ์๋๊ฐ ์ด๋ค ์ฉ๋์ธ์ง ํ์
ํด๊ฒฐ๋ฐฉ๋ฒ
์ํธํ, ์ํธํ๋ Password ๋งค์นญํ๋ ๋ฉ์๋ ๋ผ๋ ๊ฒ์ ํ์ ํจ
์ํธํ์ ์ํธํ๋ Password๋ฅผ ์กฐํํ๋ ๋ฉ์๋๋ผ๋ ๊ฒ์ ํ์
ํ๋
์ถํ DTO์ ์ ์ฉํ๋๋ฐ ์ด๋ ค์์ด ์์์
๋ฌธ์ ์
์ฐ๊ด๊ด๊ณ๋ฅผ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ ,FK๊ฐ์ ๊ฐ์ ธ์ค๊ธฐ ์ํ ๊ณผ์ ๊ณ ๋ฏผํด๊ฒฐ๋ฐฉ๋ฒ
@PathVariable์ ์ด์ฉํ์ฌ ๊ฐ๋จํ๊ฒ ๊ฐ์ ธ์ null๊ฐ ์์ธ์ฒ๋ฆฌ ํด์ฃผ๋ฉฐ,Session์ ์ด์ฉํ์ฌ Session ID๊ฐ์ ๊ฐ์ง๊ณ ์์ null๊ฐ ์์ธ์ฒ๋ฆฌํ์ฌ ์ฌ์ฉ๋ฌธ์ ์
ํด๋ผ์ด์ธํธ๊ฐ ์ํ๋ ์๋ต ํํ๋๋ก ResponseDTO๋ฅผ ๋ง๋ค์๋๋ฐ,
๊ทธ ํ๋๋ค์ ์ฑ์ฐ๋ ค๋ฉด ํ๋์ Entity์์ ํด๊ฒฐ๋์ง ์๊ณ
์ฌ๋ฌ Entity์ ๊ฐ์ด ํ์ํด์ ์ฒ๋ฆฌํ๊ธฐ๊ฐ ์ด๋ ค์์ ๋๋
ํ์ด์ง์ ์ด๋ป๊ฒ ๊ตฌํํด์ผํ ์ง ๋ชจ๋ฆ
ํด๊ฒฐ๋ฐฉ๋ฒ
ํํฐ๋์ ์กฐ์ธ์ผ๋ก -> JPQL๋ฐฉ์์ ์ฌ์ฉํ์ฌ ๊ตฌํ
JPQL์ ์ด์ฉํ์ฌ ํด๊ฒฐํ์์ง๋ง JPQL ํ์ต์ด ํ์ํ๋ค๊ณ ๋๋Page, Pageable, PageRequest์ ๋ํ์ฌ ํ์ตํ์ฌ ๋ด ์ฝ๋์ ๋ง๊ฒ ๊ตฌํ
ํ๋ก์ ํธ ์ด๋ฆ : ScheduleDevelopProject
Github์๋ ์ ๋ฑ๋กํ์๋๋ฐ Springboot์ ScheduleDelevopProject ์คํ๋ก ์
๋ ฅ
๋จ์ํ๊ฒ ์๊ฐํ์ฌ ํ๋ก์ ํธ ํด๋๋ช ์ ๋ณ๊ฒฝ
ํ๋ก์ ํธ ๋ด๋ถ์์ import์ ํจํค์ง ์ ์ฒด์ ์ผ๋ก ์ค๋ฅ ๋ฐ์
์๋์ผ๋ก ์ ๋ถ ๋ณ๊ฒฝ ํ ์บ์ ๋ฌดํจํํ์ฌ ๋ค์ ํ๋ก์ ํธ๋ฅผ ์คํ
GPT๋ฅผ ์ฌ์ฉํ์ฌ ์์ธ์ ์ฐพ๊ธฐ ์์
ScheduleDevelopProject[scheduleDelevopProject] ํ๋ก์ ํธ ํด๋๋ช
์ ๋ณ๊ฒฝํ์ฌ๋
๋๊ดํธ[] ์์ ์ด๋ฆ์ด ๋ณ๊ฒฝ๋์ง ์์ ์ค๋ฅ ๋ฐ์ํ๋ค๊ณ ํจ
GPT์์ ๋งํ๊ธฐ๋ ํ๋ก์ ํธ ํด๋์์ .idea ํด๋์ .iml ํ์ผ์ ์ฐพ์์ ์ญ์ ํ๋ผ๊ณ ํจ
.idea ํด๋ ์์ modules ํด๋ ์์ .iml ํ์ผ์ด ์กด์ฌํ๋ ๊ฑธ ์์์ .idea ํด๋๋ฅผ ์ญ์ ํจ์ญ์ ํ ์ฌ ์คํํ๋ฉด .idea ํด๋๋ ๋ค์ ์๊ธด๋ค๊ณ ํจ
.idea ํ์ผ ์์ฑ๋ ๊ฒ์ ํ์ธ -> ํ์ง๋ง ๋๊ฐ์ด ์ปดํ์ผ ์ค๋ฅ ๋ฐ์๊ฒฐ๊ณผ์ ์ผ๋ก ํ๋ก์ ํธ๊ฐ ๋ ๊ผฌ์ผ๊ฑฐ ๊ฐ๋ค๋ ๋๋์ ๋ฐ๊ณ
ํ๋ก์ ํธ ํด๋๋ฅผ ์ญ์ ํ Git์ ์ ์ฅํ ์ฝ๋๋ฅผ cloneํ์ฌ ๋ณต๊ตฌํจ