SpringBoot 整合mongoDB并自定义连接池

1 篇文章 0 订阅

整合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);
}

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值