1. 程式人生 > >spring整合多個mongodb庫

spring整合多個mongodb庫

1. 仿照抽象路由資料來源類建立一個抽象mongodb路由模板源的類。因為操作mongodb的是模板。

package com.caiwufei.common.db.mongo;

import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.util.Assert;

public abstract class AbstractMongoDBRoutingTemplateSource implements InitializingBean{
	
	private Map<Object, Object> targetMongoTemplates;

    private Object defaultTargetMongoTemplate;

    private Map<Object, MongoTemplate> resolvedMongoTemplates;

    private MongoTemplate resolvedDefaultMongoTemplate;

    @Override
    public void afterPropertiesSet() {
        if (this.targetMongoTemplates == null) {
            throw new IllegalArgumentException("Property 'targetMongoTemplates' is required");
        }
        this.resolvedMongoTemplates = new HashMap<Object, MongoTemplate>(this.targetMongoTemplates.size());
        for (Map.Entry<Object, Object> entry : this.targetMongoTemplates.entrySet()) {
            Object lookupKey = resolveSpecifiedLookupKey(entry.getKey());
            MongoTemplate mongoTemplate = resolveSpecifiedMongoTemplate(entry.getValue());
            this.resolvedMongoTemplates.put(lookupKey, mongoTemplate);
        }

        if (this.defaultTargetMongoTemplate != null) {
            this.resolvedDefaultMongoTemplate = resolveSpecifiedMongoTemplate(this.defaultTargetMongoTemplate);
        }
    }

    protected Object resolveSpecifiedLookupKey(Object lookupKey) {
        return lookupKey;
    }

    protected MongoTemplate resolveSpecifiedMongoTemplate(Object mongoTemplate) throws IllegalArgumentException {
        if (mongoTemplate instanceof MongoTemplate) {
            return (MongoTemplate) mongoTemplate;
        } else {
            throw new IllegalArgumentException(
                    "Illegal data source value - only [org.springframework.data.mongodb.core.MongoTemplate] and String supported: "
                            + mongoTemplate);
        }
    }

    protected MongoTemplate determineMongoTemplate() {
        Assert.notNull(this.resolvedMongoTemplates, "mongoTemplate router not initialized");
        Object lookupKey = determineCurrentLookupKey();
        MongoTemplate mongoTemplate = this.resolvedMongoTemplates.get(lookupKey);
        if (mongoTemplate == null && (lookupKey == null)) {
            mongoTemplate = this.resolvedDefaultMongoTemplate;
        }
        if (mongoTemplate == null) {
            throw new IllegalStateException("Cannot determine target MongoTemplate for lookup key [" + lookupKey + "]");
        }
        return mongoTemplate;
    }
    
    public Object getDefaultTargetMongoTemplate() {
		return defaultTargetMongoTemplate;
	}

	public void setDefaultTargetMongoTemplate(Object defaultTargetMongoTemplate) {
		this.defaultTargetMongoTemplate = defaultTargetMongoTemplate;
	}

	public Map<Object, Object> getTargetMongoTemplates() {
		return targetMongoTemplates;
	}

    public void setTargetMongoTemplates(Map<Object, Object> targetMongoTemplates) {
        this.targetMongoTemplates = targetMongoTemplates;
    }
    
	protected abstract Object determineCurrentLookupKey();  
}
2 建立一個動態模板資料來源,繼承上面這個抽象模板源的類。這一點和多個數據庫相似。
package com.caiwufei.common.db.mongo;

import org.springframework.data.mongodb.core.MongoTemplate;
import com.caiwufei.common.db.DBContextHolder;

public class MongoDynamicTemplateSource extends AbstractMongoDBRoutingTemplateSource{

	public MongoTemplate getMongoTemplate(){
		return determineMongoTemplate();
	}
	
