使用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
對象,下面的代碼重新配置了主機、端口号和database。更多配置資訊可以參考
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所寫)