Spring Data MongoDB Multiple Databases - Spring Boot 168 EP 20

Spring Data MongoDB Multiple Databases – Spring Boot 168 EP 20

提供了一種物件與關聯映射工具來管理 Java 應用中的關係資料,用極簡的代碼就能實現對資料庫的操作訪問,實現了多資料庫的設定, EP 20 增加了相依套件及範例,並透過 JUnit 5 單元測試來驗證產出結果。

前言

MongoDB 是一個 NoSQL 文檔型的資料庫,適合存取非結構資料,類似於 JSON 格式,可以包含其他文檔,其動態建模的特性使得它更加自由靈活,分片的資料分散處理架構,可以透過水平擴充儲存海量資料,因此適用於各種應用場景如事件紀錄、電子商務、手機應用等。

Spring Data MongoDB

檔案目錄

./
   +- build.gradle
       +- src
           +- main
               +- resources
               |   +- application.properties
               +- java
               |   +- org
               |       +- ruoxue
               |           +- spring_boot_168
               |               +- config
               |                   +- LogMongoDBConfig.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}"
}

設定 Multiple Databases

application.properties

增加 Datasource 設定。

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

spring.data.mongodb.log.custom.uri=mongodb://root:1111@127.0.0.1:27017/spring_boot_168_log?authSource=admin
spring.data.mongodb.log.custom.connectionsPerHost=100
spring.data.mongodb.log.custom.minConnectionsPerHost=8
spring.data.mongodb.log.custom.retryWrites=true  
spring.data.mongodb.log.custom.connectTimeout=60000
spring.data.mongodb.log.custom.socketTimeout=60000  
spring.data.mongodb.log.custom.maxConnectionIdleTime=28800000  
spring.data.mongodb.log.custom.maxConnectionLifeTime=28800000 
spring.data.mongodb.log.custom.maxWaitTime=60000

LogMongoDBConfig.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.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 = "logMongoTemplate", //
		basePackages = { //
				"org.ruoxue.spring_boot_168.sso.login_account_log.repository, " //
		})
@Configuration
@Slf4j
public class LogMongoDBConfig {

	@Value("${spring.data.mongodb.log.custom.uri}")
	private String uri;

	@Value("${spring.data.mongodb.log.custom.connectionsPerHost}")
	private int connectionsPerHost;

	@Value("${spring.data.mongodb.log.custom.minConnectionsPerHost}")
	private int minConnectionsPerHost;

	@Value("${spring.data.mongodb.log.custom.retryWrites}")
	private boolean retryWrites;

	@Value("${spring.data.mongodb.log.custom.connectTimeout}")
	private int connectTimeout;

	@Value("${spring.data.mongodb.log.custom.socketTimeout}")
	private int socketTimeout;

	@Value("${spring.data.mongodb.log.custom.maxConnectionIdleTime}")
	private int maxConnectionIdleTime;

	@Value("${spring.data.mongodb.log.custom.maxConnectionLifeTime}")
	private int maxConnectionLifeTime;

	@Value("${spring.data.mongodb.log.custom.maxWaitTime}")
	private int maxWaitTime;

	@Bean(name = "logMongoBuilder")
	public Builder logMongoBuilder() {
		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;
	}

	@Bean(name = "logMongoClientURI")
	public MongoClientURI logMongoClientURI(@Qualifier("logMongoBuilder") Builder builder) {
		MongoClientURI mongoClientURI = new MongoClientURI(this.uri, builder);
		return mongoClientURI;
	}

	@Bean(name = "logMongoClient")
	public MongoClient logMongoClient(@Qualifier("logMongoClientURI") MongoClientURI mongoClientURI) {
		MongoClient mongoClient = new MongoClient(mongoClientURI);
		return mongoClient;
	}

	@Bean(name = "logMongoDbFactory")
	public MongoDbFactory logMongoDbFactory(@Qualifier("logMongoClientURI") MongoClientURI mongoClientURI) {
		return new SimpleMongoDbFactory(mongoClientURI);
	}

	@Bean(name = "logMongoTemplate")
	public MongoTemplate logMongoTemplate(@Qualifier("logMongoDbFactory") 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;

	}
}

測試

LogMongoDBConfigTest.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 LogMongoDBConfigTest {

	@Autowired
	private LogMongoDBConfig config;

	@Test
	public void config() {
		assertNotNull(config);
	}
}

config

測試方法上點右鍵執行 Run As -> JUnit Test ,查看 console。

2022-06-06T23:46:37.549+0800 [main] INFO logMongoBuilder:72 - uri: mongodb://root:1111@127.0.0.1:27017/spring_boot_168_log?authSource=admin
2022-06-06T23:46:37.550+0800 [main] INFO logMongoBuilder:73 - connectionsPerHost: 100
2022-06-06T23:46:37.917+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-06T23:46:37.923+0800 [cluster-ClusterId{value='635fedddc313271f7c4e3bd1', description='null'}-127.0.0.1:27017] INFO connection#info:71 - Opened connection [connectionId{localValue:4}] to 127.0.0.1:27017
2022-06-06T23:46:37.924+0800 [cluster-ClusterId{value='635fedddc313271f7c4e3bd1', 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=303957}
2022-06-06T23:46:38.039+0800 [MaintenanceTimer-1-thread-1] INFO connection#info:71 - Opened connection [connectionId{localValue:1}] to 127.0.0.1:27017
2022-06-06T23:46:38.050+0800 [MaintenanceTimer-1-thread-1] INFO connection#info:71 - Opened connection [connectionId{localValue:5}] to 127.0.0.1:27017
2022-06-06T23:46:38.054+0800 [MaintenanceTimer-1-thread-1] INFO connection#info:71 - Opened connection [connectionId{localValue:6}] to 127.0.0.1:27017
2022-06-06T23:46:38.058+0800 [MaintenanceTimer-1-thread-1] INFO connection#info:71 - Opened connection [connectionId{localValue:7}] to 127.0.0.1:27017
2022-06-06T23:46:38.062+0800 [MaintenanceTimer-1-thread-1] INFO connection#info:71 - Opened connection [connectionId{localValue:8}] to 127.0.0.1:27017
2022-06-06T23:46:38.065+0800 [MaintenanceTimer-1-thread-1] INFO connection#info:71 - Opened connection [connectionId{localValue:9}] to 127.0.0.1:27017
2022-06-06T23:46:38.068+0800 [MaintenanceTimer-1-thread-1] INFO connection#info:71 - Opened connection [connectionId{localValue:10}] to 127.0.0.1:27017
2022-06-06T23:46:38.071+0800 [MaintenanceTimer-1-thread-1] INFO connection#info:71 - Opened connection [connectionId{localValue:11}] to 127.0.0.1:27017

心得分享

實現多資料庫的連線池,設定連線池最大與最小連線數限制,及取得連線逾時,閒置逾時等功能,讓資料庫連線更有效率,節省系統資源的耗用。

發佈留言