SpringBoot 整合mongoDB并自定义连接池

整合mongoDB的目的就是想用它给我们提供的mongoTemplate,它可以很容易的操作mongoDB数

       整合mongoDB的目的就是想用它给我们提供的mongoTemplate,它可以很容易的操作mongoDB数据库。通过我们自定义的连接池和mongoTemplate,我们可以轻松的配置多个数据源,并在多个数据源之间切换

        为了自定义连接池,我们在配置类中主要与MongoClientOptions、MongoCredential、MongoClient、MongoDbFactory打交道。最终的目的就是配置好一个MongoDbFactory的bean交由Spring管理。

首先是依赖:


    org.springframework.boot
    spring-boot-starter-data-mongodb

      先实现我们自定义的配置信息: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 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

@Repository
public interface UserInfoRepository extends MongoRepository {
    List findByUserNameLike(String username);
    List findByUserName(String username);
}

你可能感兴趣的:(java,mongodb,mongodb,数据库,java)