Spring Boot(12)——使用MongoDB
使用MongoDB
需要在Spring Boot應用中使用MongoDB,可以在pom.xml中新增spring-boot-starter-data-mongodb
依賴,這樣Spring Boot會自動配置MongoDB的相關bean,比如MongoClient、MongoTemplate等,可以參考Spring Data MongoDB的自動配置類org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration
的API文件或原始碼。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>
預設配置的MongoDB連線對應的主機是localhost,埠號是標準埠號27017,database是test。可以通過spring.data.mongodb
打頭的配置屬性進行配置,對應的屬性將繫結到org.springframework.boot.autoconfigure.mongo.MongoProperties
MongoProperties
的API文件或原始碼。
spring.data.mongodb.host=10.192.48.170 spring.data.mongodb.port=27017 spring.data.mongodb.database=test_db
之後就可以直接通過MongoTemplate進行MongoDB的操作了。下面的程式碼中定義了一個User類,其userId屬性對應MongoDB的user這個document的id屬性,username屬性對應於MongoDB的user這個document的user_name屬性。然後在測試類中,new了一個User物件,通過MongoTemplate物件把它存入到了MongoDB中。
@Document @Data public class User { @Id private Long userId; private String name; @Field("user_name") private String username; } @SpringBootTest(classes=Application.class) @RunWith(SpringJUnit4ClassRunner.class) public class MongoTest { @Autowired private MongoTemplate mongoTemplate; @Test public void testSave() { User user = new User(); user.setUserId(2L); user.setName("張三"); user.setUsername("zhangsan"); this.mongoTemplate.save(user); } }
也可以定義Spring Data Repository,通過Repository對MongoDB進行訪問。定義的Repository,Spring Boot將自動對其進行掃描,由org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration
定義,掃描路徑是Spring Boot啟動類所在的包。有需要也可以手動加上@EnableMongoRepositories
以指定需要掃描的路徑。下面的程式碼定義了一個UserRepository,其繼承自標準的MongoRepository,同時又按照Spring Data的規範定義了一個findByName方法。
public interface UserRepository extends MongoRepository<User, Long> { List<User> findByName(String name); }
之後可以直接在需要的地方注入UserRepository,通過UserRepository訪問MongoDB,下面的程式碼中就分別利用注入的UserRepository進行了User物件的新增和查詢操作。
@SpringBootTest(classes=Application.class) @RunWith(SpringJUnit4ClassRunner.class) public class MongoTest { @Autowired private UserRepository userRepository; @Test public void testSave() { User user = new User(); user.setUserId(3L); user.setName("張三"); user.setUsername("zhangsan"); this.userRepository.save(user); } @Test public void testFindByName() { List<User> users = this.userRepository.findByName("張三"); Assert.assertNotNull(users); Assert.assertEquals("張三", users.get(0).getName()); } }
本文旨在描述在Spring Boot應用中如何使用MongoDB,所以對Spring Data MongoDB的內容沒有講解太多。
基於Reactive程式設計
如果期望基於Reactive程式設計則可以引入spring-boot-starter-data-mongodb-reactive
依賴。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId> </dependency>
引入該依賴後Spring Boot將自動配置一個ReactiveMongoTemplate,它預設使用Reactor實現進行Reactive程式設計。我們可以直接在應用中注入ReactiveMongoTemplate例項,通過它進行相關Reactive操作。下面的程式碼展示了通過ReactiveMongoTemplate進行User物件的儲存操作。
@SpringBootTest(classes=Application.class) @RunWith(SpringJUnit4ClassRunner.class) public class MongoTest { @Autowired private ReactiveMongoTemplate reactiveMongoTemplate; @Test public void testReactive() { User user = new User(); user.setUserId(4L); user.setName("李四"); user.setUsername("lisi"); Mono<User> mono = this.reactiveMongoTemplate.save(user); mono.block(); } }
Repository中的相關操作也是可以基於Reactive的,這需要我們定義的Repository繼承自下面的四個介面之一,其中前面兩個是基於Reactor實現,後面兩個是基於RxJava2實現。以SortingRepository結尾的Repository都繼承自對應的CrudRepository。
- ReactiveCrudRepository
- ReactiveSortingRepository
- RxJava2CrudRepository
- RxJava2SortingRepository
添加了spring-boot-starter-data-mongodb-reactive
依賴後,會自動新增Reactor依賴,所以可以直接使用ReactiveCrudRepository和ReactiveSortingRepository。下面的程式碼中定義的ReactiveUserRepository就是基於ReactiveSortingRepository實現的,同時擴充套件了一個查詢操作findByUsername
,其返回結果是Reactor實現的Flux。
public interface ReactiveUserRepository extends ReactiveSortingRepository<User, Long> { Flux<User> findByUsername(String username); }
上面定義的ReactiveUserRepository也會被自動掃描到,並被註冊為Spring bean,在程式中可以直接注入ReactiveUserRepository物件進行使用,比如下面程式碼這樣。
@SpringBootTest(classes=Application.class) @RunWith(SpringJUnit4ClassRunner.class) public class MongoTest { @Autowired private ReactiveUserRepository reactiveUserRepository; @Test public void testReactiveUserRepository() throws Exception { User user = new User(); user.setUserId(System.currentTimeMillis()); user.setName("李四"); user.setUsername("lisi"); Mono<User> mono = this.reactiveUserRepository.save(user); mono.subscribe(u -> System.out.println("saved success : " + u)); //get users by username Flux<User> flux = this.reactiveUserRepository.findByUsername("lisi"); flux.subscribe(System.out::println); TimeUnit.SECONDS.sleep(1); } }
如果需要使用RxJava2CrudRepository和RxJava2SortingRepository,則需要引入RxJava2的依賴。
<dependency> <groupId>io.reactivex.rxjava2</groupId> <artifactId>rxjava</artifactId> </dependency>
之後可以像使用ReactiveCrudRepository一樣使用它們。下面的程式碼定義了一個基於RxJava2的Repository,同時擴充套件了一個findByUsername
查詢,返回型別是RxJava2實現的Flowable。
public interface RxJava2UserRepository extends RxJava2SortingRepository<User, Long> { Flowable<User> findByUsername(String username); }
它也可以直接被掃描和定義為一個Spring bean,所以也可以直接在程式中進行注入。
@SpringBootTest(classes=Application.class) @RunWith(SpringJUnit4ClassRunner.class) public class MongoTest { @Autowired private RxJava2UserRepository rxJava2UserRepository; @Test public void testRxJava2UserRepository() throws Exception { User user = new User(); user.setUserId(System.currentTimeMillis()); user.setName("李四"); user.setUsername("lisi"); Single<User> single = this.rxJava2UserRepository.save(user); System.out.println("saved success : " + single.blockingGet()); //get users by username Flowable<User> flowable = this.rxJava2UserRepository.findByUsername("lisi"); flowable.subscribe(System.out::println); TimeUnit.SECONDS.sleep(1); } }
(注:本文是基於Spring Boot 2.0.3所寫)