整合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:portprivate String address;//设置你的认证数据库,如果有的话private String authenticationDatabase;private MongoDbFactoryProperties mongoDbFactoryProperties;@Beanpublic 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-mongopassword: 123456address: 127.0.0.1:27017username: adminauthenticationDatabase: admin
......
配置类实现:实现自定义的MongoTemplate和MongoFactory的bean,并将其注册到容器中。这样springboot在使用mogodb时就会自动加载我们自定义的MongoTemplate和MongoFactory。
@Configuration
public class MongoDbConfigure {@AutowiredMongoDbFactoryProperties mongoDbFactoryProperties;/*** 自定义 mongoTemplate 实现多数据源配置*/@Beanpublic MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory, MongoMappingContext context){MappingMongoConverter mappingMongoConverter = mappingMongoConverter(mongoDbFactory, context);MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory, mappingMongoConverter);return mongoTemplate;}/*** 自定义mongo连接池* @param properties 私有配置* @return*/@Beanpublic 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);
}