本文需要读者对Spring Boot整合Mongodb有基本了解
软件名称 | 软件版本 |
---|---|
Spring Boot | 2.5.3 |
Maven | 3.6.3 |
MongoDB | 4.2.5 |
在application.properties
配置文件中增加如下配置
spring.data.mongodb.uri: mongodb://localhost:27017/Teach
Spring Boot框架在启动后就可以使用@Autowired
方式使用MongoTemplate
对象
private @Autowired MongoTemplate mongoTemplate;
MongoTemplate
对象可以实现对MongoDB数据的CRUD操作
spring.data.mongodb
配置是Spring Boot框架自己能够识别的配置,所以可以为我们创建MongoTemplate
对象供我们使用,如果要实现多个MongoDB数据源的配置,就需要我们自己读取配置自己创建MongoTemplate对象。
比如,我们想配置2个MongoDB数据源,分别取名叫xxx1和xxx2,并定义好如下配置项
spring.data.mongodb.xxx1.uri: mongodb://localhost:27017/Teach1
spring.data.mongodb.xxx2.uri: mongodb://localhost:27017/Teach2
想要实现自定义多个数据源,就需要做到像Spring Boot框架那样构造一个MongoTemplate
对象,接下来我们跟踪源码学习如何自己手工创建MongoTemplate
进入MongoTemplate.java
源代码,查看构造函数
public MongoTemplate(MongoClient mongoClient, String databaseName)
public MongoTemplate(MongoDatabaseFactory mongoDbFactory)
public MongoTemplate(MongoDatabaseFactory mongoDbFactory, @Nullable MongoConverter mongoConverter)
一共有三个可用的构造函数,从构造函数可以看出,如果想构造一个MongoTemplate
对象,就需要先创建一个MongoClient
对象或者MongoDatabaseFactory
对象
在MongoTemplate.java
中可以看到SimpleMongoClientDatabaseFactory这个对象的创建,创建这个对象需要传入一个MongoClient对象,利用IDE工具查看SimpleMongoClientDatabaseFactory构造函数调用的地方
进入mongoDbFactory()
@Bean
public MongoDatabaseFactory mongoDbFactory() {
return new SimpleMongoClientDatabaseFactory(mongoClient(), getDatabaseName());
}
再跟踪进入mongoClient()
public MongoClient mongoClient() {
return createMongoClient(mongoClientSettings());
}
再跟踪进入createMongoClient()
protected MongoClient createMongoClient(MongoClientSettings settings) {
return MongoClients.create(settings, SpringDataMongoDB.driverInformation());
}
从这里可以看到,原来有一个工具类MongoClients
帮助创建MongoClient
对象,这个时候我们进一步查看这个工具类其它create
方法
其中有一个最简单的工具方法,String
类型的connectionString
参数,这个connectionString
其实就是连接MongoDB的URI
源码看到这里,我们可以知道,如果要创建
MongoTemplate
对象,无论是传MongoClient
还是MongoDatabaseFactory
对象,最终都是需要一个connectionString
,也就是uri配置,那我们接下来就可以读取配置并自己构造MongoTemplate
对象了。
上面这个配置项,Spring Boot框架是不认识的,所以需要我们自己去完成对配置的读取,代码参考如下
package com.etomy.teach.mongodb.properties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
@Configuration
public class MgoConfiguration2 {
@Bean
public MongoTemplate xxx1MongoTemplate(@Value("${spring.data.mongodb.xxx1.uri}") String xxx1Url) {
return new MongoTemplate(new SimpleMongoClientDatabaseFactory(xxx1Url));
}
@Bean
public MongoTemplate xxx2MongoTemplate(@Value("${spring.data.mongodb.xxx2.uri}") String xxx2Url) {
return new MongoTemplate(new SimpleMongoClientDatabaseFactory(xxx2Url));
}
}
上面这个类完成对xxx1和xxx2两个mongodb数据源配置的读取,并且构造两个MongoTemplate
Bean
MongoTemplate
有了,接下来写单元测试
package com.etomy.teach.mongodb.properties;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.test.context.TestPropertySource;
import com.etomy.teach.mongodb.SpringbootTestBase;
@TestPropertySource(properties = {
"spring.data.mongodb.xxx1.uri: mongodb://localhost:27017/Teach1",
"spring.data.mongodb.xxx2.uri: mongodb://localhost:27017/Teach2"
})
public class MgoConfiguration2Test extends SpringbootTestBase {
@Qualifier("xxx1MongoTemplate")
private @Autowired MongoTemplate xxx1MongoTemplate;
@Qualifier("xxx2MongoTemplate")
private @Autowired MongoTemplate xxx2MongoTemplate;
@Test
public void testMultiMongodb() {
xxx1MongoTemplate.insert(buildMgoMessage());
xxx2MongoTemplate.insert(buildMgoMessage());
}
}
运行单元测试后,从mongodb核对数据情况
直接上代码
public void removeClassField(MongoTemplate mongoTemplate) {
MongoConverter converter = mongoTemplate.getConverter();
if (converter.getTypeMapper().isTypeKey(TYPE_KEY)) {
((MappingMongoConverter) converter).setTypeMapper(new DefaultMongoTypeMapper(null));
}
}