Browse Source

mongo支持多数据源版本

刘凯雄 2 years ago
parent
commit
b9ac0e2ceb

+ 6 - 13
elab-mongodb/pom.xml

@@ -9,9 +9,7 @@
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <groupId>com.elab.core</groupId>
     <artifactId>elab-mongodb</artifactId>
-    <!--<version>2.0.4.1</version>-->
 
     <dependencies>
         <dependency>
@@ -23,17 +21,6 @@
             <groupId>cn.hutool</groupId>
             <artifactId>hutool-all</artifactId>
         </dependency>
-        <!--<dependency>-->
-            <!--<groupId>com.elab.core</groupId>-->
-            <!--<artifactId>elab-spring</artifactId>-->
-            <!--<version>${project.version}</version>-->
-            <!--<exclusions>-->
-                <!--<exclusion>-->
-                    <!--<artifactId>spring-expression</artifactId>-->
-                    <!--<groupId>org.springframework</groupId>-->
-                <!--</exclusion>-->
-            <!--</exclusions>-->
-        <!--</dependency>-->
         <dependency>
             <groupId>org.springframework.data</groupId>
             <artifactId>spring-data-mongodb</artifactId>
@@ -59,6 +46,12 @@
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <version>${springboot.version}</version>
+            <optional>true</optional>
+        </dependency>
     </dependencies>
 
 </project>

+ 56 - 0
elab-mongodb/src/REDEME.md

