此工具類封裝了一些常用的操作mongodb的方法,例如:添加索引、文檔、範圍查詢、條件查詢、排序……
package org.magic.mongo.utils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import javax.annotation.PostConstruct;
import org.magic.mongo.entiy.PageModel;
import org.magic.mongo.entiy.Phone;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.GroupOperation;
import org.springframework.data.mongodb.core.aggregation.MatchOperation;
import org.springframework.data.mongodb.core.index.Index;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
/**
* @author wuguantongyang
*/
@Component
public class MongodbUtil {
public static MongodbUtil mongodbUtil;
@PostConstruct
public void init() {
mongodbUtil = this;
mongodbUtil.mongoTemplate = this.mongoTemplate;
}
@Autowired
private MongoTemplate mongoTemplate;
/**
* 保存對象List到指定集合中
* <p>
* 也可以在實體類上使用@Document(collection=“集合名稱”)指定集合名稱,未指定則默認實體類的類名爲集合名稱
*
* @param entiys
*/
public static void saveAll(String collName, List<?> entiys) {
for (Object entiy : entiys) {
saveData(collName, entiy);
}
}
/**
* 保存單個對象到指定集合中
*
* @param collName 集合名稱
* @param entiy 實體名稱
*/
public static void saveOne(String collName, Class<?> entiy) {
saveData(collName, entiy);
}
/**
* 根據id倒序查詢 集合中的數據
*
* @param entiy 數據實體
* @param collName 集合名稱
* @param direction 倒序/正序 Direction.DESC/ASC
* @param
*/
public static Object findSortById(Class<?> entiy, String collName, Sort.Direction direction) {
Query query = new Query().with(Sort.by(direction, "id"));
return mongodbUtil.mongoTemplate.find(query, entiy, collName);
}
/**
* 查詢返回指定字段
*
* @param fields 需要返回的指定字段
* @param clazz 數據實體類class
* @param collName 集合名稱
* @param map Map<查詢條件key,查詢條件value>
* <p>
* 返回字段的時候id默認爲返回,不返回id則field設置 fieldObj.put("id",false)
* @return
*/
public static Object findDesignField(List<String> fields, Map<String, Object> map, Class<?> clazz, String collName, boolean returnId) {
Criteria criteria = null;
if (map.containsKey(null)) {
return "查詢條件key不能爲Null~";
}
for (String key : map.keySet()) {
criteria = Criteria.where(key).is(map.get(key));
}
Query query = new Query(criteria);
for (String field : fields) {
query.fields().include(field);
}
if (!returnId) {
query.fields().exclude("id");
}
return mongodbUtil.mongoTemplate.find(query, clazz, collName);
}
/**
* 查詢指定集合中的所有數據
*
* @param entiy 數據實體類
* @param collName 集合名稱
*/
public static Object findAll(Class<?> entiy, String collName) {
return mongodbUtil.mongoTemplate.findAll(entiy, collName);
}
/**
* 模糊查詢 根據 key 可以到 collName 中進行模糊查詢 並排序
*
* @param param 匹配的參數
* @param collName 集合名稱
* @param direction Direction.desc /asc 倒序/正序
* @param sortField 排序字段
* @return
*/
public static Object findLikeByParam(String param, String collName, String sortField, Sort.Direction direction) {
Pattern pattern = Pattern.compile("^.*" + param + ".*$", Pattern.CASE_INSENSITIVE);
Query query = new Query(Criteria.where("name").regex(pattern)).with(Sort.by(direction, sortField));
return mongodbUtil.mongoTemplate.find(query, Phone.class, collName);
}
/**
* 向指定集合設置索引
*
* @param collName 集合名稱
* @param indexName 索引名稱
* @param map map.put("添加索引的字段",Direction.ASC/DESC)
*/
public static void createIndex(String collName, String indexName, Map<String, Sort.Direction> map) throws Exception {
if (map.containsKey(null)) {
throw new Exception("添加索引的字段不能爲null");
}
Index index = new Index().named(indexName);
for (String key : map.keySet()) {
index.on(key, map.get(key));
}
mongodbUtil.mongoTemplate.indexOps(collName).ensureIndex(index);
}
/**
* 獲取指定集合中的索引信息
*
* @param collName 集合名稱
* @return
*/
public static Object getIndexInfo(String collName) {
return mongodbUtil.mongoTemplate.indexOps(collName).getIndexInfo();
}
/**
* 根據索引名稱刪除索引
*
* @param indexName 索引名稱
* @param collName 集合名稱
*/
public static void removeIndexByName(String collName, String indexName) {
mongodbUtil.mongoTemplate.indexOps(collName).dropIndex(indexName);
}
/**
* 刪除指定集合中得所有索引
*
* @param collName 集合名稱
*/
public static void removeIndexByName(String collName) {
mongodbUtil.mongoTemplate.indexOps(collName).dropAllIndexes();
}
/**
* 根據指定key 和value到指定collName集合中刪除數據
*
* @param key
* @param value
* @param collName
*/
public static void removeAllByParam(String key, String value, String collName) {
Criteria criteria = Criteria.where(key).is(value);
Query query = Query.query(criteria);
mongodbUtil.mongoTemplate.remove(query, collName);
}
/**
* 根據指定條件查詢 並排序
*
* @param obj 數據對象
* @param map Map<"查詢條件key",查詢條件值> map
* @param collName 集合名稱
* @return
*/
public static List<? extends Object> findSortByParam(Object obj, String collName, Map<String, Object> map, String sortField, Sort.Direction direction) {
if (map.containsKey(null)) {
return new ArrayList<>();
}
Criteria criteria = null;
criteria = getCriteria(criteria, map);
if (criteria == null) {
return new ArrayList<>();
}
Query query = Query.query(criteria).with(Sort.by(direction, sortField));
return mongodbUtil.mongoTemplate.find(query, obj.getClass(), collName);
}
/**
* 範圍查詢
* <p>
* 查詢大於等於begin 小於等於end範圍內條件匹配得數據並排序
*
* @param obj 數據對象
* @param collName 集合名稱
* @param map Map<"查詢條件key",查詢條件值> map
* @param sortField 排序字段
* @param direction 排序方式 Direction.asc / Direction.desc
* @param rangeCriteria 示例: lt小於 lte 小於等於 gt大於 gte大於等於 eq等於 ne不等於
* <p>
* Criteria rangeCriteria=Criteria.where("createDate").gte(begin).lte(end));
* <p>
* createDate:數據庫中的時間字段,gegin:起始時間 end:結束時間
* @return
*/
public static List<? extends Object> findRangeByParam(Object obj, String collName, Map<String, Object> map,
String sortField, Sort.Direction direction, Criteria rangeCriteria) {
if (map.containsKey(null)) {
return new ArrayList<>();
}
Criteria criteria = null;
criteria = getCriteria(criteria, map);
if (criteria == null) {
return new ArrayList<>();
}
Query query = new Query().addCriteria(rangeCriteria).addCriteria(criteria).with(Sort.by(direction, sortField));
return mongodbUtil.mongoTemplate.find(query, obj.getClass(), collName);
}
/**
* 根據指定key value到指定集合中查詢匹配得數量
*
* @param collName
* @param key
* @param value
* @return
*/
public static long count(String collName, String key, String value) {
Query query = Query.query(Criteria.where(key).is(value));
return mongodbUtil.mongoTemplate.count(query, "goods");
}
/**
* 在指定範圍內查詢匹配條件的數量
*
* @param clazz 數據實體類
* @param collName 集合名稱
* @param map 查詢條件map
* @param rangeCriteria 範圍條件 Criteria rangeCriteria= Criteria.where("數據庫字段").gt/gte(起始範圍).lt/lte(結束範圍)
* @return
*/
public static Long countRangeCondition(Class<?> clazz, String collName, Criteria rangeCriteria, Map<String, Object> map) {
Criteria criteria = null;
if (map.containsKey(null)) {
return null;
}
for (String key : map.keySet()) {
criteria = Criteria.where(key).is(map.get(key));
}
Query query = new Query();
if (criteria != null) {
query.addCriteria(criteria);
}
query.addCriteria(rangeCriteria);
return mongodbUtil.mongoTemplate.count(query, clazz, collName);
}
/**
* 指定集合 根據條件查詢出符合的第一條數據
*
* @param entiy 數據對象
* @param map 條件map Map<條件key,條件value> map
* @param collectionName 集合名
* @return
*/
public static Object findSortFirst(Class<?> entiy, Map<String, Object> map, String collectionName, String field, Sort.Direction direction) {
if (map.containsKey(null)) {
return "查詢條件不能爲null~";
}
Criteria criteria = null;
criteria = getCriteria(criteria, map);
Query query = Query.query(criteria).with(Sort.by(direction, field));
return mongodbUtil.mongoTemplate.findOne(query, entiy, collectionName);
}
/**
* 指定集合 修改數據,且修改所找到的所有數據
*
* @param accordingKey 修改條件 key
* @param accordingValue 修改條件 value
* @param map Map<修改內容 key數組,修改內容 value數組>
* @param collName 集合名
* @param type 修改操作類型 1:修改第一條數據 0:修改所有匹配得數據
*/
public static void updateMulti(String accordingKey, Object accordingValue, Map<String, Object> map,
String collName, Integer type) {
if (map.containsKey(null)) {
return;
}
Criteria criteria = Criteria.where(accordingKey).is(accordingValue);
Query query = Query.query(criteria);
Update update = new Update();
for (String key : map.keySet()) {
update.set(key, map.get(key));
}
if (type == 1) {
mongodbUtil.mongoTemplate.updateFirst(query, update, collName);
} else {
mongodbUtil.mongoTemplate.updateMulti(query, update, collName);
}
}
/**
* 對某字段做sum求和
*
* @param clazz 數據實體類
* @param map Map<查詢條件key,查詢條件value> map
* @param collName 集合名稱
* @param sumField 求和字段
* @param rangeCriteria 範圍條件
* @return Criteria rangeCriteria = Criteria.where(字段).gt(起始範圍).lt(結束範圍)
*/
public static Object findSum(Class<?> clazz, Map<String, Object> map, String collName, String sumField, Criteria rangeCriteria) {
if (map.containsKey(null)) {
return "查詢條件key不能爲Null";
}
Criteria criteria = null;
MatchOperation match = null;
for (String key : map.keySet()) {
criteria = Criteria.where(key).is(map.get(key));
}
if (criteria != null) {
match = Aggregation.match(criteria);
}
GroupOperation count = Aggregation.group().sum(sumField).as(sumField);
return mongodbUtil.mongoTemplate.aggregate(Aggregation.newAggregation(match, count), collName, clazz).getMappedResults();
}
/**
* 分頁查詢
*
* @param entiy 數據實體類
* @param collName 集合名稱
* @param map Map<"查詢條件key",查詢條件值> map 若 keys/values 爲null,則查詢集合中所有數據
* @param pageNo 當前頁
* @param pageSize 當前頁數據條數
* @param direction Direction.Desc/ASC 排序方式
* @param sortField 排序字段
* @return
*/
public static PageModel findSortPageCondition(Class<?> entiy, String collName, Map<String, Object> map,
int pageNo, int pageSize, Sort.Direction direction, String sortField) {
Criteria criteria = getCriteria(new Criteria(), map);
long count;
if (criteria == null) {
count = mongodbUtil.mongoTemplate.count(new Query(), entiy, collName);
} else {
count = mongodbUtil.mongoTemplate.count(new Query(criteria), entiy, collName);
}
int pages = (int) Math.ceil((double) count / (double) pageSize);
if (pageNo <= 0 || pageNo > pages) {
pageNo = 1;
}
int skip = pageSize * (pageNo - 1);
Query query = new Query().skip(skip).limit(pageSize);
query.with(Sort.by(direction, sortField));
if (criteria != null) {
query.addCriteria(criteria);
}
List<?> list = mongodbUtil.mongoTemplate.find(query, entiy, collName);
PageModel pageModel = new PageModel();
pageModel.setPageNo(pageNo);
pageModel.setPagesize(pageSize);
pageModel.setTotal(count);
pageModel.setPages(pages);
pageModel.setList(list);
return pageModel;
}
private static void saveData(String collName, Object entiy) {
if (StringUtils.isEmpty(collName)) {
mongodbUtil.mongoTemplate.save(entiy);
} else {
mongodbUtil.mongoTemplate.save(entiy, collName);
}
}
private static Criteria getCriteria(Criteria criteria, Map<String, Object> map) {
if (map == null) {
return null;
}
int i = 0;
for (String key : map.keySet()) {
if (i == 0) {
criteria = Criteria.where(key).is(map.get(key));
i++;
} else {
criteria.and(key).is(map.get(key));
}
}
return criteria;
}
}
工具類中會用到的分頁實體類:
package org.magic.mongo.entiy;
import java.io.Serializable;
import java.util.List;
/**
* @author wuguantongyang
*/
public class PageModel implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 當前頁
*/
private Integer pageNo = 1;
/**
* 當前頁條數
*/
private Integer pagesize = 10;
/**
* 總共的條數
*/
private Long total;
/**
* 總共的頁數
*/
private Integer pages;
/**
* 實體類集合
*/
private List<?> list;
public Integer getPageNo() {
return pageNo;
}
public void setPageNo(Integer pageNo) {
this.pageNo = pageNo;
}
public Integer getPagesize() {
return pagesize;
}
public void setPagesize(Integer pagesize) {
this.pagesize = pagesize;
}
public Long getTotal() {
return total;
}
/**
* 總數由0開始計數
* @param total
*/
public void setTotal(Long total) {
this.total = total + 1;
}
public Integer getPages() {
return pages;
}
public void setPages(Integer pages) {
this.pages = pages;
}
public List<?> getList() {
return list;
}
public void setList(List<?> list) {
this.list = list;
}
public PageModel(Integer pageNo, Integer pagesize, Long total, Integer pages, List<?> list) {
this.pageNo = pageNo;
this.pagesize = pagesize;
this.total = total;
this.pages = pages;
this.list = list;
}
public PageModel() {
}
@Override
public String toString() {
return "PageModel{" +
"pageNo=" + pageNo +
", pagesize=" + pagesize +
", total=" + total +
", pages=" + pages +
", list=" + list +
'}';
}
}
有了這兩個類,就可以在ApplicationTest
中進行測試了,目前想到的可能會用到的功能就這些,封裝簡陋,不足之處望指正。