2023. 3. 17. 22:14ใBack-End ์์ ์ค/Spring Framework
"์ด ํฌ์คํ ์ ์ฟ ํก ํํธ๋์ค ํ๋์ ์ผํ์ผ๋ก, ์ด์ ๋ฐ๋ฅธ ์ผ์ ์ก์ ์์๋ฃ๋ฅผ ์ ๊ณต๋ฐ์ต๋๋ค."
๐ ๋ชฉ์ฐจ
1. [Spring Boot] Discord Bot(๋์ค์ฝ๋ ๋ด) ๋ง๋ค๊ธฐ
2. [Spring Boot] Discord Bot(๋์ค์ฝ๋ ๋ด) ๋ง๋ค๊ธฐ - Spring Boot(์คํ๋ง ๋ถํธ)๋ฅผ ์ด์ฉํ ๊ฐ๋จํ API ๋ง๋ค๊ธฐ feat.Mybatis(๋ง์ด๋ฐํฐ์ค)
3. [Spring Boot] Discord Bot(๋์ค์ฝ๋ ๋ด) ๋ง๋ค๊ธฐ - JAVA๋ฅผ ์ด์ฉํ API ํธ์ถ
๐ ์์ํ๊ธฐ ์ ์
๐ฝ ๊ฐ์
์๋ ํ์ธ์? ์ฃผ๋์ ๋๋ค.
์ง๋ ๋ฒ์ ๋ง๋ค์๋ ๋์ค์ฝ๋ ๋ด์ ์ข ๋ ๋ฐ์ ์์ผ ์ด๋ฒ์๋ API๋ฅผ ํตํด Data Base(DB - ๋ฐ์ดํฐ ๋ฒ ์ด์ค)์ ์ ์ฅ๋ ๊ฐ์ ๊ฐ์ ธ์ฌ ์ ์๋๋ก ๋ฐ์ ์์ผ๋ณด๋ ค๊ณ ํด์.
์ง๋ ๋ฒ์๋ ์ธ๊ธํ์์ง๋ง, ๊ธฐ๊น๋๋ ์ฌ๋๋ค ์ง์์ ์ ๋ณด๋ฅผ ๊ฐ ๊ฐ๋ถ๋ค์ด ๋ณด๋ค ํธ๋ฆฌํ๊ฒ ๋์ค์ฝ๋์์ ํ์ธํ ์ ์๋๋ก ๊ฐ๋ฐ ์ค์ธ ๊ฒ์ด๋ผ ์ค์ ์์
์ ํ๊ธฐ ์ ์ฐ์ตํ ๊ฒ์ ๋ธ๋ก๊ทธ์ ๋จ๊ฒจ ๋ณด๋ ค๊ณ ํฉ๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก JDA๋ฅผ ์ด์ฉํ ๋์ค์ฝ๋ ๋ด ๋ง๋ค๊ธฐ๋ ์ด ๊ณณ์ ๊ด์ฌ์ ์ฃผ์ธ์.
์ฌ๋ฌ IT ํ์ฌ์์ Java - Spring(์๋ฐ - ์คํ๋ง)์ ์ด์ฉํด์ BackEnd (๋ฐฑ์๋)๋ฅผ ๋ง๋ค ๋, JPA์ QueryDSL (์ฟผ๋ฆฌ๋์์ค์) ์กฐํฉ ํน์ JPA์ MyBatis(๋ง์ด๋ฐํฐ์ค) ํน์ MyBatis๋ง์ ์ด์ฉํ์ฌ ๊ฐ๋ฐ ํ๋ ๊ณณ์ด ์๋๋ผ๊ตฌ์.
์ฃผ๋๊ฐ ๊ฒฝํํ ๋ฐ๋ก๋ ๋ง์ด๋ฐํฐ์ค๋ Back Office(๋ฐฑ ์คํผ์ค)์์ ์ฃผ๋ก ๋ง์ด ์ฌ์ฉ๋๊ณ , ์ด์ฉ์ (๋๊ตญ๋ฏผ) ์๋น์ค์ ๊ฒฝ์ฐ JPA + QueryDSL ํน์ JPA + ๋ง์ด๋ฐํฐ์ค๋ฅผ ์ฐ๋ ๊ณณ์ ๋ง์ด ๋ณด์์ด์.
๊ธฐ๊น๋๋ ์ฌ๋๋ค์ ์ด๋ฐ ์ด์ ๋๋ฌธ์ ์ด์ฉ์ ์๋น์ค์ ๊ฒฝ์ฐ JPA์ QueryDSL ์กฐํฉ์ผ๋ก ๋ฐ์ดํฐ ๋ฒ ์ด์ค๋ฅผ ์กฐ์ํ๊ณ , ๋ฐฑ ์คํผ์ค์ ๊ฒฝ์ฐ ๋ง์ด๋ฐํฐ์ค๋ฅผ ์ด์ฉํด์ ๋ฐ์ดํฐ ๋ฒ ์ด์ค๋ฅผ ์กฐ์ํ๋ ค๊ณ ํด์.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ด๋ฒ ๋์ค์ฝ๋ ๋ด ๋ง๋ค๊ธฐ ๊ธ์ ๊ธฐ๊น๋๋ ์ฌ๋๋ค ๋ฐฑ ์คํผ์ค์์ ์ฌ์ฉํ ๊ฒ์ด๊ณ , ๋ง์ด๋ฐํฐ์ค๋ฅผ ์ด์ฉํ๋ ค๊ณ ํฉ๋๋ค.
๐ฝ ์์กด์ฑ ์ถ๊ฐ
์ด ์ ๊ธ์์๋ณด๋ค ๋ ๋ง์ ์์กด์ฑ๋ค์ด ์ถ๊ฐ ๋์์ด์.
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.9'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}
group = 'com.junyss'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// Discord Bot ์ฌ์ฉ์ ์ํ JDA ์์กด์ฑ
implementation 'net.dv8tion:JDA:5.0.0-beta.5'
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.3.0'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
// MyBatis Log๋ฅผ ์ฐ๊ธฐ ์ํ ์์กด์ฑ ์ถ๊ฐ(https://mvnrepository.com/artifact/ch.qos.logback/logback-classic)
testImplementation 'ch.qos.logback:logback-classic:1.4.5'
// SQL query show
implementation 'org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4.1:1.16'
// GSON ์์กด์ฑ
// https://mvnrepository.com/artifact/com.google.code.gson/gson
implementation 'com.google.code.gson:gson:2.10.1'
// https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple
implementation 'com.googlecode.json-simple:json-simple:1.1.1'
//SpringDoc ์์กด์ฑ ์ถ๊ฐ
// https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-ui
implementation 'org.springdoc:springdoc-openapi-ui:1.6.14'
// https://mvnrepository.com/artifact/org.json/json
implementation 'org.json:json:20220924'
}
tasks.named('test') {
useJUnitPlatform()
}
๐ฝ DTO์ VO
์ต์ด API๋ฅผ ๋ง๋ค๊ธฐ ์ DTO(Data Transfer Object)์ VO(Value Object)๋ฅผ ๋จผ์ ๋ง๋ค์ด ๋ณผ๊ฒ์.
์ต์ด ๋์ค์ฝ๋ ๋ด์ ํตํด ๊ฒ์์ ํ๋ ค๊ณ ํ ๋, ๊ทธ ๊ฒ์ ํ์
๊ณผ ๊ฒ์์ด ๊ทธ๋ฆฌ๊ณ , ๋ ์ง๋ฅผ ์ด์ฉํด ๊ฒ์์ ํ ์ ์๋๋ก ๊ฐ ๋ณ์๋ฅผ ๋ง๋ค์ด ์ฃผ์์ด์.
35๋ฒ์งธ ์ค์ Method(๋ฉ์๋)๋ Client(ํด๋ผ์ด์ธํธ) ์ฆ, ์ฌ์ฉ์๊ฐ ๊ฒ์์ ์ํด ๊ฒ์์ด๋ฅผ ์
๋ ฅ ํ์ ๋, ๊ทธ ๊ฐ์ด ๋ง์ด๋ฐํฐ์ค์์ ๊บผ๋ด ์ฌ์ฉํ ์ ์๋๋ก ๋ง๋ค์ด์ค Getter(๊ฒํฐ)์ธ๋ฐ, searchType ๋ณ์๊ฐ Enum Type(์ด๊ฑฐํ ํ์
)์ด๊ณ , ์ด๋ฅผ ๊ทธ๋๋ก ๋ง์ด๋ฐํฐ์ค์์ ๊ฐ์ ธ๋ค ์ฌ์ฉํ๊ฒ ํ๋ฉด ๋ฌธ์ ๊ฐ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ String (๋ฌธ์์ด)๋ก ๋ฐ๊ฟ์ ๊ฐ์ ธ๊ฐ๊ฒ ํ๋๋ก ํ๋ ค๊ณ ๋ง๋ ๊ฒํฐ ๋ฉ์๋์์.
47๋ฒ์งธ setSearchType()์ ํด๋ผ์ด์ธํธ์์ ๊ฒ์์ ์ํด ์
๋ ฅํ ๊ฒ์ ํ์
์ ๋ฐ๊ณ , ์ด๋ฅผ switch(์ค์์น) ๋ฌธ์ ํตํด ๋ถ๊ธฐ์ฒ๋ฆฌ๋ฅผ ํ์ฌ ํด๋น ๋ฌธ์์ด์ ๋ถ์ํ๊ณ , ๊ทธ์ ๋ง๋ ์ด๊ฑฐํ ํ์
์ ๊ฐ์ searchType ๋ณ์์ ๋ฃ์ ์ ์๋๋ก ํ์ฌ ์ฃผ์์ด์.
์ด๋ฒ์๋ Response(์๋ต) DTO๋ฅผ ์ดํด ๋ณผ๊ฒ์.
์ DTO ๊ฐ์ฒด๋ ๋ง์ด๋ฐํฐ์ค๋ฅผ ํตํด ์กฐํ๋ ๊ฒ์ ๊ฒฐ๊ณผ๋ค์ Mapping(๋งคํ)ํ์ฌ ํด๋ผ์ด์ธํธ์๊ฒ ๋ฐํํด ์ฃผ๊ธฐ ์ํ ๊ฐ์ฒด์์.
toDTO()๋ ๋ง์ด๋ฐํฐ์ค์์ ์กฐํ๋ ๊ฒ์ ๊ฒฐ๊ณผ๊ฐ VO ๊ฐ์ฒดํ์ผ๋ก ๋์ค๊ฒ ๋๋๋ฐ, ์ด๋ฅผ DTO ํํ๋ก ๋ฐํํด ์ฃผ๊ธฐ ์ํ ๋ฉ์๋์์.
์ด๋ ๊ฒ ํ์ง ์๊ณ , ์ฌ๋ฌ๊ฐ์ง ๋ฐฉ๋ฒ์ ํตํด ๋งคํํ ์ ์๋๋ฐ, ์ฃผ๋๋ ์ด๋ ๊ฒ ํด ์ฃผ์์ด์.
์ฌ์ค VO์ ์๋ต DTO์ ๊ฐ์ด ๋๊ฐ๊ธฐ ๋๋ฌธ์ ๋ฐ๋ก VO๋ฅผ ๋ฐํํด ์ค๋ ๋์ง๋ง, Service(์๋น์ค)๊ฐ ์ปค์ง๋ฉด ์ปค์ง์๋ก ๋ํ, ๋ชฉ๋ก ์กฐํ๋ ์ด๋ ๊ฒ ์ ์ฒด ๋ฐ์ดํฐ๋ฅผ ๋ณด์ฌ์ฃผ์ง ์๊ธฐ ๋๋ฌธ์ ๋ฐ๋ก ์๋ต DTO๋ฅผ ๋ง๋ค๊ฒ ๋๊ธฐ ๋๋ฌธ์ ๊ทธ์ ์ค์ ์ ๋๊ณ , ๋ง๋ค์ด ์ฃผ์์ด์.
VO์ ๊ฒฝ์ฐ ์์ ๊ฐ์ด ๋ง๋ค์ด ์ฃผ์์ด์.
10๋ฒ์งธ ์ค์ ์ด๋
ธํ
์ด์
์ ๊ธฐ๋ณธ ์์ฑ์์ ์ ๊ทผ ์ ์ด๋ฅผ PROTECTED(๋ค๋ฅธ Package์ ์์๋ Class (์์ ์ ์ธ)๋ ์ ๊ทผ ๋ถ๊ฐ)๋ก ์ค์ ํ๊ธฐ ์ํด ๋ช
์ํ ๊ฒ์ธ๋ฐ, ์ด๋ ๋ฌด๋ถ๋ณํ ๊ฐ์ฒด ์์ฑ์ ๋ง๊ธฐ ์ํจ์ด์์.
๋ง์ฝ ์์์ ๋ช
์ํ ๋ชจ๋ ๋ณ์๋ฅผ ๋ค ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์์๋ง ๊ธฐ๋ณธ ์์ฑ์๊ฐ ์ฌ์ฉ๋๋๋ก ํด์ผ ํ๋๋ฐ, ์ด ์ค ํ๋๋ผ๋ ์ฌ์ฉํ์ง ์๊ณ ์ฌ์ฉํ ๊ฒฝ์ฐ new ์ฐ์ฐ์ ๋ฑ์ ์ด์ฉํด VO ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ ์ฌ์ฉํ ๋, ํด๋น VO ๊ฐ์ฒด๋ ์์ ํ์ง ์์ ๊ฐ์ฒด๊ฐ ๋ ๊ฑฐ์์.
์ฝ๊ฒ ๋งํ๋ฉด Null ๊ฐ์ ๊ฐ์ง ๋ณ์๋ฅผ ๊ฐ๊ณ ์๋ ๊ฐ์ฒด๋ผ๋ ์ด์ผ๊ธฐ์์.
์ด๋ฐ ์ํฉ์ ๋ง๊ธฐ ์ํด ์ด๋ด ๋๋ Builder(๋น๋) ๋, ๋ค๋ฅธ ๋ฉ์๋๋ฅผ ์ด์ฉํด์ ์ ๊ทผํ๊ฒ ํ๋ ๊ฒ์ด ์ข์๋ฐ, ์ฃผ๋๋ ์ฐ์ต์ด๊ธฐ ๋๋ฌธ์ ๋ชจ๋ ๋ค ์ฌ์ฉํ๋๋ก ๋ง๋ค์ด ์ค๊ฑฐ์์.
๐ฝ Controller (์ปจํธ๋กค๋ฌ)
์ด๋ฒ์๋ ํด๋ผ์ด์ธํธ ์์ฒญ์ ์ต์ ์ ์ ๋งก๊ณ ์๋ ์ปจํธ๋กค๋ฌ๋ฅผ ๋ง๋ค์ด ๋ณผ๊ฒ์.
์ปจํธ๋กค๋ฌ๋ ์์ ๊ฐ์ด ๋ง๋ค์ด ์ฃผ์๋๋ฐ, 25 ~ 32๋ฒ์งธ ์ค๊น์ง ๋ด์ฉ์ springdoc-openapi์ ์ด์ฉํ Swagger ๋ฌธ์ ์์ฑ์ ํด ์ค ๊ฑฐ์์.
์์ ๊ฐ์ด ๋์ฌ ์ ์๋๋ก ๋ง๋ค์ด ์ค๊ฑฐ์์.
์ฐธ๊ณ ๋ก ์ฃผ๋๋ @ModelAttribute๋ฅผ ํตํด ๊ฒ์ ์กฐ๊ฑด์ ๋งค๊ฐ ๋ณ์๋ก ๋ฐ์์ฃผ๋๋ก ํ์์ด์.
๐ก ์ฐธ๊ณ ์ฌํญ
RequestParam๊ณผ ModelAttribute ์ฐจ์ด
1. @RequestParam ์ด๋?
Client ์์ฒญ์ ์ ๋ฌ๊ฐ์ Handler(Controller)์ ๋งค๊ฐ ๋ณ์(Parameter)๋ก 1:1 Mapping(๋งคํ) ํ ๋ ์ฌ์ฉ
@Slf4j @Controller public class JunyssTestController { @GetMapping("/") public String getTestPage(@RequestParam("name") String name) { log.info("์ด๋ฆ : " + name); return "test"; } }
์์ ๊ฐ์ Controller๊ฐ ์์ ๋, Client๊ฐ URL์ ํตํด /?name=test ๋ผ๊ณ ์์ฒญ์ ๋ณด๋ด๊ฒ ๋๋ฉด name ๋ณ์์๋ test ๋ผ๋ ๋ฌธ์์ด์ด ๋ค์ด๊ฐ.
1. @ModelAttribute ๋?
ํด๋น ์ด๋ ธํ ์ด์ ์ Method(๋ฉ์๋) Level(๋ ๋ฒจ)๊ณผ ๋งค๊ฐ ๋ณ์ ๋ ๊ณณ์์ ์ฌ์ฉ ๊ฐ๋ฅ.
@Getter @Setter public class JunyssTestDTO { private String name; private int age; } @Slf4j @RestController public class JunyssTestController { @GetMapping("/") public String getTestPage(@ModelAttribute JunyssTestDTO junyssTestDTO) { log.info("์ด๋ฆ : " + junyssTestDTO.getName()); log.info("๋์ด : " + junyssTestDTO.getAge()); return "test"; } }โ
728x90
์์ ๊ฐ์ด DTO์ Controller๊ฐ ์์ ๋, name๊ณผ age๋ฅผ ์ธ์คํด์ค Member ๋ณ์๋ก ๊ฐ์ง๊ณ ์๋ DTO๋ฅผ ํตํด Controller์์ ํด๋น ๋งค๊ฐ ๋ณ์์ ๋ง๋ ๊ฐ๋ค์ ๋ฐ๊ฒ ํ ์ ์๋ค.
์ด ๋, ์ด์ฉ์๊ฐ URL์ ํตํด /?name=Juny&age=99 ๋ผ๊ณ ๊ฐ์ ๋ณด๋ด๊ฒ ๋๋ฉด Controller์ DTO ๊ฐ์ฒด๋ก Binding์ด ๋๊ฒ ๋๋ค.
๋จ, ํด๋น ๋งค๊ฐ ๋ณ์ ๊ฐ์ฒด๋ ๋ฐ๋์ Setter๊ฐ ์์ด์ผ ํ๋ค.
๐ฝ Service (์๋น์ค)
์ด๋ฒ์๋ ๋น์ฆ๋์ค ๋ก์ง ์ฒ๋ฆฌ๋ฅผ ๋ด๋นํ๋ ์๋น์ค ๊ฐ์ฒด๋ฅผ ๋ง๋๋ณผ๊ฒ์.
์ฃผ๋๋ SOLID ์์น ์ค OCP๋ฅผ ์งํค๊ธฐ ์ํด Interface์ ๊ตฌํ์ฒด๋ฅผ ๋ถ๋ฆฌํด์ ๋ง๋ค์ด ๋ณด์์ด์.
๋ฌผ๋ก ๋ค๋ฅธ ๋ด์ฉ์ผ๋ก ๋์ฒดํ ๊ฒ์ด ์๊ธด ํ์ง๋ง, ์ผ๋จ ๋ถ๋ฆฌํด ๋ณด์์ด์.
Interface๋ฅผ ๊ตฌํํ ๊ตฌํ์ฒด์์ ์ปจํธ๋กค๋ฌ๋ฅผ ํตํด ์ ๋ฌ๋ CrewSearchDTO๋ฅผ ๋ฐ์ ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌํ๊ฒ ํด ์ฃผ์์ด์.
30 ~ 31๋ฒ์งธ ์ค์์ crewSearchDTO๋ฅผ ์ด์ฉํด์ DAO (Data Access Object)์ findByCrewList()๋ฅผ ํธ์ถํ์ฌ ๋ฐ์ดํฐ ๋ฒ ์ด์ค์์ ์กฐํ๋ ๊ฐ์ ๊บผ๋ด์ค๊ฒ ํ์๊ณ , ์กฐํ๋ ๊ฐ์ด Null safetyํ๊ฒ ํ๊ธฐ ์ํด .filter(Objects::nonNull)์ ๋ช
์ํ๊ณ , ์กฐํ๋ ๊ฐ์ forEach ๋ฌธ์ ํตํด ๋ฐ๋ณตํ๋ฉด์ ์๋กญ๊ฒ ๋ง๋ resultArray List์ ๋ด์์ฃผ๋๋ฐ, ์ด ๋, ์์์ ์ด์ผ๊ธฐ ํ์๋ VO๋ฅผ DTO๋ก ๋ฐ๊ฟ์ฃผ๋ toDTO()๋ฅผ ํธ์ถํ์ฌ DTO ๊ฐ์ฒด๋ก ๋ฐ๊ฟ ์ค ๋ค์ resultArray์ ๋ด์ ์ฃผ์์ด์.
๊ทธ๋ฐ ๋ค ํด๋น ๋ฐฐ์ด์ ํด๋ผ์ด์ธํธ์๊ฒ ๋ฐํํด ์ฃผ๋๋ก ํ์์ด์.
๐ฝ Data Access Object (DAO - ๋ค์ค)
์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก Data Base์ ์ ์ ๊ฐ๊น์์ง๊ณ ์์ด์!
์ด๋ฒ์๋ DAO์ ๋ํด ์ดํด ๋ณผ๊ฒ์.
์ต์ด 31๋ฒ์งธ ์ค์ ์ด๋
ธํ
์ด์
์ ํตํด findByCrewList()๋ ๋ฐ์ดํฐ ๋ฒ ์ด์ค์์ ์ฝ๊ธฐ ์์
๋ง ๊ฐ๋ฅํ๊ฒ ํ๊ธฐ ์ํด ์ฌ์ฉํ์ฌ ์ฃผ์์ด์. ๋ง์ฝ ์ฐ๊ธฐ ์์
์ ํด์ผ ํ๋ค๋ฉด (reaOnly = true)๋ง ์ดํฌ์ ์์ ์ฃผ๋ฉด ๋์.
๊ทธ๋ฐ ๋ค Mapper ๊ฐ์ฒด์ findByCrewList()๋ฅผ ํธ์ถํ์ฌ ์ญ์ DTO๋ฅผ ์ ๋ฌํด ์ฃผ์์ด์.
๐ฝ MyBatis Mapper (๋งคํผ)
์ด ๊ณณ์์ ์ค์ ๋ก ๋ง์ด๋ฐํฐ์ค์ SQL ๋ฌธ์ ์์ฑํ๋ XML์ ๋งคํํด ์ค ์ ์์ด์.
@Param์ ๋ง์ด๋ฐํฐ์ค์ SQL ๋ฌธ์ฅ์ ์ฌ๋ฌ ๋งค๊ฐ ๋ณ์๊ฐ์ ์ ๋ฌํ ๋, ๋ถํ์ค์ผ ํ๋ ์ด๋
ธํ
์ด์
์ธ๋ฐ, ์ด๋ ๊ฒํด์ผ ์ฌ๋ฌ๊ฐ์ง ๋งค๊ฐ ๋ณ์๋ฅผ ๋ฐ์ ๋, ๋ช
ํํ๊ฒ ๋ง์ด๋ฐํฐ์ค SQL ๋ฌธ์ฅ์ ๋งค๊ฐ ๋ณ์๋ฅผ ์ ๋ฌํด ์ค ์ ์์ด์.
์ฃผ๋๊ฐ ์์ฑํ ๋ง์ด๋ฐํฐ์ค ๋งคํผ XML์ด์์.
์์์ ์ด์ผ๊ธฐํ๋๋ก @Param์ ํตํด ๋งค๊ฐ ๋ณ์๋ก ์ ๋ฌ๋ DTO ๊ฐ์ Getter๋ฅผ ํธ์ถํ์ฌ ํด๋น ๋ณ์์ ๊ฐ์ ๊ฐ์ง๊ณ ์ฌ ์ ์๋๋ฐ, 10๋ฒ์งธ ์ค์ ๊ฒ์ ํ์
์ด Null์ด๊ฑฐ๋, ๊ณต๋ฐฑ์ด๋ผ๋ฉด 11 ~ 31๋ฒ์งธ ์ค์ ํ์ง ์๊ฒ ํด ์ฃผ์์ด์.
๋ง์ฝ ๊ฒ์ ํ์
์ด ์๋ค๋ฉด ๊ทธ ๊ฐ์ ์ด๋ค ๋ฌธ์์ด์ด ์๋์ง ํ์ธํ๊ณ , ํด๋น ๋ฌธ์์ด์ ๋ง๋ ์ปฌ๋ผ์ searchWord ์ฆ, ๊ฒ์์ด๊ฐ ์๋์ง ๊ฒ์ํ ์ ์๊ฒ ๋ง๋ค์ด ์ฃผ์์ด์.
๊ทธ๋ฐ ๋ค 27๋ฒ์งธ ์ค์ ๋ ์ง ๋ฒ์ ๊ฒ์ฌ๋ฅผ ์ํ startDate์ endDate๊ฐ Null์ด ์๋์ง ํ์ธํ๊ณ , and ์ ์ ํตํด Null์ด ์๋๋ฉด BETWEEN A And B ๋ฅผ ์ด์ฉํ์ฌ ๋ ์ง ๋ฒ์๋ฅผ ๊ฒ์ํ ์ ์๋๋ก ์ฒ๋ฆฌํด ์ฃผ์์ด์.
33๋ฒ์งธ ์ค์๋ 10๋ฒ์งธ ์ค์ด Null์ด๊ฑฐ๋, ๊ณต๋ฐฑ ์ฆ, ๊ฒ์ ํ์
์ ๊ฐ์ด ์์ด ๊ฒ์์ด๋ฅผ ์ด์ฉํ ๊ฒ์์ด ์ด๋ค์ง์ง ์์ ๋, ๋ ์ง ๋ฒ์ ๊ฒ์๋ง์ ์ํด ํด๋น ๊ฐ์ด Null์ด ์๋๋ฉด ๋ ์ง ๋ฒ์ ๊ฒ์์ด ๋๋๋ก ์ฒ๋ฆฌํด ์ฃผ์์ด์.
๐ฝ Data Base Initialization (๋ฐ์ดํฐ ๋ฒ ์ด์ค ์ด๊ธฐํ)
์ฃผ๋๋ ํ
์คํธ๋ฅผ ์ํด ์ด๋ ๊ฒ ๋ฐ์ดํฐ ๋ฒ ์ด์ค์ ๋ฏธ๋ฆฌ ํ
์ด๋ธ์ด ๋ง๋ค์ด ์ง๋๋ก ํ์์ด์.
๊ทธ๋ฆฌ๊ณ ์ด๋ ๊ฒ ํ
์คํธ์ฉ DATA (๋ฐ์ดํฐ)๊ฐ ์์ผ ์ ์๋๋ก ํด ์ฃผ์์ด์.
์ฃผ๋๋ ์์ ๊ฐ์ด H2 Embeded (์๋ฒ ๋๋)๋ก ๋ฐ์ดํฐ ๋ฒ ์ด์ค๊ฐ ์ฌ์ฉ๋๋๋ก ํด ์ฃผ์๋๋ฐ, 20 ~ 24๋ฒ์งธ ์ค ์ค์ ์ ํด์ฃผ๋ฉด ์์ schema.sql๊ณผ data.sql์ ์ฌ์ฉํ ์ ์์ด์.
discord:
bot:
token: <Discord Bot Token Value>
spring:
h2:
console:
enabled: true
path: /h2-console
settings:
web-allow-others: true
datasource:
url: jdbc:log4jdbc:h2:~/giggal-discord-bot?serverTimezone=UTC&characterEncoding=UTF-8;MODE=MySQL;
username: sa
password:
driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
sql:
init:
mode: always
schema-locations: classpath:init/database/schema.sql
data-locations: classpath:init/database/data.sql
mybatis:
mapper-locations: classpath:mapper/*.xml
configuration:
map-underscore-to-camel-case: true
springdoc:
api-docs:
groups:
enabled: true
swagger-ui:
operations-sorter: alpha
tags-sorter: alpha
path: /swagger.html
disable-swagger-default-url: true
display-query-params-without-oauth2: true
doc-expansion: none
version: v1
display-request-duration: true
cache:
disabled: true
paths-to-match:
- /api/**
์ฃผ๋๊ฐ ๋ง๋ Source Code(์์ค ์ฝ๋)๊ฐ ๊ถ๊ธํ์ ๋ถ๋ค์ ์์ Git Hub ๋งํฌ์์ ํ์ธ ๊ฐ๋ฅํ๋๋ก ์ค๋นํด ๋์์ด์.
"์ด ํฌ์คํ ์ ์ฟ ํก ํํธ๋์ค ํ๋์ ์ผํ์ผ๋ก, ์ด์ ๋ฐ๋ฅธ ์ผ์ ์ก์ ์์๋ฃ๋ฅผ ์ ๊ณต๋ฐ์ต๋๋ค."
'Back-End ์์ ์ค > Spring Framework' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring Boot][Total-Back-Office Project] AOP, Annotation์ ์ด์ฉํ API ๋์ ์๊ฐ ์ธก์ (0) | 2023.07.15 |
---|---|
[Spring Boot] Discord Bot(๋์ค์ฝ๋ ๋ด) ๋ง๋ค๊ธฐ - ๋์ค์ฝ๋ ๋ด์ ์ด์ฉํ์ฌ API ํธ์ถ (0) | 2023.03.17 |
[Spring Boot] Discord Bot(๋์ค์ฝ๋ ๋ด) ๋ง๋ค๊ธฐ (0) | 2023.03.17 |
[Spring Boot] OncePerRequestFilter๋? (0) | 2023.02.03 |
[Spring Boot] MapStruct (0) | 2022.12.07 |