服务器之家:专注于服务器技术及软件下载分享
分类导航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|数据库技术|

服务器之家 - 数据库 - MongoDB - SpringBoot 整合mongoDB并自定义连接池的示例代码

SpringBoot 整合mongoDB并自定义连接池的示例代码

2022-02-25 18:02上帝爱吃苹果 MongoDB

这篇文章主要介绍了SpringBoot 整合mongoDB并自定义连接池 ,整合mongoDB的目的就是想用它给我们提供的mongoTemplate,它可以很容易的操作mongoDB数据库,对整合过程及实例代码感兴趣的朋友跟随小编一起看看吧

得力于SpringBoot的特性,整合mongoDB是很容易的,我们整合mongoDB的目的就是想用它给我们提供的mongoTemplate,它可以很容易的操作mongoDB数据库。

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

Maven 依赖

?
1
2
3
4
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

配置文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
mongodb:
  database: bfa_mongo
  username: "xxx"
  password: "xxxxx"
  address: "host:port"
  authenticationDatabase: [设置你的认证数据库,如果有的话]
  # 连接池配置
  clientName: ${spring.application.name} # 客户端的标识,用于定位请求来源等
  connectionTimeoutMs: 10000     # TCP连接超时,毫秒
  readTimeoutMs: 15000       # TCP读取超时,毫秒
  poolMaxWaitTimeMs: 3000        #当连接池无可用连接时客户端阻塞等待的时长,单位毫秒
  connectionMaxIdleTimeMs: 60000   #TCP连接闲置时间,单位毫秒
  connectionMaxLifeTimeMs: 120000    #TCP连接最多可以使用多久,单位毫秒
  heartbeatFrequencyMs: 20000      #心跳检测发送频率,单位毫秒
  minHeartbeatFrequencyMs: 8000    #最小的心跳检测发送频率,单位毫秒
  heartbeatConnectionTimeoutMs: 10000  #心跳检测TCP连接超时,单位毫秒
  heartbeatReadTimeoutMs: 15000    #心跳检测TCP连接读取超时,单位毫秒
  connectionsPerHost: 20       # 每个host的TCP连接数
  minConnectionsPerHost: 5     #每个host的最小TCP连接数
  #计算允许多少个线程阻塞等待可用TCP连接时的乘数,算法:threadsAllowedToBlockForConnectionMultiplier*connectionsPerHost,当前配置允许10*20个线程阻塞
  threadsAllowedToBlockForConnectionMultiplier: 10

注意:其中的address参数可以配置为一个数组(代表集群模式)

?
1
2
3
address:
   - "host:port"
   - "host2:port2"

MongoConfig配置类

配置类中使用了lombok,如果你没有用lombok依赖和IDE插件,你要重写getter、Setter方法:
代码稍长,可以复制在IDEA中查看:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.validation.annotation.Validated;
 
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 
@Slf4j
@Configuration
@EnableConfigurationProperties(MongoConfig.MongoClientOptionProperties.class)
public class MongoConfig {
 
