整合mongoDB的目的就是想用它给我们提供的mongoTemplate,它可以很容易的操作mongoDB数
整合mongoDB的目的就是想用它给我们提供的mongoTemplate,它可以很容易的操作mongoDB数据库。通过我们自定义的连接池和mongoTemplate,我们可以轻松的配置多个数据源,并在多个数据源之间切换
为了自定义连接池,我们在配置类中主要与MongoClientOptions、MongoCredential、MongoClient、MongoDbFactory打交道。最终的目的就是配置好一个MongoDbFactory的bean交由Spring管理。
首先是依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
先实现我们自定义的配置信息:additional-spring-configuration-metadata.json配置如下
{
"groups": [
{
"name": "zhong.data.mongodb.database",
"type": "java.lang.String",
"description": "mongodb的数据库名称",
"sourceType": "com.zhong.springdemo.mangodbdome.configure.MongoDbProperties"
},
{
"name": "zhong.data.mongodb.mongoDbFactoryProperties",
"type": "com.zhong.springdemo.mangodbdome.configure.MongoDbFactoryProperties",
"description": "线程池配置信息",
"sourceType": "com.zhong.springdemo.mangodbdome.configure.MongoDbProperties",
"sourceMethod": "getMongoDbFactory()"
}
],
"properties": [
{
"name": "zhong.data.mongodb.username",
"type": "java.lang.String",
"description": "mongodb的用户名",
"sourceType": "com.zhong.springdemo.mangodbdome.configure.MongoDbProperties",
"defaultValue": ""
},
{
"name": "zhong.data.mongodb.password",
"type": "java.lang.String",
"description": "mongodb的密码",
"sourceType": "com.zhong.springdemo.mangodbdome.configure.MongoDbProperties",
"defaultValue": "123456"
},
{
"name": "zhong.data.mongodb.address",
"type": "java.lang.String",
"description": "mongodb的用户名地址,多个以逗号可开",
"sourceType": "com.zhong.springdemo.mangodbdome.configure.MongoDbProperties",
"defaultValue": "127.0.0.1:27017"
},
{
"name": "zhong.data.mongodb.authenticationDatabase",
"type": "java.lang.String",
"description": "你的认证数据库,如果有",
"sourceType": "com.zhong.springdemo.mangodbdome.configure.MongoDbProperties",
"defaultValue": ""
},
{
"name": "zhong.data.mongodb.factory.clientName",
"type": "java.lang.String",
"description": "客户端标识",
"sourceType": "com.zhong.springdemo.mangodbdome.configure.MongoDbFactoryProperties",
"defaultValue": ""
},
{
"name": "zhong.data.mongodb.factory.connectionTimeoutMs",
"type": "java.lang.Integer",
"description": "tcp链接超时时间.",
"sourceType": "com.zhong.springdemo.mangodbdome.configure.MongoDbFactoryProperties",
"defaultValue": 30000
},
{
"name": "zhong.data.mongodb.factory.readTimeoutMs",
"type": "java.lang.Integer",
"description": "tcp读取超时时间.",
"sourceType": "com.zhong.springdemo.mangodbdome.configure.MongoDbFactoryProperties",
"defaultValue": 15000
},
{
"name": "zhong.data.mongodb.factory.poolMaxWaitTimeMs",
"type": "java.lang.Integer",
"description": "当连接池无可用连接时客户端阻塞等待的时长,单位毫秒",
"sourceType": "com.zhong.springdemo.mangodbdome.configure.MongoDbFactoryProperties",
"defaultValue": 30000
},
{
"name": "zhong.data.mongodb.factory.connectionMaxIdleTimeMs",
"type": "java.lang.Integer",
"description": "TCP连接闲置时间,单位毫秒.",
"sourceType": "com.zhong.springdemo.mangodbdome.configure.MongoDbFactoryProperties",
"defaultValue": 30000
},
{
"name": "zhong.data.mongodb.factory.",
"type": "java.lang.Integer",
"description": "es 连接失败重试最大时长.",
"sourceType": "com.zhong.springdemo.mangodbdome.configure.MongoDbFactoryProperties",
"defaultValue": 30000
},
{
"name": "zhong.data.mongodb.factory.connectionMaxLifeTimeMs",
"type": "java.lang.Integer",
"description": "TCP连接最多可以使用多久,单位毫秒",
"sourceType": "com.zhong.springdemo.mangodbdome.configure.MongoDbFactoryProperties",
"defaultValue": 120000
},
{
"name": "zhong.data.mongodb.factory.heartbeatFrequencyMs",
"type": "java.lang.Integer",
"description": "心跳检测发送频率,单位毫秒",
"sourceType": "com.zhong.springdemo.mangodbdome.configure.MongoDbFactoryProperties",
"defaultValue": 20000
},
{
"name": "zhong.data.mongodb.factory.minHeartbeatFrequencyMs",
"type": "java.lang.Integer",
"description": "最小的心跳检测发送频率,单位毫秒",
"sourceType": "com.zhong.springdemo.mangodbdome.configure.MongoDbFactoryProperties",
"defaultValue": 8000
},
{
"name": "zhong.data.mongodb.factory.heartbeatConnectionTimeoutMs",
"type": "java.lang.Integer",
"description": "心跳检测TCP连接超时,单位毫秒",
"sourceType": "com.zhong.springdemo.mangodbdome.configure.MongoDbFactoryProperties",
"defaultValue": 30000
},
{
"name": "zhong.data.mongodb.factory.heartbeatReadTimeoutMs",
"type": "java.lang.Integer",
"description": "心跳检测TCP连接读取超时,单位毫秒",
"sourceType": "com.zhong.springdemo.mangodbdome.configure.MongoDbFactoryProperties",
"defaultValue": 30000
},
{
"name": "zhong.data.mongodb.factory.connectionsPerHost",
"type": "java.lang.Integer",
"description": "每个host的TCP连接数",
"sourceType": "com.zhong.springdemo.mangodbdome.configure.MongoDbFactoryProperties",
"defaultValue": 30000
},
{
"name": "zhong.data.mongodb.factory.minConnectionsPerHost",
"type": "java.lang.Integer",
"description": "每个host的最小TCP连接数",
"sourceType": "com.zhong.springdemo.mangodbdome.configure.MongoDbFactoryProperties",
"defaultValue": 30000
},
{
"name": "zhong.data.mongodb.factory.threadsAllowedToBlockForConnectionMultiplier",
"type": "java.lang.Integer",
"description": "计算允许多少个线程阻塞等待可用TCP连接时的乘数",
"sourceType": "com.zhong.springdemo.mangodbdome.configure.MongoDbFactoryProperties",
"defaultValue": 30000
}
],
"hints": []
}
自定义属性配置类:
@ConfigurationProperties(prefix = "zhong.data.mongodb")
public class MongoDbProperties {
//数据库名称
private String database;
//用户名
private String username;
//密码
private String password;
//地址 host:port
private String address;
//设置你的认证数据库,如果有的话
private String authenticationDatabase;
private MongoDbFactoryProperties mongoDbFactoryProperties;
@Bean
public MongoDbFactoryProperties getMongoDbFactory2(@Autowired MongoDbFactoryProperties mongoDbFactoryProperties){
return this.mongoDbFactoryProperties = mongoDbFactoryProperties;
}
}
连接池信息:
@Component
@ConfigurationProperties(prefix = "zhong.data.mongodb.factory")
public class MongoDbFactoryProperties {
//连接池配置
//客户端的标识,用于定位请求来源等
private String clientName;
private String applicationName;
//TCP连接超时,毫秒
private Integer connectionTimeoutMs = 30000;
//TCP读取超时,毫秒
private Integer readTimeoutMs = 15000;
//当连接池无可用连接时客户端阻塞等待的时长,单位毫秒
private Integer poolMaxWaitTimeMs = 3000;
//TCP连接闲置时间,单位毫秒
private Integer connectionMaxIdleTimeMs = 60000;
//TCP连接最多可以使用多久,单位毫秒
private Integer connectionMaxLifeTimeMs = 120000;
//心跳检测发送频率,单位毫秒
private Integer heartbeatFrequencyMs = 20000;
//最小的心跳检测发送频率,单位毫秒
private Integer minHeartbeatFrequencyMs = 8000;
//心跳检测TCP连接超时,单位毫秒
private Integer heartbeatConnectionTimeoutMs = 10000;
//心跳检测TCP连接读取超时,单位毫秒
private Integer heartbeatReadTimeoutMs = 15000;
// 每个host的TCP连接数
private Integer connectionsPerHost = 20;
//每个host的最小TCP连接数
private Integer minConnectionsPerHost = 5;
//计算允许多少个线程阻塞等待可用TCP连接时的乘数,算法:threadsAllowedToBlockForConnectionMultiplier*connectionsPerHost,当前配置允许10*20个线程阻塞
private Integer threadsAllowedToBlockForConnectionMultiplier = 10;
/getter and setter
}
application.yaml配置:
zhong: #自定义的mongodb测试 data: mongodb: database: zhong-mongo password: 123456 address: 127.0.0.1:27017 username: admin authenticationDatabase: admin
......
配置类实现:实现自定义的MongoTemplate和MongoFactory的bean,并将其注册到容器中。这样springboot在使用mogodb时就会自动加载我们自定义的MongoTemplate和MongoFactory。
@Configuration
public class MongoDbConfigure {
@Autowired
MongoDbFactoryProperties mongoDbFactoryProperties;
/**
* 自定义 mongoTemplate 实现多数据源配置
*/
@Bean
public MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory, MongoMappingContext context){
MappingMongoConverter mappingMongoConverter = mappingMongoConverter(mongoDbFactory, context);
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory, mappingMongoConverter);
return mongoTemplate;
}
/**
* 自定义mongo连接池
* @param properties 私有配置
* @return
*/
@Bean
public MongoDbFactory mongoDbFactory(MongoDbProperties properties) {
//创建客户端参数
MongoClientOptions options = mongoClientOptions(properties);
//解析地址
List<ServerAddress> serverAddresses = new ArrayList<>();
for (String address : properties.getAddress().split(",")) {
String[] hostAndPort = address.split(":");
String host = hostAndPort[0];
Integer port = Integer.parseInt(hostAndPort[1]);
ServerAddress serverAddress = new ServerAddress(host, port);
serverAddresses.add(serverAddress);
}
//创建认证客户端
MongoCredential mongoCredential = MongoCredential.createScramSha1Credential(properties.getUsername(),
properties.getAuthenticationDatabase() != null ? properties.getAuthenticationDatabase() : properties.getDatabase(),
properties.getPassword().toCharArray());
MongoClient mongoClient = new MongoClient(serverAddresses.get(0), mongoCredential, options);
//集群模式
if (serverAddresses.size() > 1) {
mongoClient = new MongoClient(serverAddresses, mongoCredential, null);
}
/** 创建非认证客户端*/
//MongoClient mongoClient = new MongoClient(serverAddresses, mongoClientOptions);
return new SimpleMongoDbFactory(mongoClient, properties.getDatabase());
}
/**
* mongo客户端参数配置
* @return
*/
private MongoClientOptions mongoClientOptions(MongoDbProperties properties) {
MongoDbFactoryProperties factoryProperties = this.mongoDbFactoryProperties;
return MongoClientOptions.builder()
.connectTimeout(factoryProperties.getConnectionTimeoutMs())
.socketTimeout(factoryProperties.getReadTimeoutMs()).applicationName(factoryProperties.getApplicationName())
.heartbeatConnectTimeout(factoryProperties.getHeartbeatConnectionTimeoutMs())
.heartbeatSocketTimeout(factoryProperties.getHeartbeatReadTimeoutMs())
.heartbeatFrequency(factoryProperties.getHeartbeatFrequencyMs())
.minHeartbeatFrequency(factoryProperties.getMinHeartbeatFrequencyMs())
.maxConnectionIdleTime(factoryProperties.getConnectionMaxIdleTimeMs())
.maxConnectionLifeTime(factoryProperties.getConnectionMaxLifeTimeMs())
.maxWaitTime(factoryProperties.getPoolMaxWaitTimeMs())
.connectionsPerHost(factoryProperties.getConnectionsPerHost())
.threadsAllowedToBlockForConnectionMultiplier(
factoryProperties.getThreadsAllowedToBlockForConnectionMultiplier())
.minConnectionsPerHost(factoryProperties.getMinConnectionsPerHost()).build();
}
/**
* monogo 转换器
* @return
*/
private MappingMongoConverter mappingMongoConverter(MongoDbFactory mongoDbFactory, MongoMappingContext context) {
DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory);
MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);
//此处是去除插入数据库的 _class 字段
mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
return mappingConverter;
}
}
springboot提供两种mongodb的访问方式
第一种是直接:使用MongoTemplate
第二种是使用继承MongoRepository<T, ID>
@Repository
public interface UserInfoRepository extends MongoRepository<UserInfoEntity, String> {
List<UserInfoEntity> findByUserNameLike(String username);
List<UserInfoEntity> findByUserName(String username);
}