mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
update Mongo4.x support
This commit is contained in:
parent
6236ce8788
commit
3f4079bced
@ -2,7 +2,7 @@
|
|||||||
# 🚀Changelog
|
# 🚀Changelog
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
# 5.7.23 (2022-03-14)
|
# 5.7.23 (2022-03-15)
|
||||||
|
|
||||||
### 🐣新特性
|
### 🐣新特性
|
||||||
* 【http 】 HttpRequest.form采用TableMap方式(issue#I4W427@Gitee)
|
* 【http 】 HttpRequest.form采用TableMap方式(issue#I4W427@Gitee)
|
||||||
@ -14,6 +14,7 @@
|
|||||||
* 【core 】 阿拉伯数字转换成中文对发票票面金额转换的扩展(pr#570@Gitee)
|
* 【core 】 阿拉伯数字转换成中文对发票票面金额转换的扩展(pr#570@Gitee)
|
||||||
* 【core 】 ArrayUtil增加replace方法(pr#570@Gitee)
|
* 【core 】 ArrayUtil增加replace方法(pr#570@Gitee)
|
||||||
* 【core 】 CsvReadConfig增加自定义标题行行号(issue#2180@Github)
|
* 【core 】 CsvReadConfig增加自定义标题行行号(issue#2180@Github)
|
||||||
|
* 【db 】 增加MongoDB4.x支持(pr#568@Gitee)
|
||||||
*
|
*
|
||||||
### 🐞Bug修复
|
### 🐞Bug修复
|
||||||
* 【core 】 修复ObjectUtil.hasNull传入null返回true的问题(pr#555@Gitee)
|
* 【core 】 修复ObjectUtil.hasNull传入null返回true的问题(pr#555@Gitee)
|
||||||
|
@ -20,10 +20,9 @@
|
|||||||
<!-- versions -->
|
<!-- versions -->
|
||||||
<c3p0.version>0.9.5.5</c3p0.version>
|
<c3p0.version>0.9.5.5</c3p0.version>
|
||||||
<dbcp2.version>2.9.0</dbcp2.version>
|
<dbcp2.version>2.9.0</dbcp2.version>
|
||||||
<tomcat-jdbc.version>10.0.14</tomcat-jdbc.version>
|
<tomcat-jdbc.version>10.0.16</tomcat-jdbc.version>
|
||||||
<druid.version>1.2.8</druid.version>
|
<druid.version>1.2.8</druid.version>
|
||||||
<hikariCP.version>2.4.13</hikariCP.version>
|
<hikariCP.version>2.4.13</hikariCP.version>
|
||||||
<mongo.version>3.12.10</mongo.version>
|
|
||||||
<mongo4.version>4.5.0</mongo4.version>
|
<mongo4.version>4.5.0</mongo4.version>
|
||||||
<sqlite.version>3.36.0.3</sqlite.version>
|
<sqlite.version>3.36.0.3</sqlite.version>
|
||||||
<!-- 此处固定2.5.x,支持到JDK8 -->
|
<!-- 此处固定2.5.x,支持到JDK8 -->
|
||||||
@ -97,13 +96,6 @@
|
|||||||
<version>${dbcp2.version}</version>
|
<version>${dbcp2.version}</version>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- MongoDB Java客户端 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.mongodb</groupId>
|
|
||||||
<artifactId>mongo-java-driver</artifactId>
|
|
||||||
<version>${mongo.version}</version>
|
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mongodb</groupId>
|
<groupId>org.mongodb</groupId>
|
||||||
<artifactId>mongodb-driver-sync</artifactId>
|
<artifactId>mongodb-driver-sync</artifactId>
|
||||||
|
@ -6,29 +6,35 @@ import cn.hutool.core.util.StrUtil;
|
|||||||
import cn.hutool.db.DbRuntimeException;
|
import cn.hutool.db.DbRuntimeException;
|
||||||
import cn.hutool.log.Log;
|
import cn.hutool.log.Log;
|
||||||
import cn.hutool.setting.Setting;
|
import cn.hutool.setting.Setting;
|
||||||
import com.mongodb.MongoClient;
|
import com.mongodb.MongoClientSettings;
|
||||||
import com.mongodb.MongoClientOptions;
|
|
||||||
import com.mongodb.MongoClientOptions.Builder;
|
|
||||||
import com.mongodb.MongoCredential;
|
import com.mongodb.MongoCredential;
|
||||||
import com.mongodb.ServerAddress;
|
import com.mongodb.ServerAddress;
|
||||||
|
import com.mongodb.client.MongoClient;
|
||||||
|
import com.mongodb.client.MongoClients;
|
||||||
import com.mongodb.client.MongoCollection;
|
import com.mongodb.client.MongoCollection;
|
||||||
import com.mongodb.client.MongoDatabase;
|
import com.mongodb.client.MongoDatabase;
|
||||||
|
import com.mongodb.connection.ConnectionPoolSettings;
|
||||||
|
import com.mongodb.connection.SocketSettings;
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MongoDB工具类
|
* MongoDB4工具类
|
||||||
*
|
|
||||||
* @author xiaoleilu
|
|
||||||
*
|
*
|
||||||
|
* @author VampireAchao
|
||||||
*/
|
*/
|
||||||
public class MongoDS implements Closeable {
|
public class MongoDS implements Closeable {
|
||||||
|
|
||||||
private final static Log log = Log.get();
|
private final static Log log = Log.get();
|
||||||
|
|
||||||
/** 默认配置文件 */
|
/**
|
||||||
|
* 默认配置文件
|
||||||
|
*/
|
||||||
public final static String MONGO_CONFIG_PATH = "config/mongo.setting";
|
public final static String MONGO_CONFIG_PATH = "config/mongo.setting";
|
||||||
|
|
||||||
// MongoDB配置文件
|
// MongoDB配置文件
|
||||||
@ -41,6 +47,7 @@ public class MongoDS implements Closeable {
|
|||||||
private MongoClient mongo;
|
private MongoClient mongo;
|
||||||
|
|
||||||
// --------------------------------------------------------------------------- Constructor start
|
// --------------------------------------------------------------------------- Constructor start
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造MongoDB数据源<br>
|
* 构造MongoDB数据源<br>
|
||||||
* 调用者必须持有MongoDS实例,否则会被垃圾回收导致写入失败!
|
* 调用者必须持有MongoDS实例,否则会被垃圾回收导致写入失败!
|
||||||
@ -58,8 +65,8 @@ public class MongoDS implements Closeable {
|
|||||||
* 调用者必须持有MongoDS实例,否则会被垃圾回收导致写入失败!
|
* 调用者必须持有MongoDS实例,否则会被垃圾回收导致写入失败!
|
||||||
*
|
*
|
||||||
* @param mongoSetting MongoDB的配置文件,如果是null则读取默认配置文件或者使用MongoDB默认客户端配置
|
* @param mongoSetting MongoDB的配置文件,如果是null则读取默认配置文件或者使用MongoDB默认客户端配置
|
||||||
* @param host 主机(域名或者IP)
|
* @param host 主机(域名或者IP)
|
||||||
* @param port 端口
|
* @param port 端口
|
||||||
*/
|
*/
|
||||||
public MongoDS(Setting mongoSetting, String host, int port) {
|
public MongoDS(Setting mongoSetting, String host, int port) {
|
||||||
this.setting = mongoSetting;
|
this.setting = mongoSetting;
|
||||||
@ -86,7 +93,7 @@ public class MongoDS implements Closeable {
|
|||||||
* 官方文档: http://docs.mongodb.org/manual/administration/replica-sets/
|
* 官方文档: http://docs.mongodb.org/manual/administration/replica-sets/
|
||||||
*
|
*
|
||||||
* @param mongoSetting MongoDB的配置文件,必须有
|
* @param mongoSetting MongoDB的配置文件,必须有
|
||||||
* @param groups 分组列表,当为null或空时使用无分组配置,一个分组使用单一模式,否则使用副本集模式
|
* @param groups 分组列表,当为null或空时使用无分组配置,一个分组使用单一模式,否则使用副本集模式
|
||||||
*/
|
*/
|
||||||
public MongoDS(Setting mongoSetting, String... groups) {
|
public MongoDS(Setting mongoSetting, String... groups) {
|
||||||
if (mongoSetting == null) {
|
if (mongoSetting == null) {
|
||||||
@ -146,11 +153,13 @@ public class MongoDS implements Closeable {
|
|||||||
|
|
||||||
final MongoCredential credentail = createCredentail(group);
|
final MongoCredential credentail = createCredentail(group);
|
||||||
try {
|
try {
|
||||||
if (null == credentail) {
|
MongoClientSettings.Builder clusterSettingsBuilder = MongoClientSettings.builder()
|
||||||
mongo = new MongoClient(serverAddress, buildMongoClientOptions(group));
|
.applyToClusterSettings(b -> b.hosts(Collections.singletonList(serverAddress)));
|
||||||
} else {
|
buildMongoClientSettings(clusterSettingsBuilder, group);
|
||||||
mongo = new MongoClient(serverAddress, credentail, buildMongoClientOptions(group));
|
if (null != credentail) {
|
||||||
|
clusterSettingsBuilder.credential(credentail);
|
||||||
}
|
}
|
||||||
|
mongo = MongoClients.create(clusterSettingsBuilder.build());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new DbRuntimeException(StrUtil.format("Init MongoDB pool with connection to [{}] error!", serverAddress), e);
|
throw new DbRuntimeException(StrUtil.format("Init MongoDB pool with connection to [{}] error!", serverAddress), e);
|
||||||
}
|
}
|
||||||
@ -192,11 +201,13 @@ public class MongoDS implements Closeable {
|
|||||||
|
|
||||||
final MongoCredential credentail = createCredentail(StrUtil.EMPTY);
|
final MongoCredential credentail = createCredentail(StrUtil.EMPTY);
|
||||||
try {
|
try {
|
||||||
if (null == credentail) {
|
MongoClientSettings.Builder clusterSettingsBuilder = MongoClientSettings.builder()
|
||||||
mongo = new MongoClient(addrList, buildMongoClientOptions(StrUtil.EMPTY));
|
.applyToClusterSettings(b -> b.hosts(addrList));
|
||||||
} else {
|
buildMongoClientSettings(clusterSettingsBuilder, StrUtil.EMPTY);
|
||||||
mongo = new MongoClient(addrList, credentail, buildMongoClientOptions(StrUtil.EMPTY));
|
if (null != credentail) {
|
||||||
|
clusterSettingsBuilder.credential(credentail);
|
||||||
}
|
}
|
||||||
|
mongo = MongoClients.create(clusterSettingsBuilder.build());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e, "Init MongoDB connection error!");
|
log.error(e, "Init MongoDB connection error!");
|
||||||
return;
|
return;
|
||||||
@ -234,7 +245,7 @@ public class MongoDS implements Closeable {
|
|||||||
/**
|
/**
|
||||||
* 获得MongoDB中指定集合对象
|
* 获得MongoDB中指定集合对象
|
||||||
*
|
*
|
||||||
* @param dbName 库名
|
* @param dbName 库名
|
||||||
* @param collectionName 集合名
|
* @param collectionName 集合名
|
||||||
* @return DBCollection
|
* @return DBCollection
|
||||||
*/
|
*/
|
||||||
@ -248,6 +259,7 @@ public class MongoDS implements Closeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------- Private method start
|
// --------------------------------------------------------------------------- Private method start
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建ServerAddress对象,会读取配置文件中的相关信息
|
* 创建ServerAddress对象,会读取配置文件中的相关信息
|
||||||
*
|
*
|
||||||
@ -291,7 +303,7 @@ public class MongoDS implements Closeable {
|
|||||||
*/
|
*/
|
||||||
private MongoCredential createCredentail(String group) {
|
private MongoCredential createCredentail(String group) {
|
||||||
final Setting setting = this.setting;
|
final Setting setting = this.setting;
|
||||||
if(null == setting) {
|
if (null == setting) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final String user = setting.getStr("user", group, setting.getStr("user"));
|
final String user = setting.getStr("user", group, setting.getStr("user"));
|
||||||
@ -316,23 +328,13 @@ public class MongoDS implements Closeable {
|
|||||||
return MongoCredential.createCredential(userName, database, password.toCharArray());
|
return MongoCredential.createCredential(userName, database, password.toCharArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 构件MongoDB连接选项<br>
|
|
||||||
*
|
|
||||||
* @param group 分组,当分组对应的选项不存在时会读取根选项,如果也不存在使用默认值
|
|
||||||
* @return MongoClientOptions
|
|
||||||
*/
|
|
||||||
private MongoClientOptions buildMongoClientOptions(String group) {
|
|
||||||
return buildMongoClientOptions(MongoClientOptions.builder(), group).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构件MongoDB连接选项<br>
|
* 构件MongoDB连接选项<br>
|
||||||
*
|
*
|
||||||
* @param group 分组,当分组对应的选项不存在时会读取根选项,如果也不存在使用默认值
|
* @param group 分组,当分组对应的选项不存在时会读取根选项,如果也不存在使用默认值
|
||||||
* @return Builder
|
* @return Builder
|
||||||
*/
|
*/
|
||||||
private Builder buildMongoClientOptions(Builder builder, String group) {
|
private MongoClientSettings.Builder buildMongoClientSettings(MongoClientSettings.Builder builder, String group) {
|
||||||
if (setting == null) {
|
if (setting == null) {
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
@ -348,8 +350,9 @@ public class MongoDS implements Closeable {
|
|||||||
if (StrUtil.isBlank(group) == false && connectionsPerHost == null) {
|
if (StrUtil.isBlank(group) == false && connectionsPerHost == null) {
|
||||||
connectionsPerHost = setting.getInt("connectionsPerHost");
|
connectionsPerHost = setting.getInt("connectionsPerHost");
|
||||||
}
|
}
|
||||||
|
ConnectionPoolSettings.Builder connectionPoolSettingsBuilder = ConnectionPoolSettings.builder();
|
||||||
if (connectionsPerHost != null) {
|
if (connectionsPerHost != null) {
|
||||||
builder.connectionsPerHost(connectionsPerHost);
|
connectionPoolSettingsBuilder.maxSize(connectionsPerHost);
|
||||||
log.debug("MongoDB connectionsPerHost: {}", connectionsPerHost);
|
log.debug("MongoDB connectionsPerHost: {}", connectionsPerHost);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,9 +362,10 @@ public class MongoDS implements Closeable {
|
|||||||
setting.getInt("connectTimeout");
|
setting.getInt("connectTimeout");
|
||||||
}
|
}
|
||||||
if (connectTimeout != null) {
|
if (connectTimeout != null) {
|
||||||
builder.connectTimeout(connectTimeout);
|
connectionPoolSettingsBuilder.maxWaitTime(connectTimeout, TimeUnit.MILLISECONDS);
|
||||||
log.debug("MongoDB connectTimeout: {}", connectTimeout);
|
log.debug("MongoDB connectTimeout: {}", connectTimeout);
|
||||||
}
|
}
|
||||||
|
builder.applyToConnectionPoolSettings(b -> b.applySettings(connectionPoolSettingsBuilder.build()));
|
||||||
|
|
||||||
// 套接字超时时间;该值会被传递给Socket.setSoTimeout(int)。默以为0(无穷) --int
|
// 套接字超时时间;该值会被传递给Socket.setSoTimeout(int)。默以为0(无穷) --int
|
||||||
Integer socketTimeout = setting.getInt(group + "socketTimeout");
|
Integer socketTimeout = setting.getInt(group + "socketTimeout");
|
||||||
@ -369,7 +373,8 @@ public class MongoDS implements Closeable {
|
|||||||
setting.getInt("socketTimeout");
|
setting.getInt("socketTimeout");
|
||||||
}
|
}
|
||||||
if (socketTimeout != null) {
|
if (socketTimeout != null) {
|
||||||
builder.socketTimeout(socketTimeout);
|
SocketSettings socketSettings = SocketSettings.builder().connectTimeout(socketTimeout, TimeUnit.MILLISECONDS).build();
|
||||||
|
builder.applyToSocketSettings(b -> b.applySettings(socketSettings));
|
||||||
log.debug("MongoDB socketTimeout: {}", socketTimeout);
|
log.debug("MongoDB socketTimeout: {}", socketTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,4 +393,5 @@ public class MongoDS implements Closeable {
|
|||||||
return this.setting;
|
return this.setting;
|
||||||
}
|
}
|
||||||
// --------------------------------------------------------------------------- Private method end
|
// --------------------------------------------------------------------------- Private method end
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,404 +0,0 @@
|
|||||||
package cn.hutool.db.nosql.mongo;
|
|
||||||
|
|
||||||
import cn.hutool.core.exceptions.NotInitedException;
|
|
||||||
import cn.hutool.core.net.NetUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.hutool.db.DbRuntimeException;
|
|
||||||
import cn.hutool.log.Log;
|
|
||||||
import cn.hutool.setting.Setting;
|
|
||||||
import com.mongodb.MongoClientSettings;
|
|
||||||
import com.mongodb.MongoCredential;
|
|
||||||
import com.mongodb.MongoDriverInformation;
|
|
||||||
import com.mongodb.ServerAddress;
|
|
||||||
import com.mongodb.client.MongoClient;
|
|
||||||
import com.mongodb.client.MongoCollection;
|
|
||||||
import com.mongodb.client.MongoDatabase;
|
|
||||||
import com.mongodb.client.internal.MongoClientImpl;
|
|
||||||
import com.mongodb.connection.ConnectionPoolSettings;
|
|
||||||
import com.mongodb.connection.SocketSettings;
|
|
||||||
import org.bson.Document;
|
|
||||||
|
|
||||||
import java.io.Closeable;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MongoDB4工具类
|
|
||||||
*
|
|
||||||
* @author VampireAchao
|
|
||||||
*/
|
|
||||||
public class MongoDS4 implements Closeable {
|
|
||||||
|
|
||||||
private final static Log log = Log.get();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 默认配置文件
|
|
||||||
*/
|
|
||||||
public final static String MONGO_CONFIG_PATH = "config/mongo.setting";
|
|
||||||
|
|
||||||
// MongoDB配置文件
|
|
||||||
private Setting setting;
|
|
||||||
// MongoDB实例连接列表
|
|
||||||
private String[] groups;
|
|
||||||
// MongoDB单点连接信息
|
|
||||||
private ServerAddress serverAddress;
|
|
||||||
// MongoDB客户端对象
|
|
||||||
private MongoClient mongo;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------- Constructor start
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造MongoDB数据源<br>
|
|
||||||
* 调用者必须持有MongoDS实例,否则会被垃圾回收导致写入失败!
|
|
||||||
*
|
|
||||||
* @param host 主机(域名或者IP)
|
|
||||||
* @param port 端口
|
|
||||||
*/
|
|
||||||
public MongoDS4(String host, int port) {
|
|
||||||
this.serverAddress = createServerAddress(host, port);
|
|
||||||
initSingle();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造MongoDB数据源<br>
|
|
||||||
* 调用者必须持有MongoDS实例,否则会被垃圾回收导致写入失败!
|
|
||||||
*
|
|
||||||
* @param mongoSetting MongoDB的配置文件,如果是null则读取默认配置文件或者使用MongoDB默认客户端配置
|
|
||||||
* @param host 主机(域名或者IP)
|
|
||||||
* @param port 端口
|
|
||||||
*/
|
|
||||||
public MongoDS4(Setting mongoSetting, String host, int port) {
|
|
||||||
this.setting = mongoSetting;
|
|
||||||
this.serverAddress = createServerAddress(host, port);
|
|
||||||
initSingle();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造MongoDB数据源<br>
|
|
||||||
* 当提供多个数据源时,这些数据源将为一个副本集或者多个mongos<br>
|
|
||||||
* 调用者必须持有MongoDS实例,否则会被垃圾回收导致写入失败! 官方文档: http://docs.mongodb.org/manual/administration/replica-sets/
|
|
||||||
*
|
|
||||||
* @param groups 分组列表,当为null或空时使用无分组配置,一个分组使用单一模式,否则使用副本集模式
|
|
||||||
*/
|
|
||||||
public MongoDS4(String... groups) {
|
|
||||||
this.groups = groups;
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造MongoDB数据源<br>
|
|
||||||
* 当提供多个数据源时,这些数据源将为一个副本集或者mongos<br>
|
|
||||||
* 调用者必须持有MongoDS实例,否则会被垃圾回收导致写入失败!<br>
|
|
||||||
* 官方文档: http://docs.mongodb.org/manual/administration/replica-sets/
|
|
||||||
*
|
|
||||||
* @param mongoSetting MongoDB的配置文件,必须有
|
|
||||||
* @param groups 分组列表,当为null或空时使用无分组配置,一个分组使用单一模式,否则使用副本集模式
|
|
||||||
*/
|
|
||||||
public MongoDS4(Setting mongoSetting, String... groups) {
|
|
||||||
if (mongoSetting == null) {
|
|
||||||
throw new DbRuntimeException("Mongo setting is null!");
|
|
||||||
}
|
|
||||||
this.setting = mongoSetting;
|
|
||||||
this.groups = groups;
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
// --------------------------------------------------------------------------- Constructor end
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化,当给定分组数大于一个时使用
|
|
||||||
*/
|
|
||||||
public void init() {
|
|
||||||
if (groups != null && groups.length > 1) {
|
|
||||||
initCloud();
|
|
||||||
} else {
|
|
||||||
initSingle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化<br>
|
|
||||||
* 设定文件中的host和端口有三种形式:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* host = host:port
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* host = host
|
|
||||||
* port = port
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* host = host
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
synchronized public void initSingle() {
|
|
||||||
if (setting == null) {
|
|
||||||
try {
|
|
||||||
setting = new Setting(MONGO_CONFIG_PATH, true);
|
|
||||||
} catch (Exception e) {
|
|
||||||
// 在single模式下,可以没有配置文件。
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String group = StrUtil.EMPTY;
|
|
||||||
if (null == this.serverAddress) {
|
|
||||||
//存在唯一分组
|
|
||||||
if (groups != null && groups.length == 1) {
|
|
||||||
group = groups[0];
|
|
||||||
}
|
|
||||||
serverAddress = createServerAddress(group);
|
|
||||||
}
|
|
||||||
|
|
||||||
final MongoCredential credentail = createCredentail(group);
|
|
||||||
try {
|
|
||||||
MongoClientSettings.Builder clusterSettingsBuilder = MongoClientSettings.builder().applyToClusterSettings(b -> b.hosts(Collections.singletonList(serverAddress)));
|
|
||||||
if (null != credentail) {
|
|
||||||
clusterSettingsBuilder.credential(credentail);
|
|
||||||
}
|
|
||||||
mongo = new MongoClientImpl(clusterSettingsBuilder.build(), MongoDriverInformation.builder().build());
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new DbRuntimeException(StrUtil.format("Init MongoDB pool with connection to [{}] error!", serverAddress), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info("Init MongoDB pool with connection to [{}]", serverAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化集群<br>
|
|
||||||
* 集群的其它客户端设定参数使用全局设定<br>
|
|
||||||
* 集群中每一个实例成员用一个group表示,例如:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* user = test1
|
|
||||||
* pass = 123456
|
|
||||||
* database = test
|
|
||||||
* [db0]
|
|
||||||
* host = 192.168.1.1:27117
|
|
||||||
* [db1]
|
|
||||||
* host = 192.168.1.1:27118
|
|
||||||
* [db2]
|
|
||||||
* host = 192.168.1.1:27119
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
synchronized public void initCloud() {
|
|
||||||
if (groups == null || groups.length == 0) {
|
|
||||||
throw new DbRuntimeException("Please give replication set groups!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (setting == null) {
|
|
||||||
// 若未指定配置文件,则使用默认配置文件
|
|
||||||
setting = new Setting(MONGO_CONFIG_PATH, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<ServerAddress> addrList = new ArrayList<>();
|
|
||||||
for (String group : groups) {
|
|
||||||
addrList.add(createServerAddress(group));
|
|
||||||
}
|
|
||||||
|
|
||||||
final MongoCredential credentail = createCredentail(StrUtil.EMPTY);
|
|
||||||
try {
|
|
||||||
MongoClientSettings.Builder clusterSettingsBuilder = MongoClientSettings.builder().applyToClusterSettings(b -> b.hosts(addrList));
|
|
||||||
if (null != credentail) {
|
|
||||||
clusterSettingsBuilder.credential(credentail);
|
|
||||||
}
|
|
||||||
mongo = new MongoClientImpl(clusterSettingsBuilder.build(), MongoDriverInformation.builder().build());
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error(e, "Init MongoDB connection error!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info("Init MongoDB cloud Set pool with connection to {}", addrList);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定MongoDB配置文件
|
|
||||||
*
|
|
||||||
* @param setting 配置文件
|
|
||||||
*/
|
|
||||||
public void setSetting(Setting setting) {
|
|
||||||
this.setting = setting;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return 获得MongoDB客户端对象
|
|
||||||
*/
|
|
||||||
public MongoClient getMongo() {
|
|
||||||
return mongo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得DB
|
|
||||||
*
|
|
||||||
* @param dbName DB
|
|
||||||
* @return DB
|
|
||||||
*/
|
|
||||||
public MongoDatabase getDb(String dbName) {
|
|
||||||
return mongo.getDatabase(dbName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得MongoDB中指定集合对象
|
|
||||||
*
|
|
||||||
* @param dbName 库名
|
|
||||||
* @param collectionName 集合名
|
|
||||||
* @return DBCollection
|
|
||||||
*/
|
|
||||||
public MongoCollection<Document> getCollection(String dbName, String collectionName) {
|
|
||||||
return getDb(dbName).getCollection(collectionName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
mongo.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------- Private method start
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建ServerAddress对象,会读取配置文件中的相关信息
|
|
||||||
*
|
|
||||||
* @param group 分组,如果为{@code null}或者""默认为无分组
|
|
||||||
* @return ServerAddress
|
|
||||||
*/
|
|
||||||
private ServerAddress createServerAddress(String group) {
|
|
||||||
final Setting setting = checkSetting();
|
|
||||||
|
|
||||||
if (group == null) {
|
|
||||||
group = StrUtil.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String tmpHost = setting.getByGroup("host", group);
|
|
||||||
if (StrUtil.isBlank(tmpHost)) {
|
|
||||||
throw new NotInitedException("Host name is empy of group: {}", group);
|
|
||||||
}
|
|
||||||
|
|
||||||
final int defaultPort = setting.getInt("port", group, 27017);
|
|
||||||
return new ServerAddress(NetUtil.buildInetSocketAddress(tmpHost, defaultPort));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建ServerAddress对象
|
|
||||||
*
|
|
||||||
* @param host 主机域名或者IP(如果为空默认127.0.0.1)
|
|
||||||
* @param port 端口(如果为空默认为)
|
|
||||||
* @return ServerAddress
|
|
||||||
*/
|
|
||||||
private ServerAddress createServerAddress(String host, int port) {
|
|
||||||
return new ServerAddress(host, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建{@link MongoCredential},用于服务端验证<br>
|
|
||||||
* 此方法会首先读取指定分组下的属性,用户没有定义则读取空分组下的属性
|
|
||||||
*
|
|
||||||
* @param group 分组
|
|
||||||
* @return {@link MongoCredential},如果用户未指定用户名密码返回null
|
|
||||||
* @since 4.1.20
|
|
||||||
*/
|
|
||||||
private MongoCredential createCredentail(String group) {
|
|
||||||
final Setting setting = this.setting;
|
|
||||||
if (null == setting) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
final String user = setting.getStr("user", group, setting.getStr("user"));
|
|
||||||
final String pass = setting.getStr("pass", group, setting.getStr("pass"));
|
|
||||||
final String database = setting.getStr("database", group, setting.getStr("database"));
|
|
||||||
return createCredentail(user, database, pass);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建{@link MongoCredential},用于服务端验证
|
|
||||||
*
|
|
||||||
* @param userName 用户名
|
|
||||||
* @param database 数据库名
|
|
||||||
* @param password 密码
|
|
||||||
* @return {@link MongoCredential}
|
|
||||||
* @since 4.1.20
|
|
||||||
*/
|
|
||||||
private MongoCredential createCredentail(String userName, String database, String password) {
|
|
||||||
if (StrUtil.hasEmpty(userName, database, database)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return MongoCredential.createCredential(userName, database, password.toCharArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构件MongoDB连接选项<br>
|
|
||||||
*
|
|
||||||
* @param group 分组,当分组对应的选项不存在时会读取根选项,如果也不存在使用默认值
|
|
||||||
* @return MongoClientOptions
|
|
||||||
*/
|
|
||||||
private MongoClientSettings buildMongoClientOptions(String group) {
|
|
||||||
return buildMongoClientOptions(MongoClientSettings.builder(), group).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构件MongoDB连接选项<br>
|
|
||||||
*
|
|
||||||
* @param group 分组,当分组对应的选项不存在时会读取根选项,如果也不存在使用默认值
|
|
||||||
* @return Builder
|
|
||||||
*/
|
|
||||||
private MongoClientSettings.Builder buildMongoClientOptions(MongoClientSettings.Builder builder, String group) {
|
|
||||||
if (setting == null) {
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StrUtil.isEmpty(group)) {
|
|
||||||
group = StrUtil.EMPTY;
|
|
||||||
} else {
|
|
||||||
group = group + StrUtil.DOT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 每个主机答应的连接数(每个主机的连接池大小),当连接池被用光时,会被阻塞住
|
|
||||||
Integer connectionsPerHost = setting.getInt(group + "connectionsPerHost");
|
|
||||||
if (StrUtil.isBlank(group) == false && connectionsPerHost == null) {
|
|
||||||
connectionsPerHost = setting.getInt("connectionsPerHost");
|
|
||||||
}
|
|
||||||
ConnectionPoolSettings.Builder connectionPoolSettingsBuilder = ConnectionPoolSettings.builder();
|
|
||||||
if (connectionsPerHost != null) {
|
|
||||||
connectionPoolSettingsBuilder.maxSize(connectionsPerHost);
|
|
||||||
log.debug("MongoDB connectionsPerHost: {}", connectionsPerHost);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 被阻塞线程从连接池获取连接的最长等待时间(ms) --int
|
|
||||||
Integer connectTimeout = setting.getInt(group + "connectTimeout");
|
|
||||||
if (StrUtil.isBlank(group) == false && connectTimeout == null) {
|
|
||||||
setting.getInt("connectTimeout");
|
|
||||||
}
|
|
||||||
if (connectTimeout != null) {
|
|
||||||
connectionPoolSettingsBuilder.maxWaitTime(connectTimeout, TimeUnit.MILLISECONDS);
|
|
||||||
log.debug("MongoDB connectTimeout: {}", connectTimeout);
|
|
||||||
}
|
|
||||||
builder.applyToConnectionPoolSettings(b -> b.applySettings(connectionPoolSettingsBuilder.build()));
|
|
||||||
|
|
||||||
// 套接字超时时间;该值会被传递给Socket.setSoTimeout(int)。默以为0(无穷) --int
|
|
||||||
Integer socketTimeout = setting.getInt(group + "socketTimeout");
|
|
||||||
if (StrUtil.isBlank(group) == false && socketTimeout == null) {
|
|
||||||
setting.getInt("socketTimeout");
|
|
||||||
}
|
|
||||||
if (socketTimeout != null) {
|
|
||||||
SocketSettings socketSettings = SocketSettings.builder().connectTimeout(socketTimeout, TimeUnit.MILLISECONDS).build();
|
|
||||||
builder.applyToSocketSettings(b -> b.applySettings(socketSettings));
|
|
||||||
log.debug("MongoDB socketTimeout: {}", socketTimeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查Setting配置文件
|
|
||||||
*
|
|
||||||
* @return Setting配置文件
|
|
||||||
*/
|
|
||||||
private Setting checkSetting() {
|
|
||||||
if (null == this.setting) {
|
|
||||||
throw new DbRuntimeException("Please indicate setting file or create default [{}]", MONGO_CONFIG_PATH);
|
|
||||||
}
|
|
||||||
return this.setting;
|
|
||||||
}
|
|
||||||
// --------------------------------------------------------------------------- Private method end
|
|
||||||
|
|
||||||
}
|
|
@ -10,16 +10,20 @@ import java.util.Map;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MongoDB工厂类,用于创建
|
* {@link MongoDS}工厂类,用于创建
|
||||||
* @author looly
|
|
||||||
*
|
*
|
||||||
|
* @author Looly, VampireAchao
|
||||||
*/
|
*/
|
||||||
public class MongoFactory {
|
public class MongoFactory {
|
||||||
|
|
||||||
/** 各分组做组合key的时候分隔符 */
|
/**
|
||||||
|
* 各分组做组合key的时候分隔符
|
||||||
|
*/
|
||||||
private final static String GROUP_SEPRATER = ",";
|
private final static String GROUP_SEPRATER = ",";
|
||||||
|
|
||||||
/** 数据源池 */
|
/**
|
||||||
|
* 数据源池
|
||||||
|
*/
|
||||||
private static final Map<String, MongoDS> DS_MAP = new ConcurrentHashMap<>();
|
private static final Map<String, MongoDS> DS_MAP = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
// JVM关闭前关闭MongoDB连接
|
// JVM关闭前关闭MongoDB连接
|
||||||
@ -28,6 +32,7 @@ public class MongoFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------ Get DS start
|
// ------------------------------------------------------------------------ Get DS start
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取MongoDB数据源<br>
|
* 获取MongoDB数据源<br>
|
||||||
*
|
*
|
||||||
@ -80,7 +85,7 @@ public class MongoFactory {
|
|||||||
* 获取MongoDB数据源<br>
|
* 获取MongoDB数据源<br>
|
||||||
*
|
*
|
||||||
* @param setting 设定文件
|
* @param setting 设定文件
|
||||||
* @param groups 分组列表
|
* @param groups 分组列表
|
||||||
* @return MongoDB连接
|
* @return MongoDB连接
|
||||||
*/
|
*/
|
||||||
public static MongoDS getDS(Setting setting, String... groups) {
|
public static MongoDS getDS(Setting setting, String... groups) {
|
||||||
@ -99,7 +104,7 @@ public class MongoFactory {
|
|||||||
* 获取MongoDB数据源<br>
|
* 获取MongoDB数据源<br>
|
||||||
*
|
*
|
||||||
* @param setting 配置文件
|
* @param setting 配置文件
|
||||||
* @param groups 分组列表
|
* @param groups 分组列表
|
||||||
* @return MongoDB连接
|
* @return MongoDB连接
|
||||||
*/
|
*/
|
||||||
public static MongoDS getDS(Setting setting, Collection<String> groups) {
|
public static MongoDS getDS(Setting setting, Collection<String> groups) {
|
||||||
@ -111,8 +116,8 @@ public class MongoFactory {
|
|||||||
* 关闭全部连接
|
* 关闭全部连接
|
||||||
*/
|
*/
|
||||||
public static void closeAll() {
|
public static void closeAll() {
|
||||||
if(MapUtil.isNotEmpty(DS_MAP)){
|
if (MapUtil.isNotEmpty(DS_MAP)) {
|
||||||
for(MongoDS ds : DS_MAP.values()) {
|
for (MongoDS ds : DS_MAP.values()) {
|
||||||
ds.close();
|
ds.close();
|
||||||
}
|
}
|
||||||
DS_MAP.clear();
|
DS_MAP.clear();
|
||||||
|
@ -1,120 +0,0 @@
|
|||||||
package cn.hutool.db.nosql.mongo;
|
|
||||||
|
|
||||||
import cn.hutool.core.map.MapUtil;
|
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
|
||||||
import cn.hutool.core.util.RuntimeUtil;
|
|
||||||
import cn.hutool.setting.Setting;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MongoDB4工厂类,用于创建
|
|
||||||
* @author VampireAchao
|
|
||||||
*/
|
|
||||||
public class MongoFactory4 {
|
|
||||||
|
|
||||||
/** 各分组做组合key的时候分隔符 */
|
|
||||||
private final static String GROUP_SEPRATER = ",";
|
|
||||||
|
|
||||||
/** 数据源池 */
|
|
||||||
private static final Map<String, MongoDS4> DS_MAP = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
// JVM关闭前关闭MongoDB连接
|
|
||||||
static {
|
|
||||||
RuntimeUtil.addShutdownHook(MongoFactory4::closeAll);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------ Get DS start
|
|
||||||
/**
|
|
||||||
* 获取MongoDB数据源<br>
|
|
||||||
*
|
|
||||||
* @param host 主机
|
|
||||||
* @param port 端口
|
|
||||||
* @return MongoDB连接
|
|
||||||
*/
|
|
||||||
public static MongoDS4 getDS(String host, int port) {
|
|
||||||
final String key = host + ":" + port;
|
|
||||||
MongoDS4 ds = DS_MAP.get(key);
|
|
||||||
if (null == ds) {
|
|
||||||
// 没有在池中加入之
|
|
||||||
ds = new MongoDS4(host, port);
|
|
||||||
DS_MAP.put(key, ds);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ds;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取MongoDB数据源<br>
|
|
||||||
* 多个分组名对应的连接组成集群
|
|
||||||
*
|
|
||||||
* @param groups 分组列表
|
|
||||||
* @return MongoDB连接
|
|
||||||
*/
|
|
||||||
public static MongoDS4 getDS(String... groups) {
|
|
||||||
final String key = ArrayUtil.join(groups, GROUP_SEPRATER);
|
|
||||||
MongoDS4 ds = DS_MAP.get(key);
|
|
||||||
if (null == ds) {
|
|
||||||
// 没有在池中加入之
|
|
||||||
ds = new MongoDS4(groups);
|
|
||||||
DS_MAP.put(key, ds);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ds;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取MongoDB数据源<br>
|
|
||||||
*
|
|
||||||
* @param groups 分组列表
|
|
||||||
* @return MongoDB连接
|
|
||||||
*/
|
|
||||||
public static MongoDS4 getDS(Collection<String> groups) {
|
|
||||||
return getDS(groups.toArray(new String[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取MongoDB数据源<br>
|
|
||||||
*
|
|
||||||
* @param setting 设定文件
|
|
||||||
* @param groups 分组列表
|
|
||||||
* @return MongoDB连接
|
|
||||||
*/
|
|
||||||
public static MongoDS4 getDS(Setting setting, String... groups) {
|
|
||||||
final String key = setting.getSettingPath() + GROUP_SEPRATER + ArrayUtil.join(groups, GROUP_SEPRATER);
|
|
||||||
MongoDS4 ds = DS_MAP.get(key);
|
|
||||||
if (null == ds) {
|
|
||||||
// 没有在池中加入之
|
|
||||||
ds = new MongoDS4(setting, groups);
|
|
||||||
DS_MAP.put(key, ds);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ds;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取MongoDB数据源<br>
|
|
||||||
*
|
|
||||||
* @param setting 配置文件
|
|
||||||
* @param groups 分组列表
|
|
||||||
* @return MongoDB连接
|
|
||||||
*/
|
|
||||||
public static MongoDS4 getDS(Setting setting, Collection<String> groups) {
|
|
||||||
return getDS(setting, groups.toArray(new String[0]));
|
|
||||||
}
|
|
||||||
// ------------------------------------------------------------------------ Get DS ends
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 关闭全部连接
|
|
||||||
*/
|
|
||||||
public static void closeAll() {
|
|
||||||
if(MapUtil.isNotEmpty(DS_MAP)){
|
|
||||||
for(MongoDS4 ds : DS_MAP.values()) {
|
|
||||||
ds.close();
|
|
||||||
}
|
|
||||||
DS_MAP.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
package cn.hutool.db.nosql;
|
package cn.hutool.db.nosql;
|
||||||
|
|
||||||
import cn.hutool.db.nosql.mongo.MongoFactory4;
|
import cn.hutool.db.nosql.mongo.MongoFactory;
|
||||||
import com.mongodb.client.MongoDatabase;
|
import com.mongodb.client.MongoDatabase;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
@ -13,8 +13,8 @@ public class MongoDBTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
@Ignore
|
||||||
public void redisDSTest() {
|
public void mongoDSTest() {
|
||||||
MongoDatabase db = MongoFactory4.getDS("master").getDb("test");
|
MongoDatabase db = MongoFactory.getDS("master").getDb("test");
|
||||||
Assert.assertEquals("test", db.getName());
|
Assert.assertEquals("test", db.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user