    /**
     * monogo 转换器
     * @return
     */
    @Bean
    public MappingMongoConverter mappingMongoConverter(MongoDbFactory factory,
                                                       MongoMappingContext context, BeanFactory beanFactory, MongoCustomConversions conversions) {
        DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
        MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);
        // remove _class field
//    mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
        mappingConverter.setCustomConversions(conversions);
        return mappingConverter;
    }
 
    /**
     * 自定义mongo连接池
     * @param properties
     * @return
     */
    @Bean
    public MongoDbFactory mongoDbFactory(MongoClientOptionProperties properties) {
        //创建客户端参数
        MongoClientOptions options = mongoClientOptions(properties);
 
        //创建客户端和Factory
        List<ServerAddress> serverAddresses = new ArrayList<>();
        for (String address : properties.getAddress()) {
            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, new ArrayList<>(Arrays.asList(mongoCredential)));
        }
        /** ps: 创建非认证客户端*/
        //MongoClient mongoClient = new MongoClient(serverAddresses, mongoClientOptions);
        return new SimpleMongoDbFactory(mongoClient, properties.getDatabase());
    }
 
    /**
     * mongo客户端参数配置
     * @return
     */
    public MongoClientOptions mongoClientOptions(MongoClientOptionProperties properties) {
        return MongoClientOptions.builder()
                .connectTimeout(properties.getConnectionTimeoutMs())
                .socketTimeout(properties.getReadTimeoutMs()).applicationName(properties.getClientName())
                .heartbeatConnectTimeout(properties.getHeartbeatConnectionTimeoutMs())
                .heartbeatSocketTimeout(properties.getHeartbeatReadTimeoutMs())
                .heartbeatFrequency(properties.getHeartbeatFrequencyMs())
                .minHeartbeatFrequency(properties.getMinHeartbeatFrequencyMs())
                .maxConnectionIdleTime(properties.getConnectionMaxIdleTimeMs())
                .maxConnectionLifeTime(properties.getConnectionMaxLifeTimeMs())
                .maxWaitTime(properties.getPoolMaxWaitTimeMs())
                .connectionsPerHost(properties.getConnectionsPerHost())
                .threadsAllowedToBlockForConnectionMultiplier(
                        properties.getThreadsAllowedToBlockForConnectionMultiplier())
                .minConnectionsPerHost(properties.getMinConnectionsPerHost()).build();
    }
 
    @Getter
    @Setter
    @Validated
    @ConfigurationProperties(prefix = "mongodb")
    public static class MongoClientOptionProperties {
 
        /** 基础连接参数 */
        private String database;
        private String username;
        private String password;
        @NotNull
        private List<String> address;
        private String authenticationDatabase;
 
        /** 客户端连接池参数 */
        @NotNull
        @Size(min = 1)
        private String clientName;
        /** socket连接超时时间 */
        @Min(value = 1)
        private int connectionTimeoutMs;
        /** socket读取超时时间 */
        @Min(value = 1)
        private int readTimeoutMs;
        /** 连接池获取链接等待时间 */
        @Min(value = 1)
        private int poolMaxWaitTimeMs;
        /** 连接闲置时间 */
        @Min(value = 1)
        private int connectionMaxIdleTimeMs;
        /** 连接最多可以使用多久 */
        @Min(value = 1)
        private int connectionMaxLifeTimeMs;
        /** 心跳检测发送频率 */
        @Min(value = 2000)
        private int heartbeatFrequencyMs;
 
        /** 最小的心跳检测发送频率 */
        @Min(value = 300)
        private int minHeartbeatFrequencyMs;
        /** 计算允许多少个线程阻塞等待时的乘数,算法:threadsAllowedToBlockForConnectionMultiplier*connectionsPerHost */
        @Min(value = 1)
        private int threadsAllowedToBlockForConnectionMultiplier;
        /** 心跳检测连接超时时间 */
        @Min(value = 200)
        private int heartbeatConnectionTimeoutMs;
        /** 心跳检测读取超时时间 */
        @Min(value = 200)
        private int heartbeatReadTimeoutMs;
 
        /** 每个host最大连接数 */
        @Min(value = 1)
        private int connectionsPerHost;
        /** 每个host的最小连接数 */
        @Min(value = 1)
        private int minConnectionsPerHost;
    }
}

MappingMongoConverter可以自定义mongo转换器,主要自定义存取mongo数据时的一些操作,例如 mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null)) 方法会将mongo数据中的_class字段去掉。

最后通过 new SimpleMongoDbFactory(mongoClient, properties.getDatabase())方法配置了一个MongoDbFactory交由Spring管理,Springboot会拿这个MongoDbFactory工厂bean来new一个MongoTemplate,在MongoDbFactoryDependentConfiguration类下可以看到SpringBoot帮你做得事:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
 * Configuration for Mongo-related beans that depend on a {@link MongoDbFactory}.
 *
 * @author Andy Wilkinson
 */
