1. 程式人生 > >mongodb 【多資料來源配置】

mongodb 【多資料來源配置】

mongodb 多資料來源配置

  • 配置檔案

application.properties

        
    # mongdb1
    spring.data.mongodb.one.uri=mongodb://localhost:27017/dao
    
    
    
    # mongdb2
    spring.data.mongodb.two.uri=mongodb://localhost:27017/Xu?replicaSet=mgset-5031831
    
    #mongodb://[username:[email protected]]host1[:port1][,host2[:port2],…[,hostN[:portN]]][/[database][?options]]


  • 配置程式碼,設定動態資料來源

MongoConfig.java

    
    package com.dao.mongdb.config;
    
    import com.mongodb.MongoClientURI;
    import org.springframework.beans.factory.annotation.Value;
    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.MongoTemplate; import org.springframework.data.mongodb.core.SimpleMongoDbFactory; import org.springframework.data.mongodb.core.
convert.DefaultDbRefResolver; import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import java.net.UnknownHostException; /** * 去掉預設儲存的_class,節約記憶體 * * @author 阿導 * @version BUILD1001 * @fileName com.bxm.datapark.service.mongo.mongo.Test.java * @CopyRright (c) 2017-bxm:萬物皆導 * @created 2018-01-05 11:39:00 * @modifier 阿導 * @updated 2018-01-05 11:39:00 * */ @Configuration public class MongoConfig { /** * 自動注入第一個 mongondb */ @Value("${spring.data.mongodb.one.uri}") private String MONGO_URI; /** * 自動注入第二個 mongondb */ @Value("${spring.data.mongodb.two.uri}") private String MONGO_URI2; // ===================== 連線到 mongodb 伺服器 ================================= @Bean @Primary public MongoMappingContext mongoMappingContext() { MongoMappingContext mappingContext = new MongoMappingContext(); return mappingContext; } /** * 使用自定義的typeMapper去除寫入mongodb時的“_class”欄位 * * @return * @throws Exception */ @Bean @Primary public MappingMongoConverter mappingMongoConverter() throws Exception { DefaultDbRefResolver dbRefResolver = new DefaultDbRefResolver(this.dbFactory()); MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, this.mongoMappingContext()); converter.setTypeMapper(new DefaultMongoTypeMapper(null)); return converter; } @Bean @Primary public MongoDbFactory dbFactory() throws UnknownHostException { return new SimpleMongoDbFactory(new MongoClientURI(MONGO_URI)); } @Bean @Primary public MongoTemplate mongoTemplate() throws Exception { return new MongoTemplate(dbFactory(), this.mappingMongoConverter()); } // ==================== 連線到 mongodb2 伺服器 ====================================== @Bean public MongoMappingContext mongoMappingContext2() { MongoMappingContext mappingContext = new MongoMappingContext(); return mappingContext; } /** * 使用自定義的typeMapper去除寫入mongodb時的“_class”欄位 * * @return * @throws Exception */ @Bean public MappingMongoConverter mappingMongoConverter2() throws Exception { DefaultDbRefResolver dbRefResolver = new DefaultDbRefResolver(this.dbFactory2()); MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, this.mongoMappingContext2()); converter.setTypeMapper(new DefaultMongoTypeMapper(null)); return converter; } @Bean public MongoDbFactory dbFactory2() throws UnknownHostException { return new SimpleMongoDbFactory(new MongoClientURI(MONGO_URI2)); } @Bean public MongoTemplate mongoTemplate2() throws Exception { return new MongoTemplate(this.dbFactory2(), this.mappingMongoConverter2()); } }
  • 抽象類做原型,複用資料訪問層

MongoCommonDao.java

    
    package com.dao.mongdb.base;
    
    import org.springframework.data.mongodb.core.MongoTemplate;
    import org.springframework.data.mongodb.core.aggregation.Aggregation;
    import org.springframework.data.mongodb.core.aggregation.AggregationResults;
    import org.springframework.data.mongodb.core.aggregation.GroupOperation;
    import org.springframework.data.mongodb.core.aggregation.MatchOperation;
    import org.springframework.data.mongodb.core.query.Query;
    import org.springframework.data.mongodb.core.query.Update;
    
    import java.util.List;
    
    
    /**
     * @author 阿導
     * @version BUILD1001
     * @fileName com.dao.base.mongoutil.Page.java
     * @CopyRright (c) 2017-bxm:萬物皆導
     * @created 2018-01-05 16:03:00
     * @modifier 阿導
     * @updated 2018-01-05 16:03:00
     * @description
     */
    public abstract class MongoCommonDao<T> {
    
        /**
         * 預設分頁資訊
         */
        private static final int DEFAULT_SKIP = 0;
        private static final int DEFAULT_LIMIT = 100;
    
        /**
         * spring-mongodb 整合操作類
         * <p>
         * 作為一個工具類,防止注入失敗導致無法解決後續問題,所以由子類自動注入
         */
        protected MongoTemplate mongoTemplate;
    
        /**
         * 通過條件查詢實體(集合), 只能指定條件,集合名預設為實體類
         *
         * @param query
         * @return java.util.List<T>
         * @author 阿導
         * @time 2018-01-05
         * @CopyRight 萬物皆導
         */
    
        public List<T> find(Query query) {
            return mongoTemplate.find(query, this.getEntityClass());
        }
    
        /**
         * 通過條件查詢實體(集合),可以指定條件和集合名
         *
         * @param query
         * @param collectionName
         * @return java.util.List<T>
         * @author 阿導
         * @time 2018-01-05
         * @CopyRight 萬物皆導
         */
    
        public List<T> find(Query query, String collectionName) {
            return mongoTemplate.find(query, this.getEntityClass(), collectionName);
        }
    
        /**
         * 通過條件查詢實體(集合),可以指定條件和集合名以及返回集合實體類
         *
         * @param query
         * @param clazz
         * @param collectionName
         * @return java.util.List<T>
         * @author 阿導
         * @time 2018-01-05
         * @CopyRight 萬物皆導
         */
    
        public List<?> find(Query query, Class<?> clazz, String collectionName) {
            return mongoTemplate.find(query, clazz, collectionName);
        }
    
        /**
         * 通過一定的條件查詢一個實體,只能指定條件,集合名預設為實體類
         *
         * @param query
         * @return T
         * @author 阿導
         * @time 2018-01-05
         * @CopyRight 萬物皆導
         */
    
        public T findOne(Query query) {
            return mongoTemplate.findOne(query, this.getEntityClass());
        }
    
        /**
         * 可以指定條件和集合名以及返回集合實體類
         *
         * @param query
         * @param collectionName
         * @return T
         * @author 阿導
         * @time 2018-01-05
         * @CopyRight 萬物皆導
         */
    
        public T findOne(Query query, String collectionName) {
            return mongoTemplate.findOne(query, this.getEntityClass(), collectionName);
        }
    
        /**
         * 可以指定條件和集合名以及返回集合實體類
         *
         * @param query
         * @param clazz
         * @param collectionName
         * @return java.lang.Object
         * @author 阿導
         * @time 2018-01-05
         * @CopyRight 萬物皆導
         */
    
        public Object findOne(Query query, Class<?> clazz, String collectionName) {
            return mongoTemplate.findOne(query, clazz, collectionName);
        }
    
        /**
         * 通過條件查詢更新資料,
         *
         * @param query
         * @param update
         * @return void
         * @author 阿導
         * @time 2018-01-05
         * @CopyRight 萬物皆導
         */
    
        public void update(Query query, Update update) {
            mongoTemplate.findAndModify(query, update, this.getEntityClass());
        }
    
        /**
         * 通過條件查詢更新資料,可以指定集合名
         *
         * @param query
         * @param update
         * @param collectionName
         * @return void
         * @author 阿導
         * @time 2018-01-05
         * @CopyRight 萬物皆導
         */
    
        public void update(Query query, Update update, String collectionName) {
            mongoTemplate.findAndModify(query, update, this.getEntityClass(), collectionName);
        }
    
        /**
         * 通過條件查詢更新資料,可以指定集合名和類名(主要獲取其屬性名稱)
         *
         * @param query
         * @param update
         * @param clazz
         * @param collectionName
         * @return void
         * @author 阿導
         * @time 2018-01-05
         * @CopyRight 萬物皆導
         */
    
        public void update(Query query, Update update, Class<?> clazz, String collectionName) {
            mongoTemplate.findAndModify(query, update, clazz, collectionName);
        }
    
        /**
         * 儲存一個物件到mongodb
         *
         * @param entity
         * @return T
         * @author 阿導
         * @time 2018-01-05
         * @CopyRight 萬物皆導
         */
    
        public T save(T entity) {
            mongoTemplate.insert(entity);
            return entity;
        }
    
        /**
         * 儲存一個物件到mongodb(可以指定儲存到的集合名稱)
         *
         * @param entity
         * @param collectionName
         * @return T
         * @author 阿導
         * @time 2018-01-05
         * @CopyRight 萬物皆導
         */
    
        public T save(T entity, String collectionName) {
            mongoTemplate.insert(entity, collectionName);
            return entity;
        }
    
        /**
         * 批量新增
         *
         * @param t
         * @param collectionName
         * @return void
         * @author 阿導
         * @time 2018/1/9
         * @CopyRight 萬物皆導
         */
        public void saveBatch(List<T> t, String collectionName) {
            mongoTemplate.insert(t, collectionName);
        }
    
        /**
         * 按條件刪除
         *
         * @param query
         * @param collectionName
         * @return void
         * @author 阿導
         * @time 2018/1/9
         * @CopyRight 萬物皆導
         */
        public void remove(Query query, String collectionName) {
            if (mongoTemplate.exists(query, collectionName)) {
                mongoTemplate.remove(query, collectionName);
            }
        }
    
        /**
         * 刪除資料集
         *
         * @author 阿導
         * @time 2018/1/9
         * @CopyRight 萬物皆導
         * @param collectionName
         * @return void
         */
        public void drop(String collectionName) {
            mongoTemplate.dropCollection(collectionName);
        }
    
    
        /**
         * 通過ID獲取記錄
         *
         * @param id
         * @return T
         * @author 阿導
         * @time 2018-01-05
         * @CopyRight 萬物皆導
         */
    
        public T findById(String id) {
            return mongoTemplate.findById(id, this.getEntityClass());
        }
    
        /**
         * 通過ID獲取記錄,並且指定了集合名(表的意思)
         *
         * @param id
         * @param collectionName
         * @return T
         * @author 阿導
         * @time 2018-01-05
         * @CopyRight 萬物皆導
         */
    
        public T findById(String id, String collectionName) {
            return mongoTemplate.findById(id, this.getEntityClass(), collectionName);
        }
    
        /**
         * 分頁查詢
         *
         * @param pageNum
         * @param pageSize
         * @param query
         * @return com.dao.base.mongoutil.Page<T>
         * @author 阿導
         * @time 2018-01-05
         * @CopyRight 萬物皆導
         */
    
        public Page<T> findPage(Integer pageNum, Integer pageSize, Query query) {
            //獲取分頁總數
            Long total = this.count(query);
    
            //分頁資訊處理
            if (pageNum == null || pageSize == null) {
                query.skip(DEFAULT_SKIP);
            } else {
                query.skip((pageNum - 1) * pageSize);
            }
            if (pageSize == null) {
                query.limit(DEFAULT_LIMIT);
            } else {
                query.limit(pageSize);
            }
            //將查詢的資料設定進集合
            return new Page<T>(this.find(query), pageNum, pageSize, total);
        }
    
        /**
         * 分頁查詢
         *
         * @param pageNum
         * @param pageSize
         * @param query
         * @param collectionName
         * @return com.dao.base.mongoutil.Page<T>
         * @author 阿導
         * @time 2018-01-05
         * @CopyRight 萬物皆導
         */
        public Page<T> findPage(Integer pageNum, Integer pageSize, Query query,String collectionName) {
            //獲取分頁總數
            Long total = this.count(query,collectionName);
    
            //分頁資訊處理
            if (pageNum == null || pageSize == null) {
                query.skip(DEFAULT_SKIP);
            } else {
                query.skip((pageNum - 1) * pageSize);
            }
            if (pageSize == null) {
                query.limit(DEFAULT_LIMIT);
            } else {
                query.limit(pageSize);
            }
            //將查詢的資料設定進集合
            return new Page<T>(this.find(query,collectionName), pageNum, pageSize, total);
        }
        /**
         * @param query
         * @return long
         * @description
         * @author 阿導
         * @time 2018-01-05
         * @CopyRight 萬物皆導
         */
    
        public long count(Query query) {
            return mongoTemplate.count(query, this.getEntityClass());
        }
        public long count(Query query,String collectionName) {
            return mongoTemplate.count(query, this.getEntityClass(),collectionName);
        }
    
        /**
         * 分組統計
         *
         * @param collectionName 資料集名稱
         * @param match          條件注入
         * @param group          分組資訊
         * @return java.util.List<T>
         * @author 阿導
         * @time 2018/1/6
         * @CopyRight 萬物皆導
         */
        public List<T> sum(String collectionName, MatchOperation match, GroupOperation group) {
            // Aggregation.match(Criteria.where("oid").is(orderId))
            // Aggregation.group("userName").sum("flowSize").as("tatoalFlowSize").sum("amount").as("totalAmount")
            Aggregation aggregation = Aggregation.newAggregation(match, group);
            AggregationResults<T> aggRes = mongoTemplate.aggregate(aggregation,
                    collectionName, this.getEntityClass());
            return aggRes.getMappedResults();
        }
    
    //    public Page<T> pageSum(String collectionName, MatchOperation match, GroupOperation group, SortOperation sort, Integer pageNum, Integer pageSize){
    //        Aggregation aggregation = Aggregation.newAggregation(match,group,sort, Aggregation.skip(pageNum>1?(pageNum-1)*pageSize:0),Aggregation.limit(pageSize));
    //        AggregationResults<T> aggRes = mongoTemplate.aggregate(aggregation,collectionName, this.getEntityClass());
    //        //將查詢的資料設定進集合
    //        return new Page<T>(aggRes.getMappedResults()  , pageNum,pageSize,);
    //    }
    
    
        /**
         * 獲取需要操作的實體類class
         *
         * @return
         */
        private Class<T> getEntityClass() {
            return ReflectionUtils.getSuperClassGenricType(getClass());
        }
    
        /**
         * 注入mongodbTemplate
         *
         * @param mongoTemplate
         */
        protected abstract void setMongoTemplate(MongoTemplate mongoTemplate);
    
        public MongoTemplate getMongoTemplate() {
            return mongoTemplate;
        }
    }



  • 反射工具類

ReflectionUtils.java

    
    package com.dao.mongdb.base;
    
    import org.apache.commons.lang3.StringUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.util.Assert;
    
    import java.lang.reflect.*;
    
    /** 
     * 反射工具類. 
     *  
     * 提供訪問私有變數,獲取泛型型別Class, 提取集合中元素的屬性, 轉換字串到物件等Util函式. 
     *  
     */  
    public class ReflectionUtils {  
      
        private static Logger logger = LoggerFactory.getLogger(ReflectionUtils.class);
      
        /** 
         * 呼叫Getter方法. 
         */  
        public static Object invokeGetterMethod(Object obj, String propertyName) {  
            String getterMethodName = "get" + StringUtils.capitalize(propertyName);
            return invokeMethod(obj, getterMethodName, new Class[] {}, new Object[] {});  
        }  
      
        /** 
         * 呼叫Setter方法.使用value的Class來查詢Setter方法. 
         */  
        public static void invokeSetterMethod(Object obj, String propertyName, Object value) {  
            invokeSetterMethod(obj, propertyName, value, null);  
        }  
      
        /** 
         * 呼叫Setter方法. 
         *  
         * @param propertyType 用於查詢Setter方法,為空時使用value的Class替代. 
         */  
        public static void invokeSetterMethod(Object obj, String propertyName, Object value, Class<?> propertyType) {  
            Class<?> type = propertyType != null ? propertyType : value.getClass();  
            String setterMethodName = "set" + StringUtils.capitalize(propertyName);  
            invokeMethod(obj, setterMethodName, new Class[] { type }, new Object[] { value });  
        }  
      
        /** 
         * 直接讀取物件屬性值, 無視private/protected修飾符, 不經過getter函式. 
         */  
        public static Object getFieldValue(final Object obj, final String fieldName) {  
            Field field = getAccessibleField