-
[29]스프링데이터: NoSQL - MongoDBSpring/Spring boot 2020. 9. 7. 10:11반응형
MongoDB는 NoSQL의 일종으로 JSON 기반의 document database이기 때문에 schema가 없습니다.
(성숙한 NoSQL은 클러스터를 만들기 쉽습니다.) 1
Spring boot에서 MongoDB를 사용하기 위해서는 관련된 의존성을 추가해야 합니다. 의존성 추가를 위해 pom.xml에 다음 내용을 추가해 줍니다.
<dependencies> ... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> ... </<dependencies>
spring webflux를 사용할 경우에는 위의 의존성 대신 spring-boot-starter-data-mongodb-reactive를 추가해줍니다.
Docker를 통해 MongoDB를 설치합니다.
docker run -p 27017:27017 --name mongo_boot -d mongo
docker hub에서 설치기 원하는 이미지에 대한 가이드가 있으므로 서비스되는 port번호를 비롯해 컨테이너 실행에 필요한 정보가 있을 경우 docker mongodb 와 같이 검색해서 docker hub를 통해 정보를 확인합니다.
계정 정보를 MongoDB에 담는 예제를 통해 spring boot에서 MongoDB를 사용하는 방법을 간단히 살펴보도록 하겠습니다.
account 패키지를 만들고 Account class와 AccountRepository interface를 각각 생성합니다.
먼저 Account class의 코드입니다.
package me.dave.account; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; @Document(collection = "accounts") // ① public class Account { @Id private String id; private String username; private String email; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
① collection을 지정한 document로 맵핑합니다. collection은 RDB의 table 정도로 생각할 수 있습니다.
다음은 CRUD를 위한 AccountRepository interface 코드입니다.
package me.dave.account; import org.springframework.data.mongodb.repository.MongoRepository; import java.util.Optional; public interface AccountRepository extends MongoRepository<Account, String> { Optional<Account> findByEmail(String email); // ① }
① Email을 기준으로 데이터를 조회하는 findByEmail 메서드를 정의합니다.
실행을 위한 ApplicationRunner를 작성합니다. main class인 Application class 안에 람다 표현식으로 runner를 추가해보도록 합니다.
package me.dave; import me.dave.account.Account; import me.dave.account.AccountRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.ApplicationRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.data.mongodb.core.MongoTemplate; @SpringBootApplication public class Application { @Autowired MongoTemplate mongoTemplate; @Autowired AccountRepository accountRepository; public static void main(String[] args) { SpringApplication app = new SpringApplication(); app.setWebApplicationType(WebApplicationType.SERVLET); app.run(Application.class, args); } @Bean public ApplicationRunner applicationRunner() { return args -> { Account account1 = new Account(); account1.setEmail("dave@gmail.com"); account1.setUsername("Dave Kim"); //1.MongoTemplate를 사용하여 data insert mongoTemplate.insert(account1); Account account2 = new Account(); account2.setEmail("camel@gmail.com"); account2.setUsername("Camel"); //2. AccountRepository를 사용하여 data insert accountRepository.insert(account2); }; } }
위의 코드를 실행하고 난 뒤 MongoDB에서 결과를 확인합니다.
MongoDB 컨테이너에서 bash를 실행합니다.
docker exec -i -t mongo_boot bash
bash에서 MongoDB를 실행합니다.
코드에서 MongoTemplate로 한 번, MongoRepository로 한 번 총 두번 데이터를 insert 했는데, 조회해보니 성공적으로 insert 된 거 같네요.
MongoDB는 슬라이싱 테스트를 쉽게 진행할 수 있도록 내장형 DB로도 사용할 수 있습니다.
내장형 MongoDB 사용을 위한 의존성 추가
<dependencies> ... <dependency> <groupId>de.flapdoodle.embed</groupId> <artifactId>de.flapdoodle.embed.mongo</artifactId> <scope>test</scope> </dependency> ... </<dependencies>
우리는 CRUD 기능을 테스트하고 있으니 AccountRepository interface에 대해 테스트 코드를 작성해보도록 합니다.
AccountRepositoryTest class를 테스트를 위한 경로에 추가하고 그 내용을 다음과 같이 작성합니다.
package me.dave.account; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; @RunWith(SpringRunner.class) @DataMongoTest // ① public class AccountRepositoryTest { @Autowired AccountRepository accountRepository; // ② @Test public void findByEmail() { Account account = new Account(); // ③ account.setUsername("Camel"); // ③ account.setEmail("sos@test.com"); // ③ accountRepository.save(account); // ③ Optional<Account> byId = accountRepository.findById(account.getId()); assertThat(byId).isNotEmpty(); // ④ Optional<Account> byEmail = accountRepository.findByEmail(account.getEmail()); assertThat(byEmail).isNotEmpty(); // ⑤ assertThat(byEmail.get().getUsername()).isEqualTo("Camel"); // ⑥ } }
① class @DataMongoTest annotaion을 붙이면 MongoRepository 관련 bean들이 주입됩니다.
② test하기위한 기능을 가진 MongoRepository <T, ID> 타입을 상속받은 AccountRepository 타입 bean을 주입받습니다.
③ 이후 Account 객체를 하나 생성하여 상태 정보를 입력하고 MongoDB로 저장합니다.
④ account의 id로 조회한 결과가 있는 경우 테스트를 통과합니다.
⑤ account의 email로 조회한 결과가 있는 경우 테스트를 통과합니다.
⑥ account의 email로 조회한 정보의 username이 account 객체 생성 시 지정한 "Camel"과 동일하면 테스트를 통과합니다.
terminal로 돌아가 docker에 실행 중인 mongodb의 내용을 확인해 보면 테스트 데이터는 추가되지 않았네요. 성공적으로 테스트 환경을 구축한 것 같습니다.
이 예제의 전체 소스코드는 github.com/camel-master/MongoDB-Example.git 에서 받을 수 있습니다.
MongoDBdml 명령어를 간단히 정리해 놓은 블로그 (sjh836.tistory.com/100)
- 고가용성(장애 복구를 단시간 내에 진행할 수 있도록 하기위해), 병렬처리(대량의 데이터 처리 속도 개선을 위해), 성능향상(대량 트래픽이 발생하는 웹서비스의 속도를 개선하기 위해)을 위해 DB를 여러개의 서버가 나눠서 처리하도록 하는 형태 [본문으로]
'Spring > Spring boot' 카테고리의 다른 글
[31] 스프링 시큐리티 (0) 2020.09.10 [30] 스프링 데이터: NoSQL - Neo4j (0) 2020.09.08 [28] 스프링데이터: NoSQL - Redis (0) 2020.09.05 [27] Spring Data : Database Migration Tool (FlyWay) (0) 2020.07.21 [26] Spring Data : Initialization of Database (0) 2020.07.17