@@ -166,4 +166,60 @@ System.out.println(list.size());
 ```
 
 
+## 多数据源切换配置
+### yaml配置
+定义数据源
+```yaml
+spring:
+  elab:
+    mongodb:
+      group-source:
+        test1: # 这个是数据源的key,切换的依据,不同的数据源定义不同
+          host: xxxx
+          port: 27017
+          databaseName: mofang
+          username: xxxx
+          password: xxxx
+        local:
+          host: localhost
+          port: 27017
+          databaseName: test
+```
+
+### 如何切换
+```java
+@Autowired
+private MongoSelector selector;
+
+@Autowired
+private UserMongoCollection userMongoCollection;
+
+// 注入的方式
+final MongoTemplate test1 = selector.get("test1");
+final MongoTemplate test2 = selector.get("test2");
+
+// 静态工具类的方式
+final MongoTemplate test11 = MongoSelector.selectKey("test1");
+
+// 老代码兼容切换
+User user = new User();
+user.setUsername("lkx");
+final Long count = userMongoCollection.count(user);
+```
+
+```java
+public class UserMongoCollection extends BaseMongodb<User> {
 
+    @Override
+    public Class<User> getEntity() {
+        return User.class;
+    }
+
+    @Override
+    public MongoTemplate getMongoTemplate() {
+        // 按照你希望的数据源的key
+        return MongoSelector.selectKey("local");
+    }
+
+}
+```

+ 120 - 0
elab-mongodb/src/main/java/com/elab/mongodb/MongoHelper.java

@@ -0,0 +1,120 @@
+package com.elab.mongodb;
+
+import com.elab.mongodb.chain.MongoInterceptInvoke;
+import com.elab.mongodb.config.property.MongoConfig;
+import com.mongodb.MongoClient;
+import com.mongodb.MongoClientURI;
+import com.mongodb.MongoCredential;
+import com.mongodb.ServerAddress;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
+import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
+import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
+import org.springframework.data.mongodb.core.convert.MongoConverter;
+
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * mongo构建帮助类
+ *
+ * @author liukaixiong
+ * @date 2022/10/10 - 13:15
+ */
+public class MongoHelper {
+    private static final Logger logger = LoggerFactory.getLogger(MongoHelper.class);
+
+    public static MongoTemplate newMongoTemplate(MongoConfig mongoConfig,
+        List<MongoInterceptInvoke> mongoInterceptInvokeList) throws UnknownHostException {
+        String mongoClientHost = mongoConfig.getHost();
+        String[] mongoClientHosts = mongoClientHost.split(",");
+        int[] mongoClientPorts = {mongoConfig.getPort()};
+        String mongodbName = mongoConfig.getDatabaseName();
+        String clusterUrl = mongoConfig.getClusterUrl();
+        String userName = mongoConfig.getUserName() == null ? "" : mongoConfig.getUserName();
+        String password = mongoConfig.getPassword() == null ? "" : mongoConfig.getPassword();
+        if (null != clusterUrl && clusterUrl.length() > 0) {
+            String[] hostAndPorts = clusterUrl.split(",");
+            mongoClientHosts = new String[hostAndPorts.length];
+            mongoClientPorts = new int[hostAndPorts.length];
+            for (int i = 0; i < hostAndPorts.length; i++) {
+                String[] hostAndPortArray = hostAndPorts[i].split(":");
+                mongoClientHosts[i] = hostAndPortArray[0];
+                mongoClientPorts[i] = Integer.parseInt(hostAndPortArray[1]);
+            }
+            return buildMongoTemplateCluster(mongoClientHosts, mongoClientPorts, mongodbName, userName, password,
+                mongoInterceptInvokeList);
+        } else {
+            MongoCredential userCredentials =
+                MongoCredential.createCredential(userName, mongoConfig.getDatabaseName(), password.toCharArray());
+            return buildMongoTemplate(mongoClientHosts, mongoConfig.getPort(), mongodbName, userCredentials,
+                mongoInterceptInvokeList);
+        }
+    }
+
+    private static MongoTemplate buildMongoTemplate(String[] mongoClientHosts, int port, String mongodbName,
+        MongoCredential userCredentials, List<MongoInterceptInvoke> mongoInterceptInvokeList)
+        throws UnknownHostException {
+        List<ServerAddress> serverAddressList = new ArrayList<>();
+        for (String host : mongoClientHosts) {
+            serverAddressList.add(new ServerAddress(host, port));
+        }
+        MongoClient mongoClient = new MongoClient(serverAddressList);
+        SimpleMongoDbFactory mongoDbFactory = null;
+        if (userCredentials != null && StringUtils.isNotEmpty(userCredentials.getUserName())
+            && userCredentials.getPassword() != null) {
+            //mongodb://${mongo.username}:${mongo.password}@${mongo.uri}/${mongo.db}
+            String uri =
+                "mongodb://" + userCredentials.getUserName() + ":" + new String(userCredentials.getPassword()) + "@"
+                    + mongoClientHosts[0] + ":" + port + "/" + mongodbName + "";
+            MongoClientURI mongoClientURI = new MongoClientURI(uri);
+            mongoDbFactory = new SimpleMongoDbFactory(mongoClientURI);
+        } else {
+            mongoDbFactory = new SimpleMongoDbFactory(mongoClient, mongodbName);
+        }
+        return getMongoTemplate(mongoDbFactory, mongoInterceptInvokeList);
+    }
+
+    private static MongoTemplate getMongoTemplate(SimpleMongoDbFactory mongoDbFactory,
+        List<MongoInterceptInvoke> mongoInterceptInvokeList) {
+        SimpleMongodbTemplate mongoTemplate = new SimpleMongodbTemplate(mongoDbFactory);
+        mongoTemplate.setMongoInterceptInvokeList(mongoInterceptInvokeList);
+        convertClass(mongoTemplate);
+        return mongoTemplate;
+    }
+
+    private static MongoTemplate buildMongoTemplateCluster(String[] mongoClientHosts, int[] mongoClientPorts,
+        String mongodbName, String userName, String password, List<MongoInterceptInvoke> mongoInterceptInvokeList) {
+        try {
+            List<ServerAddress> serverAddressList = new ArrayList<>();
+            for (int i = 0; i < mongoClientHosts.length; i++) {
+                if (mongoClientPorts.length < i + 1) {
+                    mongoClientPorts[i] = mongoClientPorts[i - 1];
+                }
+                serverAddressList.add(new ServerAddress(mongoClientHosts[i], mongoClientPorts[i]));
+            }
+            MongoCredential userCredentials =
+                MongoCredential.createCredential(userName, mongodbName, password.toCharArray());
+            List<MongoCredential> userCredentialsList = new ArrayList<>();
+            userCredentialsList.add(userCredentials);
+            MongoClient mongoClient = new MongoClient(serverAddressList, userCredentialsList);
+
+            SimpleMongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongoClient, mongodbName);
+            return getMongoTemplate(mongoDbFactory, mongoInterceptInvokeList);
+        } catch (Exception e) {
+            logger.error("mongodb 初始化失败", e);
+        }
+        return null;
+    }
+
+    private static void convertClass(MongoTemplate mongoTemplate) {
+        MongoConverter converter = mongoTemplate.getConverter();
+        if (converter.getTypeMapper().isTypeKey("_class")) {
+            ((MappingMongoConverter)converter).setTypeMapper(new DefaultMongoTypeMapper(null));
+        }
+    }
+}

+ 6 - 102
elab-mongodb/src/main/java/com/elab/mongodb/config/MongoAutoConfiguration.java

@@ -1,16 +1,9 @@
 package com.elab.mongodb.config;
 
-import com.elab.mongodb.SimpleMongodbTemplate;
+import com.elab.mongodb.MongoHelper;
 import com.elab.mongodb.chain.CatMongoInterceptInvoke;
 import com.elab.mongodb.chain.MongoInterceptInvoke;
 import com.elab.mongodb.config.property.MongoConfig;
-import com.mongodb.MongoClient;
-import com.mongodb.MongoClientURI;
-import com.mongodb.MongoCredential;
-import com.mongodb.ServerAddress;
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -18,13 +11,8 @@ import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.EnableAspectJAutoProxy;
 import org.springframework.data.mongodb.core.MongoTemplate;
-import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
-import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
-import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
-import org.springframework.data.mongodb.core.convert.MongoConverter;
 
 import java.net.UnknownHostException;
-import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -39,13 +27,8 @@ import java.util.List;
  **/
 @Configuration
 @EnableAspectJAutoProxy
-@EnableConfigurationProperties(value = MongoConfig.class)
+@EnableConfigurationProperties(value = {MongoConfig.class})
 public class MongoAutoConfiguration {
-    private Logger logger = LoggerFactory.getLogger(getClass());
-
-    @Autowired(required = false)
-    private List<MongoInterceptInvoke> mongoInterceptInvokeList;
-
     @Bean
     public MongoInterceptInvoke catMongoInterceptInvoke() {
         return new CatMongoInterceptInvoke();
@@ -55,89 +38,10 @@ public class MongoAutoConfiguration {
     @ConditionalOnMissingBean(value = {MongoTemplate.class})
     public MongoTemplate mongoTemplate(
         @Autowired
-            MongoConfig mongoConfig) throws UnknownHostException {
-        String mongoClientHost = mongoConfig.getHost();
-        String[] mongoClientHosts = mongoClientHost.split(",");
-        int[] mongoClientPorts = {mongoConfig.getPort()};
-        String mongodbName = mongoConfig.getDatabaseName();
-        String clusterUrl = mongoConfig.getClusterUrl();
-        String userName = mongoConfig.getUserName() == null ? "" : mongoConfig.getUserName();
-        String password = mongoConfig.getPassword() == null ? "" : mongoConfig.getPassword();
-        if (null != clusterUrl && clusterUrl.length() > 0) {
-            String[] hostAndPorts = clusterUrl.split(",");
-            mongoClientHosts = new String[hostAndPorts.length];
-            mongoClientPorts = new int[hostAndPorts.length];
-            for (int i = 0; i < hostAndPorts.length; i++) {
-                String[] hostAndPortArray = hostAndPorts[i].split(":");
-                mongoClientHosts[i] = hostAndPortArray[0];
-                mongoClientPorts[i] = Integer.parseInt(hostAndPortArray[1]);
-            }
-            return buildMongoTemplateCluster(mongoClientHosts, mongoClientPorts, mongodbName, userName, password);
-        } else {
-            MongoCredential userCredentials =
-                MongoCredential.createCredential(userName, mongoConfig.getDatabaseName(), password.toCharArray());
-            return buildMongoTemplate(mongoClientHosts, mongoConfig.getPort(), mongodbName, userCredentials);
-        }
-    }
-
-    private MongoTemplate buildMongoTemplate(String[] mongoClientHosts, int port, String mongodbName,
-        MongoCredential userCredentials) throws UnknownHostException {
-        List<ServerAddress> serverAddressList = new ArrayList<>();
-        for (String host : mongoClientHosts) {
-            serverAddressList.add(new ServerAddress(host, port));
-        }
-        MongoClient mongoClient = new MongoClient(serverAddressList);
-        SimpleMongoDbFactory mongoDbFactory = null;
-        if (userCredentials != null && StringUtils.isNotEmpty(userCredentials.getUserName())
-            && userCredentials.getPassword() != null) {
-            //mongodb://${mongo.username}:${mongo.password}@${mongo.uri}/${mongo.db}
-            String uri =
-                "mongodb://" + userCredentials.getUserName() + ":" + new String(userCredentials.getPassword()) + "@"
-                    + mongoClientHosts[0] + ":" + port + "/" + mongodbName + "";
-            MongoClientURI mongoClientURI = new MongoClientURI(uri);
-            mongoDbFactory = new SimpleMongoDbFactory(mongoClientURI);
-        } else {
-            mongoDbFactory = new SimpleMongoDbFactory(mongoClient, mongodbName);
-        }
-        return getMongoTemplate(mongoDbFactory);
-    }
-
-    private MongoTemplate getMongoTemplate(SimpleMongoDbFactory mongoDbFactory) {
-        SimpleMongodbTemplate mongoTemplate = new SimpleMongodbTemplate(mongoDbFactory);
-        mongoTemplate.setMongoInterceptInvokeList(mongoInterceptInvokeList);
-        convertClass(mongoTemplate);
-        return mongoTemplate;
-    }
-
-    private MongoTemplate buildMongoTemplateCluster(String[] mongoClientHosts, int[] mongoClientPorts,
-        String mongodbName, String userName, String password) {
-        try {
-            List<ServerAddress> serverAddressList = new ArrayList<>();
-            for (int i = 0; i < mongoClientHosts.length; i++) {
-                if (mongoClientPorts.length < i + 1) {
-                    mongoClientPorts[i] = mongoClientPorts[i - 1];
-                }
-                serverAddressList.add(new ServerAddress(mongoClientHosts[i], mongoClientPorts[i]));
-            }
-            MongoCredential userCredentials =
-                MongoCredential.createCredential(userName, mongodbName, password.toCharArray());
-            List<MongoCredential> userCredentialsList = new ArrayList<>();
-            userCredentialsList.add(userCredentials);
-            MongoClient mongoClient = new MongoClient(serverAddressList, userCredentialsList);
-
-            SimpleMongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongoClient, mongodbName);
-            return getMongoTemplate(mongoDbFactory);
-        } catch (Exception e) {
-            logger.error("mongodb 初始化失败", e);
-        }
-        return null;
-    }
-
-    private void convertClass(MongoTemplate mongoTemplate) {
-        MongoConverter converter = mongoTemplate.getConverter();
-        if (converter.getTypeMapper().isTypeKey("_class")) {
-            ((MappingMongoConverter)converter).setTypeMapper(new DefaultMongoTypeMapper(null));
-        }
+            MongoConfig mongoConfig,
+        @Autowired(required = false)
+            List<MongoInterceptInvoke> mongoInterceptInvokeList) throws UnknownHostException {
+        return MongoHelper.newMongoTemplate(mongoConfig, mongoInterceptInvokeList);
     }
 
 }

+ 45 - 0
elab-mongodb/src/main/java/com/elab/mongodb/config/MongoMultipleAutoConfiguration.java

@@ -0,0 +1,45 @@
+package com.elab.mongodb.config;
+
+import com.elab.mongodb.MongoHelper;
+import com.elab.mongodb.chain.MongoInterceptInvoke;
+import com.elab.mongodb.config.property.MongoConfig;
+import com.elab.mongodb.config.property.MultipleMongoProperties;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.net.UnknownHostException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 多mongo实例自动配置
+ *
+ * @author liukaixiong
+ * @date 2022/10/10 - 10:40
+ */
+@Configuration
+@EnableConfigurationProperties(value = {MultipleMongoProperties.class})
+public class MongoMultipleAutoConfiguration {
+
+    @Autowired(required = false)
+    private List<MongoInterceptInvoke> mongoInterceptInvokeList;
+
+    @Bean
+    public MongoSelector mongoSelector(MultipleMongoProperties properties) {
+
+        final MongoSelector instance = MongoSelector.getInstance();
+
+        final Map<String, MongoConfig> groupSource = properties.getGroupSource();
+        groupSource.forEach((k, v) -> {
+            try {
+                instance.add(k, MongoHelper.newMongoTemplate(v, mongoInterceptInvokeList));
+            } catch (UnknownHostException e) {
+                e.printStackTrace();
+            }
+        });
+        return instance;
+    }
+
+}

+ 62 - 0
elab-mongodb/src/main/java/com/elab/mongodb/config/MongoSelector.java

@@ -0,0 +1,62 @@
+package com.elab.mongodb.config;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.util.Assert;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * mongo选择器
+ *
+ * @author liukaixiong
+ * @date 2022/10/10 - 10:44
+ */
+public class MongoSelector {
+    private static final MongoSelector INSTANCE = new MongoSelector();
+    private final Logger logger = LoggerFactory.getLogger(getClass());
+    private final Map<String, MongoTemplate> selector = new HashMap<>();
+
+    public static MongoSelector getInstance() {
+        return INSTANCE;
+    }
+
+    /**
+     * 选择对应的key
+     *
+     * @param name db的key
+     * @return
+     */
+    public static MongoTemplate selectKey(String name) {
+        return getInstance().get(name);
+    }
+
+    /**
+     * 添加对应的key
+     *
+     * @param name
+     * @param mongoTemplate
+     */
+    protected void add(String name, MongoTemplate mongoTemplate) {
+        Assert.notNull(name, "name 不能为空!");
+        Assert.notNull(mongoTemplate, "mongoTemplate 不能为空!");
+
+        selector.put(name, mongoTemplate);
+        logger.info("mongo新增[{}]连接, mongoDBName:{}", name, mongoTemplate.getDb().getName());
+    }
+
+    /**
+     * 获取对应的key的连接
+     *
+     * @param name
+     * @return
+     */
+    public MongoTemplate get(String name) {
+        final MongoTemplate mongoTemplate = selector.get(name);
+        Assert.notNull(mongoTemplate, "没有找到[" + name + "]相关的mongo数据源,请检查[spring.elab.mongodb.group-source]是否定义!");
+        return mongoTemplate;
+    }
+
+}

+ 27 - 0
elab-mongodb/src/main/java/com/elab/mongodb/config/property/MultipleMongoProperties.java

@@ -0,0 +1,27 @@
+package com.elab.mongodb.config.property;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.NestedConfigurationProperty;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 多mongo实例配置
+ *
+ * @author liukaixiong
+ * @date 2022/10/10 - 10:37
+ */
+@ConfigurationProperties(prefix = "spring.elab.mongodb")
+public class MultipleMongoProperties {
+
+    private Map<String, MongoConfig> groupSource = new HashMap<>();
+
+    public Map<String, MongoConfig> getGroupSource() {
+        return groupSource;
+    }
+
+    public void setGroupSource(Map<String, MongoConfig> groupSource) {
+        this.groupSource = groupSource;
+    }
+}

+ 36 - 0
elab-mongodb/src/test/java/com/elab/mongodb/config/MongoMultipleAutoConfigurationTest.java

@@ -0,0 +1,36 @@
+package com.elab.mongodb.config;
+
+import com.elab.mongodb.chain.CatMongoInterceptInvoke;
+import com.elab.test.mongodb.entity.User;
+import com.elab.test.mongodb.ext.UserMongoCollection;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = {MongoMultipleAutoConfiguration.class, MongoAutoConfiguration.class, UserMongoCollection.class,
+    CatMongoInterceptInvoke.class})
+public class MongoMultipleAutoConfigurationTest {
+
+    @Autowired
+    private MongoSelector selector;
+
+    @Autowired
+    private UserMongoCollection userMongoCollection;
+
+    @Test
+    public void test() throws Exception {
+        final MongoTemplate test1 = selector.get("test1");
+        final MongoTemplate test2 = selector.get("test2");
+
+        final MongoTemplate test11 = MongoSelector.selectKey("test1");
+        User user = new User();
+        user.setUsername("lkx");
+        final Long count = userMongoCollection.count(user);
+        System.out.println(count);
+    }
+
+}

+ 26 - 0
elab-mongodb/src/test/java/com/elab/test/mongodb/ext/UserMongoCollection.java

@@ -0,0 +1,26 @@
+package com.elab.test.mongodb.ext;
+
+import com.elab.mongodb.BaseMongodb;
+import com.elab.mongodb.config.MongoSelector;
+import com.elab.test.mongodb.entity.User;
+import org.springframework.data.mongodb.core.MongoTemplate;
+
+/**
+ *
+ * @author Liukx
+ * @create 2018-05-03 15:41
+ * @email liukx@elab-plus.com
+ **/
+public class UserMongoCollection extends BaseMongodb<User> {
+
+    @Override
+    public Class<User> getEntity() {
+        return User.class;
+    }
+
+    @Override
+    public MongoTemplate getMongoTemplate() {
+        return MongoSelector.selectKey("local");
+    }
+
+}

+ 15 - 1
elab-mongodb/src/test/resources/application.yml

@@ -8,4 +8,18 @@ mongodb:
   port: 27017
   databaseName: test
 
-app.name: cat-mongo-demo
+app.name: cat-mongo-demo
+spring:
+  elab:
+    mongodb:
+      group-source:
+        test1:
+          host: 106.15.201.221
+          port: 27017
+          databaseName: mofang
+          username: elab
+          password: elab8888
+        local:
+          host: localhost
+          port: 27017
+          databaseName: test