์ด๋ฒ ํ๋ก์ ํธ์์๋ Java + SpringBoot + Mongo DB ๋ก ๊ตฌํํ ์์ ์
๋๋ค.
๊ฐ๊ฐ ์ฌ์ฉํ ๋ฒ์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- Java 8 (์ค๋ผํดjdk๊ฐ ์์ฉ๋ชฉ์ ์ผ๋ก๋ ์ ๋ฃํ๋์ด ์ถํ ์ฝํ๋ฆฐ์ผ๋ก ๋ณ๊ฒฝํ๋ ํ๋ก์ ํธ๋ฅผ ์งํํด๋ด์ผ๊ฒ ๋ค์)
- Springboot 2.4.0 (20๋
11์ ํ์ฌ ์ต์ ๋ฒ์ )
- Mongo DB 4.4.2 Community Server (20๋
11์ ํ์ฌ ์ต์ ๋ฒ์ )
๋ชฝ๊ณ ๋๋น ์ค์น ๊ด๋ จํด์๋ ๋ชฝ๊ณ DB ์ต์ ๋ฒ์ ์ค์นํ๊ธฐ ํฌ์คํ
์ ์ฐธ๊ณ ํ์๋ฉด ๋ฉ๋๋ค.
์ค์น ํ ์ฌ์ฉ์ ๊ณ์ ์์ฑ ๋ฐ ๋ฐ์ดํฐ ๋ฒ ์ด์ค ์์ฑ ๊ด๋ จํด์๋ [๋ชฝ๊ณ DB] ๊ธฐ๋ณธ๋ช
๋ น์ด ํฌ์คํ
์ ์ฐธ๊ณ ํด์ฃผ์ธ์.
์ด์ ๊ทธ๋๋ค ์๋ฐ ํ๋ก์ ํธ๋ฅผ ํ๋ ์์ฑํ์ฌ Blog > ๋ค์ด์ด๋ฆฌ ๋ฉ๋ด์์ ์ฌ์ฉํ CRUD๋ฅผ ์์๋๋ก ์์ฑํด๋ณด๊ฒ ์ต๋๋ค.
๊ฐ์ฅ ๋จผ์ ํ๋ก์ ํธ ๊ตฌ์ฑ์ ํ๋ฒ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์ฐ์ build.graldeํ์ผ์ ์๋์ ๊ฐ์ด ์์ฑํ์ต๋๋ค.
plugins {
id "org.springframework.boot" version "2.4.0"
id 'java'
}
group 'com.keichee'
version '1.0-SNAPSHOT'
sourceCompatibility = "1.8"
repositories {
jcenter()
}
ext {
springVersion = '2.4.0'
}
dependencies {
testImplementation group: 'junit', name: 'junit', version: '4.12'
implementation 'org.mongodb:mongodb-driver-sync:4.1.1'
testImplementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3'
implementation "org.springframework.boot:spring-boot-starter-web:$springVersion"
testImplementation("org.springframework.boot:spring-boot-starter-test:$springVersion") {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
compileOnly 'org.projectlombok:lombok:1.18.16'
annotationProcessor 'org.projectlombok:lombok:1.18.16'
testCompileOnly 'org.projectlombok:lombok:1.18.16'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.16'
implementation "io.springfox:springfox-boot-starter:3.0.0"
implementation 'io.springfox:springfox-swagger-ui:3.0.0'
implementation 'com.google.guava:guava:30.0-jre'
}
test {
useJUnitPlatform()
}
mongodb-driver ๋ sync 4.1.1 ์ ์ฌ์ฉํ์ต๋๋ค.
๋ก๊น
์ ์ํด์ logback-classic์ ์ถ๊ฐํ๊ณ
api ๋ฅผ ์ฝ๊ฒ ๋ง๋ค ์ ์๋๋ก spring-boot-starter-web์ ์ถ๊ฐ
getter, setter ๋ฑ์ ์ด๋
ธํ
์ด์
์ฌ์ฉ์ ์ํด lombok ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ถ๊ฐํ์๊ณ
์ค์จ๊ฑฐ ๋ฌธ์๋ฅผ ์ฌ์ฉํ๋ ค๊ณ springfox ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค๋ ์ถ๊ฐํ์ต๋๋ค.
์ด์ ๋ชฝ๊ณ DB์ ์ฐ๊ฒฐ์ ์ํ ์ค์ ์ ์๋์ ๊ฐ์ด ํด์ค๋๋ค.
@Configuration
public class MongoConfig {
private static final String host = "localhost";
private static final int port = 27017;
private static final String database = "blogapp";
@Bean
public MongoDatabase blogAppDatabase() {
MongoClient client = MongoClients.create(
MongoClientSettings.builder()
.applyToClusterSettings(builder ->
builder.hosts(Collections.singletonList(new ServerAddress(host, port))))
.build());
return client.getDatabase(database);
}
}
์ปจํธ๋กค๋ฌ์๋ ๋ฑ 4๊ฐ์ Restful API๋ฅผ ๋ง๋ค์์ต๋๋ค.
@Slf4j
@RestController
@RequestMapping("/diary/life")
@AllArgsConstructor
public class DiaryLifeController {
private final DiaryLifeService diaryLifeService;
@ApiOperation("์ ์ฒด ๋ชฉ๋ก ์กฐํ")
@GetMapping
public Response<List<Post>> getPosts() {
log.info("์ ์ฒด ๋ชฉ๋ก ์กฐํ");
return new Response<>(diaryLifeService.getPosts(null));
}
@ApiOperation("๋ค์ด์ด๋ฆฌ ํฌ์คํ
์ ๊ท์์ฑ")
@PostMapping
public Response<Void> savePost(@RequestBody Post post) {
validatePostInput(post);
diaryLifeService.createPost(post);
return new Response<>();
}
@ApiOperation("๋ค์ด์ด๋ฆฌ ํฌ์คํ
์
๋ฐ์ดํธ")
@PutMapping
public Response<Void> updatePost(@RequestBody Post post) {
validatePostInput(post);
diaryLifeService.updatePost(post);
return new Response<>();
}
@ApiOperation("๋ค์ด์ด๋ฆฌ ํฌ์คํ
์ญ์ ")
@DeleteMapping
public Response<Void> deletePost(@RequestParam String _id) {
diaryLifeService.deletePost(_id);
return new Response<>();
}
private void validatePostInput(Post post) {
if (ObjectUtils.isEmpty(post.getTitle())) {
throw new BadRequestException("No TITLE exists.");
}
if (ObjectUtils.isEmpty(post.getContent())) {
throw new BadRequestException("No CONTENT exists.");
}
}
@ExceptionHandler
public ResponseEntity<Response<String>> badRequest(BadRequestException e) {
log.error("Bad request.., e-msg:{}", e.getMessage(), e);
return ResponseEntity.badRequest().body(new Response<>(e.getMessage()));
}
}
์ค์จ๊ฑฐ๋ก ๋ณด๋ฉด ๋ค์์ฒ๋ผ ๋์ค๊ฒ ๋ฉ๋๋ค.
์ค์จ๊ฑฐ๋ฅผ ์ด์ฉํด์ ๊ธฐ๋ฅ ํ
์คํธ๋ฅผ ํ๋ฒ ํด๋ณด๊ฒ ์ต๋๋ค.
ํ์ฌ ๊ตฌํ๋ ๊ธฐ๋ฅ์ ๋ชจ๋ ์ ์์ ์ผ๋ก ๋์ํ๋ ๊ฒ ๊น์ง ํ์ธํ์ต๋๋ค.
์ฌ๊ธฐ๊น์ง ์์
ํ๋ฉด์ ์ฝ๊ฒ ํ๋ฆฌ์ง ์์๋ ๋ถ๋ถ์ ๋ชฝ๊ณ DB๋ฅผ ์ฒ์ ์ฌ์ฉํ๋ค๋ณด๋ ๋ชฝ๊ณ DB ํด๋ผ์ด์ธํธ๋ฅผ ์ด์ฉํ CRUD๋ง๋๋ ๋ถ๋ถ์ด์์ต๋๋ค. ๊ธฐ์กด RDS์๋ ๋ค๋ฅด๊ฒ ObjectID ๋ก ํธ๋ค๋ง์ ํด์ผํ๋ ๋ถ๋ถ์ด ์์๊ณ , auto increment pk ์ค์ ์ ๋ฐ๋ก ํ ์ ์์์ต๋๋ค. ๋ง์ฝ ๊ฒ์๊ธ์ ๋ฒํธ๊ฐ ํ์ํ๋ค๋ฉด ์ด๋ป๊ฒ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํด์ผํ ์ง ๊ณ ๋ฏผ์ด ์ข ๋๋ ๋ถ๋ถ์
๋๋ค. ๊ฐ ๊ฒ์๊ธ๋ง๋ค ์ํ์ค๊ฐ์ ๋ฃ์ด์ค์ผํ๋๋ฐ ๊ตฌ๊ธ๋งํด์ ๋์ค๋ ๊ฒ๋ค์ synchronized ๊ฐ ์๋ ๊ฒ ์ฒ๋ผ ๋ณด์ฌ์ ํ
์คํธ๋ ์ข ํด๋ด์ผ ํ ๊ฒ ๊ฐ์ต๋๋ค.
์ฌ๊ธฐ๊น์ง ๋ฐฑ์๋์ ๊ธฐ๋ณธ์ ์ธ ๊ตฌํ์ ์๋ฃํ์ต๋๋ค.
๋ค์ ํฌ์คํ
์์๋ ํ๋ก ํธ์ ๋ฐฑ์๋๋ฅผ ์ฐ๊ฒฐํ๋ ๋ถ๋ถ์ ๋ํด์ ์ฌ๋ฆฌ๊ฒ ์ต๋๋ค.