@Configuration
@ConditionalOnBean(MongoDbFactory.class)
class MongoDbFactoryDependentConfiguration {
 
    private final MongoProperties properties;
    MongoDbFactoryDependentConfiguration(MongoProperties properties) {
        this.properties = properties;
    }
    
    //SpringBoot创建MongoTemplate实例
    @Bean
    @ConditionalOnMissingBean
    public MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory, MongoConverter converter) {
        return new MongoTemplate(mongoDbFactory, converter);
    @ConditionalOnMissingBean(MongoConverter.class)
    public MappingMongoConverter mappingMongoConverter(MongoDbFactory factory, MongoMappingContext context,
            MongoCustomConversions conversions) {
        DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
        MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);
        mappingConverter.setCustomConversions(conversions);
        return mappingConverter;
    
    //...
}

SpringBoot利用我们配置好的MongoDbFactory在配置类中生成一个MongoTemplate,之后我们就可以在项目代码中直接@Autowired了。因为用于生成MongoTemplate的MongoDbFactory是我们自己在MongoConfig配置类中生成的,所以我们自定义的连接池参数也就生效了。

到此这篇关于SpringBoot 整合mongoDB并自定义连接池的文章就介绍到这了,更多相关SpringBoot自定义连接池内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://www.cnblogs.com/keeya/p/11992267.html

延伸 · 阅读

精彩推荐
  • MongoDBMongodb索引的优化

    Mongodb索引的优化

    MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。接下来通过本文给大家介绍Mongodb索引的优化,本文介绍的非常详细,具有参考借鉴价值,感...

    MRR3252020-05-05
  • MongoDB在mac系统下安装与配置mongoDB数据库

    在mac系统下安装与配置mongoDB数据库

    这篇文章主要介绍了在mac系统下安装与配置mongoDB数据库的操作步骤,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪...

    CXYhh1219312021-11-14
  • MongoDBMongoDB系列教程(五):mongo语法和mysql语法对比学习

    MongoDB系列教程(五):mongo语法和mysql语法对比学习

    这篇文章主要介绍了MongoDB系列教程(五):mongo语法和mysql语法对比学习,本文对熟悉Mysql数据库的同学来说帮助很大,用对比的方式可以快速学习到MongoDB的命...

    MongoDB教程网3252020-05-01
  • MongoDBMongoDB多条件模糊查询示例代码

    MongoDB多条件模糊查询示例代码

    这篇文章主要给大家介绍了关于MongoDB多条件模糊查询的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用MongoDB具有一定的参考学习价值...

    浅夏晴空5902020-05-25
  • MongoDBmongodb数据库基础知识之连表查询

    mongodb数据库基础知识之连表查询

    这篇文章主要给大家介绍了关于mongodb数据库基础知识之连表查询的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用mongodb具有一定的参...

    ZJW02155642020-05-22
  • MongoDBWindows下MongoDB配置用户权限实例

    Windows下MongoDB配置用户权限实例

    这篇文章主要介绍了Windows下MongoDB配置用户权限实例,本文实现需要输入用户名、密码才可以访问MongoDB数据库,需要的朋友可以参考下 ...

    MongoDB教程网3082020-04-29
  • MongoDBMongoDB的索引

    MongoDB的索引

    数据库中的索引就是用来提高查询操作的性能,但是会影响插入、更新和删除的效率,因为数据库不仅要执行这些操作,还要负责索引的更新 ...

    MongoDB教程网2532020-05-12
  • MongoDBMongoDB查询之高级操作详解(多条件查询、正则匹配查询等)

    MongoDB查询之高级操作详解(多条件查询、正则匹配查询等)

    这篇文章主要给大家介绍了关于MongoDB查询之高级操作(多条件查询、正则匹配查询等)的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者...

    w田翔3872020-12-19