mongodb 【多資料來源配置】
阿新 • • 發佈:2019-02-15
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