	@Override
	protected Object determineCurrentLookupKey() {
		return DBContextHolder.Mongo.getTargetMongoTemplate();
	}

}
3. 配置mongodb的xml檔案
<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	   xmlns="http://www.springframework.org/schema/beans" 
	   xmlns:context="http://www.springframework.org/schema/context" 
       xmlns:aop="http://www.springframework.org/schema/aop"  
       xmlns:tx="http://www.springframework.org/schema/tx" 
       xmlns:mongo="http://www.springframework.org/schema/data/mongo"  
       xmlns:repository="http://www.springframework.org/schema/data/repository"
       xsi:schemaLocation="http://www.springframework.org/schema/context  
                           http://www.springframework.org/schema/context/spring-context.xsd  
    					   http://www.springframework.org/schema/beans  
    					   http://www.springframework.org/schema/beans/spring-beans.xsd
    					   http://www.springframework.org/schema/aop
    					   http://www.springframework.org/schema/apo/spring-aop.xsd  
    					   http://www.springframework.org/schema/tx  
    		               http://www.springframework.org/schema/tx/spring-tx.xsd
    		               http://www.springframework.org/schema/data/mongo   
                           http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
                           http://www.springframework.org/schema/data/repository
                           http://www.springframework.org/schema/data/repository/spring-repository.xsd">  
                           
      <bean id="mongoMappingContext" class="org.springframework.data.mongodb.core.mapping.MongoMappingContext" />  
      
      <bean id="mongoTypeMapper" class="org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper">    
          <constructor-arg name="typeKey">
          	  <null/>
          </constructor-arg>    
 	  </bean> 
   
      <mongo:mapping-converter id="mongoMappingConverter" 
                               base-package="com.caiwufei.entity" 
             			       mapping-context-ref="mongoMappingContext" 
                               type-mapper-ref="mongoTypeMapper"/>
  
	  <!-- mongo_stg client -->
	  <mongo:mongo-client id="mongo_stg" host="127.0.0.1" port="23092" credentials="cfsssopr:
[email protected]
" > <mongo:client-options connect-timeout="5000" connections-per-host="10" description="mongo_stg" heartbeat-connect-timeout="1000" heartbeat-frequency="100" heartbeat-socket-timeout="1000" max-connection-idle-time="1500" max-connection-life-time="0" max-wait-time="10000" min-connections-per-host="5" min-heartbeat-frequency="10" read-preference="PRIMARY" socket-keep-alive="true" socket-timeout="3000" ssl="false" threads-allowed-to-block-for-connection-multiplier="5" write-concern="NONE" /> </mongo:mongo-client> <!-- mongo_pro client --> <mongo:mongo-client id="mongo_pro" host="127.0.0.1" port="24086" credentials="devsup01:[email protected]"> <mongo:client-options connect-timeout="5000" connections-per-host="10" description="mongo_pro" heartbeat-connect-timeout="1000" heartbeat-frequency="100" heartbeat-socket-timeout="1000" max-connection-idle-time="1500" max-connection-life-time="0" max-wait-time="10000" min-connections-per-host="5" min-heartbeat-frequency="10" read-preference="PRIMARY" socket-keep-alive="true" socket-timeout="3000" ssl="false" threads-allowed-to-block-for-connection-multiplier="5" write-concern="NONE" /> </mongo:mongo-client> <!-- mongoDbFactory stg未使用“mongoFactory_stg”,因為框架其他的bean強制使用了“mongoDbFactory”引入 --> <mongo:db-factory id="mongoDbFactory" dbname="cfsss" mongo-ref="mongo_stg"/> <mongo:db-factory id="mongoFactory_pro" dbname="cfsss" mongo-ref="mongo_pro"/> <!-- 兩個模板 --> <mongo:template id="mongoTemplate_stg" db-factory-ref="mongoDbFactory" converter-ref="mongoMappingConverter"/> <mongo:template id="mongoTemplate_pro" db-factory-ref="mongoFactory_pro" converter-ref="mongoMappingConverter"/> <!-- 動態資料來源模板 --> <bean id="mongoTemplateSource" class="com.caiwufei.common.db.mongo.MongoDynamicTemplateSource"> <property name="defaultTargetMongoTemplate" ref="mongoTemplate_stg"/> <property name="targetMongoTemplates"> <map> <entry key="stg" value-ref="mongoTemplate_stg"></entry> <entry key="pro" value-ref="mongoTemplate_pro"></entry> </map> </property> </bean> </beans>
4. 建立資料來源上下文。方便在其他地方,使用靜態方法更換資料模板
package com.caiwufei.common.db;

