about 6 years ago
當數據有新舊問題的時候,或是新舊移轉之類的需求,就必須同時存取新舊的表
在 SpringBoot Data Mongo 如何實現配置呢?
buildscript {
ext {
springBootVersion = '1.4.3.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
jar {
baseName = 'convert'
version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-actuator')
compile('org.springframework.boot:spring-boot-starter-data-mongodb')
compileOnly('org.projectlombok:lombok')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
這邊配置了兩個 MongoDB 的數據源,則必須手動配置載入,不能透過 Spring Boot Data Mongo
mongodb:
primary:
uri: mongodb://samzhu:123456@ds123456.mlab.com:59217/dbname
secondary:
uri: mongodb://samzhu:123456@ds123-a0.mlab.com:21971,ds456-a1.mlab.com:21971/dbname
讀入設定參數檔,其實只是要讀 uri 這個參數而已,所以透過原本 org.springframework.boot.autoconfigure.mongo.MongoProperties 來當載體
@Data
@ConfigurationProperties(prefix = "mongodb")
public class MultipleMongoProperties {
private MongoProperties primary = new MongoProperties();
private MongoProperties secondary = new MongoProperties();
}
配置主從資料庫的設定,透過 basePackages 區分主從資料庫對應物件,透過 mongoTemplateRef 聲明 bean
@Configuration
@EnableMongoRepositories(basePackages = "com.giish.convert.repositories.main", mongoTemplateRef = PrimaryMongoConfig.MONGO_TEMPLATE)
public class PrimaryMongoConfig {
public static final String MONGO_TEMPLATE = "primaryMongoTemplate";
}
@Configuration
@EnableMongoRepositories(basePackages = "com.giish.convert.repositories.secondary", mongoTemplateRef = SecondaryMongoConfig.MONGO_TEMPLATE)
public class SecondaryMongoConfig {
protected static final String MONGO_TEMPLATE = "secondaryMongoTemplate";
}
配置 MongoTemplate 跟 MongoDbFactory
import com.mongodb.MongoClientURI;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
/**
* Created by samchu on 2017/1/3.
*/
@Configuration
public class MultipleMongoConfig {
private MultipleMongoProperties mongoProperties;
// @SuppressWarnings 加這個注解讓IDE 不報: Could not autowire
@Autowired
public void setMongoProperties(@SuppressWarnings("SpringJavaAutowiringInspection") MultipleMongoProperties mongoProperties) {
this.mongoProperties = mongoProperties;
}
@Primary
@Bean(name = PrimaryMongoConfig.MONGO_TEMPLATE)
public MongoTemplate primaryMongoTemplate() throws Exception {
return new MongoTemplate(primaryFactory(this.mongoProperties.getPrimary()));
}
@Bean
@Qualifier(SecondaryMongoConfig.MONGO_TEMPLATE)
public MongoTemplate secondaryMongoTemplate() throws Exception {
return new MongoTemplate(secondaryFactory(this.mongoProperties.getSecondary()));
}
@Bean
@Primary
public MongoDbFactory primaryFactory(@SuppressWarnings("SpringJavaAutowiringInspection") MongoProperties mongoProperties) throws Exception {
// 這邊是使用另一種方式連接
// MongoCredential credential = MongoCredential.createCredential("username", "databasename", "password".toCharArray());
// ServerAddress serverAdress = new ServerAddress(mongo.getHost(), mongo.getPort());
// new SimpleMongoDbFactory(new MongoClient(serverAdress, Arrays.asList(credential)), mongo.getDatabase());
return new SimpleMongoDbFactory(new MongoClientURI(mongoProperties.getUri()));
}
@Bean
public MongoDbFactory secondaryFactory(@SuppressWarnings("SpringJavaAutowiringInspection") MongoProperties mongoProperties) throws Exception {
return new SimpleMongoDbFactory(new MongoClientURI(mongoProperties.getUri()));
}
}
啟動程式,前面說過必需自己配置 mongodb 連線,所以這邊我們必須停掉 org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration 的自動配置,以及載入 MultipleMongoProperties
@EnableConfigurationProperties(MultipleMongoProperties.class)
@SpringBootApplication(exclude = MongoAutoConfiguration.class)
public class GiishConvertApplication {
public static void main(String[] args) {
SpringApplication.run(GiishConvertApplication.class, args);
}
}
實際執行效果
@RequiredArgsConstructor
@Component
public class ApplicationLoader implements CommandLineRunner {
//@Autowired
@NonNull
private com.giish.convert.repositories.main.UserRep mainUserRep;
//@Autowired
@NonNull
private com.giish.convert.repositories.secondary.OldUserRep secondaryUserRep;
@Override
public void run(String... args) throws Exception {
// 取得主資料庫
System.out.println(mainUserRep.count());
// 取得從資料庫
System.out.println(secondaryUserRep.count());
}
}
這樣一來只要操作對應的數據物件, spring 就會透過對應的 MongoDbFactory 設定連到正確的 MongoDB 取資料了
參考資料
marcosbarbero/spring-boot-multi-mongo: Multiple mongo connector