提供了一種物件與關聯映射工具來管理 Java 應用中的關係資料,用極簡的代碼就能實現對資料庫的操作訪問,實現了 Single Database 單資料庫的設定, EP 19 增加了相依套件及範例,並透過 JUnit 5 單元測試來驗證產出結果。
Table of Contents
Toggle前言
MongoDB 是一個 NoSQL 文檔型的資料庫,適合存取非結構資料,類似於 JSON 格式,可以包含其他文檔,其動態建模的特性使得它更加自由靈活,分片的資料分散處理架構,可以透過水平擴充儲存海量資料,因此適用於各種應用場景如事件紀錄、電子商務、手機應用等。
Spring Data MongoDB
檔案目錄
./
+- build.gradle
+- src
+- main
+- resources
| +- application.properties
+- java
| +- org
| +- ruoxue
| +- spring_boot_168
| +- config
| +- MongoDBConfig.java
Gradle
build.gradle
增加 Spring Boot Starter Data MongoDB 。
修改完後,點右鍵,Gradle -> Refresh Gradle Project 。
buildscript {
group 'org.ruoxue.spring-boot-168'
version = '0.0.1-SNAPSHOT'
ext {
springBootVersion = '2.1.7.RELEASE'
}
}
dependencies {
implementation "org.springframework.boot:spring-boot-starter-data-mongodb:${springBootVersion}"
}
設定 Single Database
application.properties
增加 Mongodb 設定。
spring.data.mongodb.custom.uri=mongodb://root:1111@127.0.0.1:27017/spring_boot_168?authSource=admin
spring.data.mongodb.custom.connectionsPerHost=100
spring.data.mongodb.custom.minConnectionsPerHost=8
spring.data.mongodb.custom.retryWrites=true
spring.data.mongodb.custom.connectTimeout=60000
spring.data.mongodb.custom.socketTimeout=60000
spring.data.mongodb.custom.maxConnectionIdleTime=28800000
spring.data.mongodb.custom.maxConnectionLifeTime=28800000
spring.data.mongodb.custom.maxWaitTime=60000
MongoDBConfig.java
新增檔案。
package org.ruoxue.spring_boot_168.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.mapping.model.SnakeCaseFieldNamingStrategy;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoClientOptions.Builder;
import lombok.extern.slf4j.Slf4j;
import com.mongodb.MongoClientURI;
@EnableMongoRepositories(mongoTemplateRef = "mongoTemplate", //
basePackages = { //
"org.ruoxue.spring_boot_168.chat.chat_message.repository, " //
})
@Configuration
@Slf4j
public class MongoDBConfig {
@Value("${spring.data.mongodb.custom.uri}")
private String uri;
@Value("${spring.data.mongodb.custom.connectionsPerHost}")
private int connectionsPerHost;
@Value("${spring.data.mongodb.custom.minConnectionsPerHost}")
private int minConnectionsPerHost;
@Value("${spring.data.mongodb.custom.retryWrites}")
private boolean retryWrites;
@Value("${spring.data.mongodb.custom.connectTimeout}")
private int connectTimeout;
@Value("${spring.data.mongodb.custom.socketTimeout}")
private int socketTimeout;
@Value("${spring.data.mongodb.custom.maxConnectionIdleTime}")
private int maxConnectionIdleTime;
@Value("${spring.data.mongodb.custom.maxConnectionLifeTime}")
private int maxConnectionLifeTime;
@Value("${spring.data.mongodb.custom.maxWaitTime}")
private int maxWaitTime;
@Primary
@Bean(name = "mongoBuilder")
public Builder mongoBuilder() {
Builder builder = MongoClientOptions.builder();
builder.connectionsPerHost(this.connectionsPerHost);
builder.minConnectionsPerHost(this.minConnectionsPerHost);
builder.retryWrites(this.retryWrites);
builder.connectTimeout(this.connectTimeout);
builder.socketTimeout(this.socketTimeout);
builder.maxConnectionIdleTime(this.maxConnectionIdleTime);
builder.maxConnectionLifeTime(this.maxConnectionLifeTime);
builder.maxWaitTime(this.maxWaitTime);
log.info("uri: " + this.uri);
log.info("connectionsPerHost: " + this.connectionsPerHost);
return builder;
}
@Primary
@Bean(name = "mongoClientURI")
public MongoClientURI mongoClientURI(@Qualifier("mongoBuilder") Builder builder) {
MongoClientURI mongoClientURI = new MongoClientURI(this.uri, builder);
return mongoClientURI;
}
@Primary
@Bean(name = "mongoClient")
public MongoClient mongoClient(@Qualifier("mongoClientURI") MongoClientURI mongoClientURI) {
MongoClient mongoClient = new MongoClient(mongoClientURI);
return mongoClient;
}
@Primary
@Bean(name = "mongoDbFactory")
public MongoDbFactory mongoDbFactory(@Qualifier("mongoClientURI") MongoClientURI mongoClientURI) {
return new SimpleMongoDbFactory(mongoClientURI);
}
@Primary
@Bean(name = "mongoTemplate")
public MongoTemplate mongoTemplate(@Qualifier("mongoDbFactory") MongoDbFactory mongoDbFactory) {
DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory);
MongoMappingContext mongoMappingContext = new MongoMappingContext();
mongoMappingContext.setFieldNamingStrategy(new SnakeCaseFieldNamingStrategy());
MongoConverter mongoConverter = new MappingMongoConverter(dbRefResolver, mongoMappingContext);
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory, mongoConverter);
return mongoTemplate;
}
}
測試
MongoDBConfigTest.java
新增單元測試,驗證是否符合預期 。
package org.ruoxue.spring_boot_168.config;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.ruoxue.spring_boot_168.Application;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = Application.class)
public class MongoDBConfigTest {
@Autowired
private MongoDBConfig config;
@Test
public void config() {
assertNotNull(config);
}
}
config
測試方法上點右鍵執行 Run As -> JUnit Test ,查看 console 。
2022-06-03T23:17:42.458+0800 [main] INFO mongoBuilder:75 - uri: mongodb://root:1111@127.0.0.1:27017/spring_boot_168?authSource=admin
2022-06-03T23:17:42.459+0800 [main] INFO mongoBuilder:76 - connectionsPerHost: 100
2022-06-03T00:17:42.927+0800 [MaintenanceTimer-1-thread-1] INFO connection#info:71 - Opened connection [connectionId{localValue:3}] to 127.0.0.1:27017
2022-06-03T00:17:42.927+0800 [main] INFO cluster#info:71 - Cluster created with settings {hosts=[127.0.0.1:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500}
2022-06-03T00:17:42.931+0800 [cluster-ClusterId{value='635ff1b6c313272ee09f12e2', description='null'}-127.0.0.1:27017] INFO connection#info:71 - Opened connection [connectionId{localValue:6}] to 127.0.0.1:27017
2022-06-03T00:17:42.931+0800 [cluster-ClusterId{value='635ff1b6c313272ee09f12e2', description='null'}-127.0.0.1:27017] INFO cluster#info:71 - Monitor thread successfully connected to server with description ServerDescription{address=127.0.0.1:27017, type=STANDALONE, state=CONNECTED, ok=true, version=ServerVersion{versionList=[6, 0, 2]}, minWireVersion=0, maxWireVersion=17, maxDocumentSize=16777216, logicalSessionTimeoutMinutes=30, roundTripTimeNanos=526811}
2022-06-03T00:17:42.934+0800 [MaintenanceTimer-1-thread-1] INFO connection#info:71 - Opened connection [connectionId{localValue:4}] to 127.0.0.1:27017
2022-06-03T00:17:42.938+0800 [MaintenanceTimer-1-thread-1] INFO connection#info:71 - Opened connection [connectionId{localValue:7}] to 127.0.0.1:27017
2022-06-03T00:17:42.942+0800 [MaintenanceTimer-1-thread-1] INFO connection#info:71 - Opened connection [connectionId{localValue:8}] to 127.0.0.1:27017
2022-06-03T00:17:42.946+0800 [MaintenanceTimer-1-thread-1] INFO connection#info:71 - Opened connection [connectionId{localValue:9}] to 127.0.0.1:27017
2022-06-03T00:17:42.951+0800 [MaintenanceTimer-1-thread-1] INFO connection#info:71 - Opened connection [connectionId{localValue:10}] to 127.0.0.1:27017
2022-06-03T00:17:42.954+0800 [MaintenanceTimer-1-thread-1] INFO connection#info:71 - Opened connection [connectionId{localValue:11}] to 127.0.0.1:27017
心得分享
實現單一資料庫的連線池,設定連線池最大與最小連線數限制,及取得連線逾時,閒置逾時等功能,讓資料庫連線更有效率,節省系統資源的耗用。