import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Component;
import com.caiwufei.common.db.mongo.MongoDynamicTemplateSource;

@Component
public class DBContextHolder{
	
	@Autowired
	private MongoDynamicTemplateSource dynamicTemplateSource;
	
	private static DBContextHolder dbContextHolder;
	
	private static final ThreadLocal<String> dbName = new ThreadLocal<String>();
	
	private static final ThreadLocal<String> mongoTemplate = new ThreadLocal<String>();
    
    @PostConstruct
	public void init() {
		dbContextHolder = this;
		dbContextHolder.dynamicTemplateSource = this.dynamicTemplateSource;
	}

	public void setMongoTemplateSource(MongoDynamicTemplateSource mongoTemplateSource) {
		this.dynamicTemplateSource = mongoTemplateSource;
	}

	public static class DB {
		
		public static void changeTargetDataSource(String dataKey){
			dbName.set(dataKey);
		}
		
		public static String getTargetDataSource(){
			return dbName.get();
		}
	}
	
	public static class Mongo {
		
		public static void changeTargetMongoTemplate(String mongoTemplateKey){
			mongoTemplate.set(mongoTemplateKey);
		}
		
		public static String getTargetMongoTemplate(){
			return mongoTemplate.get();
		}
		
	}
	
	public static MongoTemplate mongoTemplate() {
		return dbContextHolder.dynamicTemplateSource.getMongoTemplate();
	}

}





相關推薦

spring整合mongodb

1. 仿照抽象路由資料來源類建立一個抽象mongodb路由模板源的類。因為操作mongodb的是模板。 package com.caiwufei.common.db.mongo; import java.util.HashMap; import java.util.Map

django中配置mongodb數據

默認 bsp def imp test string body mode name 在Djnago中使用MongoDB數據庫時,使用mongoengine模塊。在settings中配置數據庫連接如下: from mongoengine import co

JavaScript使用 $ 號的命名沖突問題

多個 script 一個 對象 conflict onf java read 調用 多個JavaScript庫使用 $ 號的命名沖突問題:  1. 為解決這個問題,jQuery 提供了一個 jQuery.noConflict() 方法,調用該方法可以把對 $ 標

android開發源代碼分析--activity調用jni的方法

red 設有 path 我們 trac sha ndk bin p s android開發源代碼分析--多個activity調用多個jni庫的方法 有時候,我們在開發android項目時會遇到須要調用多個native c/jni庫文件,下面是本人以前實現過的方

阿裏雲上安裝版本

AI auth 技術 admin 權限 註意 開啟 更改 svn服務 1.已經在阿裏雲上成功安裝了svn服務端,但是沒有搞明白URL應用,嘗試安裝第二個版本庫。 2.進入svn目錄下 3.創建admin版本庫 4.查看是否創建成功 5.配置svn文件配置 先進入con

spring cloud消費端重複定義feign client,模組掃描

