[์ธํ๋ฐ ์๋ฐ์ ํด๋ฝ 2๊ธฐ - BE] 1์ฃผ์ฐจ ๋ฐ์๊ตญ
๋ฐ์๊ตญ ๋ด์ฉ์ ๋ฑํ ํ์์ด ์ ํด์ ธ ์์ง ์์์ ๋ฐ์๊ตญ ์ฐ๊ธฐ ์ ๋ ๊น์ง ๋ค์๋ ๊ฐ์๋ค ์ค, ๋ชจ๋ฅด๋ ๋ด์ฉ๋ค์ ์ ์ด์ ๋ด๊ฐ ๋ค์ ๋ดค์ ๋, "์ ๋ง๋ค!" ๋ผ๋ ๋ง์ด ๋์ฌ ์ ๋๋ก๋ง ์ ์ ์์ ์ด๋ค!
๋ชฉ์ฐจ
- ๋ชจ๋ฅด๋ ๋ด์ฉ ์ ๋ฆฌ
- ๋ฏธ์ ํด๊ฒฐ ๊ณผ์
- ํ๊ณ
1. ๋ชจ๋ฅด๋ ๋ด์ฉ ์ ๋ฆฌ
<Gradle>
Gradle : Gradle์ Groovy๋ฅผ ๊ธฐ๋ฐํ ๋น๋ ๊ด๋ฆฌ ๋๊ตฌ.
- ๋น๋ ๊ด๋ฆฌ ๋๊ตฌ : ํ๋ก์ ํธ ๋ด์์ ๋ค์ํ๊ฒ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ก์ปฌ ๋ ํฌ์งํ ๋ฆฌ์์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ณ๋ก ๋ฒ์ ๊ด๋ฆฌ๋ฅผ ํด์ผํ ๋ ์ฉ์ด
- Gradle์ด ์ ํ์ํ ๊น?
- Gradle
- groovy ์ธ์ด๋ฅผ ์ฌ์ฉํ Domain-specific-language๋ฅผ ์ฌ์ฉ ( ์ฝ๋๊ฐ ๊ฐ๊ฒฐ)
- ์ด๋ task๊ฐ ์ ๋ฐ์ดํธ ๋์๋์ง ์ฒดํฌ
- ์ด๋ฏธ ๋ฐ์๋ ๋น๋ ๋ถ๋ถ์ ๋์ด์ ์ฌ ์คํ๋์ง ์๋๋ค. -> ๋น๋ ์๊ฐ ๋จ์ถ
- Maven
- java8์ฉ ํ๋ก์ ํธ ๊ด๋ฆฌ ๋๊ตฌ apache์ ant ๋์
- ์ธ๋ถ ์ ์ฅ์์์ ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ, ํ๋ฌ๊ทธ์ธ๋ค์ ๋ค์ด๋ก๋ ํ ํ , ๋ก์ปฌ ์์คํ ์ ์บ์์ ๋ชจ๋ ์ ์ฅ
- ๊ทธ๋์ ์ Gradle์ธ๋ฐ!!!
- Gradle์ ์์ ์์กด์ฑ์ ๊ทธ๋ํ, Maven์ ๊ณ ์ ์ ์ด๊ณ ์ ํ์ ๋ชจ๋ธ์ ๊ธฐ๋ฐ
- Gralde์ ์ด๋ค task๊ฐ ์ ๋ฐ์ดํธ๋์๊ณ ์๋์๋์ง๋ฅผ ์ฒดํฌ
- Gradle์ ์ด๋ฏธ ์ ๋ฐ์ดํธ ๋ task์ ๋ํด์๋ ์์ ์ด ์คํ๋์ง ์์ผ๋ฏ๋ก ๋น๋ ์๊ฐ ๋จ์ถ
- ๋น๋ ์ค์ ๊ท๋ชจ๊ฐ ์์ผ๋ฉด ํฐ ์ฐจ์ด๋ฅผ ๋๋ผ์ง ๋ชปํ์ง๋ง ๊ท๋ชจ๊ฐ ํฌ๋ฉด ํจ์ฌ Gradle์ ๋น๋ ์๊ฐ์ด ๋จ์ถ๋๋ค๋๊ฑธ ์ ์ ์๋ค.
- Gradle
- Gradle๊ณผ Maven ์ฐจ์ด๋ฅผ ์๋ฉด Gradle์ด ์ ํ์ํ์ง ์ ์ ์๋ค.
<Dependencies>
- Spring Web : ์น ์ดํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ๊ธฐ ์ํ ํต์ฌ ๊ธฐ๋ฅ ์ ๊ณต
- Thymeleaf : View Template, ๋์ ์ผ๋ก ํ๋ฉด์ ๊ตฌ์ฑํ ์ ์๊ฒ ํด์ค
- Spring Data JPA : JPA๋ฅผ ์ด์ํ ๊ตฌํ์ฒด๋ฅผ ๋ ์ถ์ํ์์ผ ๋ ์ฝ๊ณ ๊ฐํธํ๊ฒ JPA๋ฅผ ์ด์ฉ ๊ฐ๋ฅ
- mysql driver : mysql๋ฅผ ์ฐ๋ํ ๋ ํ์ํ dependency
- h2 database : RDBMS, ํ ์คํธ ๋จ๊ณ ๋๋ ์์ ๊ท๋ชจ์ ํ๋ก์ ํธ์์ ์ฌ์ฉ
- validation : ๋ฐ์ดํฐ์ ๋ํ ์ ํจ์ฑ ๊ฒ์ฆ ์ฒ๋ฆฌ๋ฅผ ์ํ
- Spring Security : ํํ์ด์ง์ ์ธ์ฆ ๋ฐ ๊ถํ ๊ธฐ๋ฅ์ ๋น ๋ฅด๊ฒ ๋ถ์ฌํด ์ธ์ฆ ๋ฐ ๊ถํ ๋ณดํธ ๊ธฐ๋ฅ์ ์์ฝ๊ฒ ์ถ๊ฐํ ์ ์์.
<ํ๋ก๊ทธ๋จ์ด ์์๋๋ ์์๋๋ ์ฝ๋>
src/main/kotlin/PortfolioApplicatioin.kt
fun main(args: Array<String>) {
runApplication<PortfolioApplication>(*args)
}
Whitelabel Error Page ์ค๋ฅ๊ฐ ๋จ๋ ์ด์ : ์ดํ๋ฆฌ์ผ์ด์ ์ด ๋ญ ํด์ผ ํ ์ง ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ Whitelabel Error Page๋ฅผ ๋ณด๋ด์ค.(์ ์)
<Git ์ฉ์ด>
Git : ๋ถ์ฐ ๋ฒ์ ๊ด๋ฆฌ ์์คํ ⇒ ํ์ ์ ์ฝ๊ฒ ํด์ฃผ๋ ํด : GitHub
Commit : git์ ์ ์ฅํ๋ ๋จ๊ณ
Rollback : ์ด๋ ฅ ๋๋๋ฆฌ๊ธฐ
Branch : branch ์์ฑ ๋ฐ ์ ๊ฑฐ, ํ์ธ๋ฑ์ ๊ธฐ๋ฅ์ ํ๋ ๋ช ๋ น์ด
Merge : ๋ธ๋์น ๋ณํฉ
Conflict : ์ถฉ๋
Repository : ์๊ฒฉ ์ ์ฅ์ , ์ธํฐ๋ท์ด๋ ๋คํธ์ํฌ ์ด๋๊ฐ์ ์๋ ์ ์ฅ์
Push : ๋ก์ปฌ ๋ธ๋์น๋ฅผ ์๊ฒฉ ์ ์ฅ์๋ก ํธ์ํ ๋ ์ฌ์ฉํ๋ ๊ธฐ๋ณธ ๋ช ๋ น์ด
<Git ๋ช ๋ น์ด>
- git init : git ๊ณต๊ฐ์ผ๋ก ์ด๊ธฐํ
- git status ๋ช ๋ น์ด ์ ๋ ฅ์ Untracked files ๋ผ๋ ๊ฒ ์๋๋ฐ ์ด๊ฑด git์์ ๋ฐ๋ก ์ค์ ์ ์ํ๋ค๋ ์๋ฆฌ
- https://www.toptal.com/developers/gitignore/ : gitignore ํ์ผ์ ์๋์ผ๋ก ๋ง๋ค์ด์ค
<github์ PUSH ๋ฐฉ๋ฒ>
- ํฐ๋ฏธ๋์์ git init
- git remote “git ์ ์ฅ์”
- → ์ธํ ๋ฆฌ์ ์ด(GUI)๋ก ํ ์์๋ git → Manage Remote
- commit
- push
<application-default.yml , application-docker.yml>
profile์ด default ์ด๋ฉด, application-default.yml ํ์ผ์์ ํ๊ฒฝ๋ณ์๋ฅผ ๊ฐ์ ธ์ค๊ณ
profile์ด docker ์ด๋ฉด, application-docker.yml ํ์ผ์์ ํ๊ฒฝ๋ณ์๋ฅผ ๊ฐ์ ธ์จ๋ค.
application-default.yml ํ์ผ์์ spring:jpa:hibernate:ddl-auto:create ์ธ๋ฐ
์ application-docker.yml ํ์ผ์์๋ spring:jpa:hibernamte:ddl-auto:none ์ผ๊น?
=> application-default.yml ์์๋ ๊ฐ๋ฐ ๋ชฉ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค ์คํค๋ง๋ฅผ ๋งค๋ฒ ์ฌ์์ฑํ ํ์๊ฐ ์์ง๋ง, application-docker.yml ์์๋ ๋ฒ ํฌ ๋ฐ ์ด์ ํ๊ฒฝ์ ์ ํฉํ๊ฒ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ตฌ์กฐ๊ฐ ๋ณ๊ฒฝ๋์ง ์๋๋ก ํ๊ธฐ ์ํ ์ค์
<์ด๋ ธํ ์ด์ ์ ๋ฆฌ>
@Id : ํด๋น ํ ์ด๋ธ์ PK ํ๋๋ฅผ ์๋ฏธ
@Entity : JPA๋ฅผ ์ฌ์ฉํด ํ ์ด๋ธ๊ณผ ๋งคํํ ํด๋์ค์ ๋ถ์ฌ์ฃผ๋ ์ด๋ ธํ ์ด์
@GeneratedValue : JPA์์ Entity์ PK๋ฅผ ์์ฑํ์ฌ ์ฃผ๋ ๊ธฐ๋ฅ
-> @GeneratedValue(name="member_id") : PK๋ก ์ฌ์ฉ๋ Entity์ ํ๋กํผํฐ์ @Id ์ด๋ ธํ ์ด์ ์ ์ธ
-> @GeneratedValue(strategy=GenerationType.IDENTITY) : ๊ธฐ๋ณธ ํค ์์ฑ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์์ํ๋ค.
-> @GeneratedValue(strategy=GenerationType.AUTO) : ๊ธฐ๋ณธ๊ฐ์ผ๋ก DB ๋ฐฉ์ธ์ ๋ง์ถฐ ์๋์ผ๋ก ์ค์ ํ์ฌ ์ค๋ค.
@Column : ๊ฐ์ฒด ํ๋์ DB ํ ์ด๋ธ ์นผ๋ผ์ ๋งตํํ๋ค.
@Component : ํด๋์ค๋ฅผ ์๋์ผ๋ก ๋น์ผ๋ก ๋ฑ๋กํ๊ธฐ ์ํด ํด๋์ค ๋ ๋ฒจ์์ ์ฌ์ฉ
@Profile : ๋น์ด๋, ์ปดํจ๋ํธ์๊ฒ ํ๋กํ์ ์ ํด์ค ์ ์์
@PostConstruct : ๊ฐ์ฒด์ ์์ฑ์ด ์ผ์ด๋ ์ง ํ์ ์ด๊ธฐํ๋ฅผ ์ํํ๋ ๋ฉ์๋์ ๋ถ์ฐฉํ๋ค.
@ManyToOne : ๋จ๋ฐฉํฅ ๊ด๊ณ์ด๊ณ FK๊ด๋ฆฌ์ ์์ด์ ๊ฐ์ฅ ์์ฐ์ค๋ฝ๋ค. @JoinColumn ์ด๋ ธํ ์ด์ ๊ณผ ๊ฐ์ด ์ฐ์ธ๋ค.
@JoinColumn : ์ํฐํฐ ํ ์ด๋ธ์ FK ์นผ๋ผ์ ์ ์ํด์ค๋ค.
์๋ฃํ๋ค์ ? ๋ ๋ฌด์จ ์๋ฏธ์ผ๊น ?
ex ) Long?
์๋ฃํ ๋ค์ ? ๊ฐ ์ค๋ ๊ฒ์ Kotlin์์ ์ฌ์ฉ๋๋ ๋ฌธ๋ฒ์ด๊ณ ?๋ฅผ ์๋ฃํ ๋ค์ ๋ถ์ด๋ ๋ฐฉ์์ nullable ์ฌ๋ถ๋ฅผ ๋ํ๋ธ๋ค. ์๋ฅผ ๋ค๋ฉด var name: String? = null ์ด ์ฝ๋๋ ํด๋น ๋ณ์ name์ null ๊ฐ์ด ์ฌ ์๋ ์๋ค๋ ๋ป์ด๋ค.
<์ฝ๋ ๋ถ์>
- var type: SkillType = SkillType.valueOf(type) : SkillType.valueOf(type) ์ type์ด๋ผ๋ ๋ฌธ์์ด์ SkillType ์ด๊ฑฐํ์ ๊ฐ์ผ๋ก ๋ณํ. ๋ง์ฝ type์ด ์ด๊ฑฐํ์ ์๋ ๊ฐ์ด๋ฉด ์์ธ ๋ฐ์
- var cookies: String? = httpServletRequest.cookies ?.map {"${it.name}:${it.value}"} ?.toString() : httpServletRequest์์ ์ฟ ํค ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๊ณ , ์ฟ ํค ์ด๋ฆ๊ณผ ๊ฐ์ "์ด๋ฆ:๊ฐ" ํ์์ผ๋ก ๋ณํํ๋ ์ฝ๋
- var referer: String? = httpServletRequest.getHeader("referer") : HTTP ์์ฒญ์์ "Referer" ํค๋ ๊ฐ์ ๊ฐ์ ธ์จ๋ค. ์ด ์ฝ๋๋ ์ฌ์ฉ์๊ฐ ์ด๋ค ํ์ด์ง์์ ํ์ฌ ํ์ด์ง๋ก ์ด๋ํ๋์ง ๋ํ๋
- @OneToManyvar details: MutableList<ExperienceDetail> = mutableListOf() : JPA ๊ด๊ณ๋ฅผ ๋ํ๋ด๊ณ , ์ํฐํฐ ๊ฐ์ ์ผ๋๋ค(One-to-Many) ๊ด๊ณ๋ฅผ ๋ํ๋
2. ๋ฏธ์
๋ฏธ์ 1๊ณผ 2๋ฅผ ์ ์ถํ๋๊ฑด๋ฐ, ๋ฏธ์ 1์ ํ ์ด๋ธ ์ค๊ณํ๊ธฐ์ ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ ํ๋ก์ ํธ ์ฌ๋ฆฌ๊ธฐ์ด๋ค.
๋ฏธ์ 1 : https://github.com/HyupTech/LMS/commit/fa47b404d36b3ce418f16213e3bb30ca96b812ed
๋ฏธ์ 2 : https://github.com/HyupTech/LMS/commit/0993897036a0e17e7a366031b950235edd5d506e
3. ํ๊ณ
๋ฐ์๊ตญ์ ์์ฑํ๋ฉด์ ๋๋ ์ด์ ๊น์ง ๊ฐ์๋ฅผ ๋ณด๋ฉด์ ๊ณต๋ถ๋ฅผ ํ์ง๋ง ๋ค์ ํ๋ฒ ์ด๋ ๊ฒ ์ ๋ฆฌ๋ฅผ ํด๊ฐ๋ฉด์ ๊ฐ์๋ฅผ ๋ณด์ง ์์๋ค. ์๋ํ๋ฉด ์๊ฐ์ด ๋๋ฌด ์๊น์ ๊ณ , ์ฐจ๋ผ๋ฆฌ ์ ๋ฆฌํ๋ ์๊ฐ์ ๊ฐ์๋ฅผ ํ๋ ๋ ๋ณด์๋ ๋ง์ธ๋์๋ค. ํ์ง๋ง ๋ฐ์๊ตญ์ ์จ๋ณด๋ฉด์ ์ ์ด๋ ๊ฒ ์ข์๊ฑธ ๋ด๊ฐ ์ํ์๊น๋ผ๋ ํํ๊ฐ ๋ค๊ณ , ์ด๋ ๊ฒ ์ ๋ฆฌ๋ฅผ ํด๊ฐ๋ฉด์ ํ์ผ๋ฉด ์๋ง ์ค๋ ฅ์ด ์กฐ๊ธ์ด๋ผ๋ ๋ ์ฌ๋์ง ์์๋ ๋ผ๋ ์๊ฐ์ด ๋ค์๋ค. ์์ผ๋ก ๋ฐ์๊ตญ๋ ์ฐ๊ณ , ๋ด๊ฐ ๋ฐ๋ก ๊ณต๋ถํ๊ณ ์๋๊ฒ๋ ์ ๋ฆฌํด๊ฐ๋ฉด์ ๊ณต๋ถ๋ฅผ ํด์ผ๊ฒ ๋ค.
3-1. ๋ฏธ์ ํ๊ณ
์ด๋ฒ ๋ฏธ์ ์์ ์ฒ์์ผ๋ก ERD๋ฅผ ๊ตฌ์ฑํ๊ณ ์ด๋์ PK๋ฅผ ์ฃผ๊ณ ๊ด๊ณ ์ค์ ์ ์ด๋ป๊ฒ ํ ์ง์ ๋ํ ๊ณ ๋ฏผ์ด ๋ง์๋ ๊ฒ ๊ฐ๋ค. ํ์ฌ ๋ํ๊ต 2-2์ ์ฌํ์ค์ธ๋ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ณผ๋ชฉ์ ์๊ฐ์ค์ธ๋ฐ ๊ฝค ๋์์ด ๋์๋ ๊ฒ ๊ฐ๊ณ , ๋ฐฑ์๋ ๊ฐ๋ฐ์๊ฐ ๋ ๋ ค๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ณต๋ถ๋ ๋์ง ๋ง์์ผ๊ฒ ๋ค๊ณ ์๊ฐ์ด ๋ค์๋ค. ์์ผ๋ก ๋ ๋ง์ ๋ฏธ์ ๋ค์ด ๊ธฐ๋ค๋ฆฌ๊ณ ์๋๋ฐ ์ด์ฌํ ๊ณต๋ถ๋ฅผ ํด์ผ๊ฒ ๋ค!