問題連線:點選開啟連結  嘗試將FeignClient單獨建立了一個模組G,將對各個模組的FeignClient呼叫介面集中在模組G中管理,A,B,C,D,E,F模組互調時,只需要在pom中引入G模組即可。但一直失敗,對於該問題網上大都是 加@ComponentScan(basePack

spring配置事務管理器

<tx:annotation-driven/> <bean id="transactionManager1" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <prope

Spring與Web框架(例如Spring MVC)漫談——關於Spring對於Web框架的支援

  在看Spring MVC的官方文件時,最後一章是關於Spring對於其它Web框架的支援(如JSF,Apache Struts 2.x,Tapestry 5.x),當然Spring自己的MVC框架Spring MVC就不用多說了。   這裡並不想討論其它的Web框架,而是記錄下這章開頭提到的關於Spri

java連線mongoDB資料庫

開發需求: 1.客戶端聊天過程中需要根據玩家uid和所在聊天室ID,去對應服的遊戲資料庫查詢該玩家的使用者資訊,並返回給客戶端。 2.PVP記錄、離線訊息需要記錄到另一個數據庫。 之前的mongoDB工具類只考慮到連線一個數據庫,現在需要根據配置檔案,連線多個數據庫 稍微

spring boot圖片上傳

package com.example.demo.controller; import org.apache.commons.io.FileUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spri

Jenkins pipeline中下載配置

場景:        流水構建場景有時候需要下載多個配置庫的程式碼        參考https://stackoverflow.com/questions/40224272/using-a-jenkins-pipeline-to-checkout-multiple-g

MyBatis對整合表的類的操作

前言 前幾天在實現oj的DAO層時,由於將problem表中的一些欄位拿出來做了字典表,導致了資料庫表過多,如果還是像以前一樣: 一個數據庫表對應一個實體類的話,這樣不僅會增加好多重複性的工作,還會使

引入jquery時js的衝突解決

當一個專案中引入多個第三方庫的時候,由於沒有名稱空間的約束(名稱空間就好比同 一個目錄下的資料夾一樣,名字相同就會產生衝突),庫與庫之間發生衝突在所難免。 那麼,既然有衝突的問題,為什麼要使用多個庫呢?原因是jQuery 只不過是DOM 操 作為主的庫,方便我們日常

Android多渠道整合功能邏輯實現的方法

以自動更新功能為例,360、百度都要求整合各自的更新sdk,如何用同一套程式碼去解決。 1、建立兩個module,分佈將百度、360的sdk放進去。 2、在兩個module下建立一個相同包名、類名的類 3、在同名類下實現同名方法,方法內實現各自邏輯。 第一個實

關於Android的.so檔案---第三方載入到工程讀取不到.so的解決辦法

原文連結 早期的Android系統幾乎只支援ARMv5的CPU架構,你知道現在它支援多少種嗎?7種! Android系統目前支援以下七種不同的CPU架構:ARMv5,ARMv7 (從2010年起),x86 (從2011年起),MIPS (從2012年起),ARMv8,MIPS64和x86_64 (從

spring框架個數據操作需統一提交事務回滾機制解析以及解決辦法

1、遇到的問題   當我們一個方法裡面有多個數據庫儲存操作的時候,中間的資料庫操作發生的錯誤。虛擬碼如下: public method() { Dao1.save(Person1); Dao1.save(Person2); Dao1.sa

springservice中的方法不在同一個事物

問題:1、spring重啟在啟動階段初始化兩次 第一次通過web.xml配置以XmlWebApplicationContext為入口 第二次通過ClassPathXmlApplicationContext為入口

windows 、linux 下 靜態合併成一個靜態

第一步、 開啟visual studio 下的對應平臺命令列工具 第二步、 執行lib命令 lib /OUT:ETKey.lib A.lib B.lib ,完畢 linux 下的合成庫 Li

Jenkins編譯任務如何下載git程式碼到同一本地倉庫

問題提出: Jenkins裡下載程式碼時出現程式碼在不同的git庫裡面,怎麼將不同位置的不同程式碼下載到同一個本地目錄下?SVN倒是支援的,git的怎麼搞? 解決方案: 附上下載好的外掛:  multiple-scms.hpi Jenkins

iOS專案中引用第三方引發衝突的解決方法

這個真蛋疼~~~~ 解決方法如下: iOS程式開發過程中引用多個第三方庫時會出現類名重疊,導致衝突,具體的衝突錯誤提示如下: duplicate symbol OBJC_IVAR$_AFHTTPSessionManager._requestSerializer in: