import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.mongodb.client.ListIndexesIterable; import com.mongodb.client.model.IndexOptions; import com.mongodb.client.model.Indexes; import org.bson.Document; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoTemplate; 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.ObjectUtils; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * @author ming * @date 27/12/2019 上午 11:21 * @desc MongoDB 操作工具類 */ @Component public class MongoDBHelper<T> { /** * 注入template */ @Autowired private MongoTemplate mongoTemplate; /** * 功能描述: 創建一個集合 * 同一個集合中可以存入多個不同類型的對象,我們為了方便維護和提升性能, * 后續將限制一個集合中存入的對象類型,即一個集合只能存放一個類型的數據 * * @param name 集合名稱,相當於傳統數據庫的表名 * @return:void */ public void createCollection(String name) { mongoTemplate.createCollection(name); } /** * 功能描述: 創建索引 * 索引是順序排列,且唯一的索引 * * @param collectionName 集合名稱,相當於關系型數據庫中的表名 * @param filedName 對象中的某個屬性名 * @return:java.lang.String */ public String createIndex(String collectionName, String filedName) { //配置索引選項 IndexOptions options = new IndexOptions(); // 設置為唯一 options.unique(true); //創建按filedName升序排的索引 return mongoTemplate.getCollection(collectionName).createIndex(Indexes.ascending(filedName), options); } /** * 功能描述: 獲取當前集合對應的所有索引的名稱 * * @param collectionName * @return:java.util.List<java.lang.String> */ public List<String> getAllIndexes(String collectionName) { ListIndexesIterable<Document> list = mongoTemplate.getCollection(collectionName).listIndexes(); //上面的list不能直接獲取size,因此初始化arrayList就不設置初始化大小了 List<String> indexes = new ArrayList<>(); for (org.bson.Document document : list) { document.entrySet().forEach((key) -> { //提取出索引的名稱 if (key.getKey().equals("name")) { indexes.add(key.getValue().toString()); } }); } return indexes; } /** * 功能描述: 往對應的集合中插入一條數據 * * @param info 存儲對象 * @param collectionName 集合名稱 * @return:void */ public void insert(T info, String collectionName) { mongoTemplate.insert(info, collectionName); } /** * 功能描述: 往對應的集合中批量插入數據,注意批量的數據中不要包含重復的id * * @param infos 對象列表 * @return:void */ public void insertMulti(List<T> infos, String collectionName) { mongoTemplate.insert(infos, collectionName); } /** * 功能描述: 使用索引信息精確更改某條數據 * * @param id 唯一鍵 * @param collectionName 集合名稱 * @param info 待更新的內容 * @return:void */ public void updateById(String id, String collectionName, T info) { Query query = new Query(Criteria.where("id").is(id)); Update update = new Update(); String str = JSON.toJSONString(info); JSONObject jQuery = JSON.parseObject(str); jQuery.forEach((key, value) -> { //因為id相當於傳統數據庫中的主鍵,這里使用時就不支持更新,所以需要剔除掉 if (!key.equals("id")) { update.set(key, value); } }); mongoTemplate.updateMulti(query, update, info.getClass(), collectionName); } /** * 功能描述: 根據id刪除集合中的內容 * * @param id 序列id * @param collectionName 集合名稱 * @param clazz 集合中對象的類型 * @return:void */ public void deleteById(String id, Class<T> clazz, String collectionName) { // 設置查詢條件,當id=#{id} Query query = new Query(Criteria.where("id").is(id)); // mongodb在刪除對象的時候會判斷對象類型,如果你不傳入對象類型,只傳入了集合名稱,它是找不到的 // 上面我們為了方便管理和提升后續處理的性能,將一個集合限制了一個對象類型,所以需要自行管理一下對象類型 // 在接口傳入時需要同時傳入對象類型 mongoTemplate.remove(query, clazz, collectionName); } /** * 功能描述: 根據id查詢信息 * * @param id 注解 * @param clazz 類型 * @param collectionName 集合名稱 * @return:java.util.List<T> */ public T selectById(String id, Class<T> clazz, String collectionName) { // 查詢對象的時候,不僅需要傳入id這個唯一鍵,還需要傳入對象的類型,以及集合的名稱 return mongoTemplate.findById(id, clazz, collectionName); } /** * 功能描述: 查詢列表信息 * 將集合中符合對象類型的數據全部查詢出來 * * @param collectName 集合名稱 * @param clazz 類型 * @return:java.util.List<T> */ public List<T> selectList(String collectName, Class<T> clazz) { return selectList(collectName, clazz, null, null); } /** * 功能描述: 分頁查詢列表信息 * * @param collectName 集合名稱 * @param clazz 對象類型 * @param currentPage 當前頁碼 * @param pageSize 分頁大小 * @return:java.util.List<T> */ public List<T> selectList(String collectName, Class<T> clazz, Integer currentPage, Integer pageSize) { //設置分頁參數 Query query = new Query(); //設置分頁信息 if (!ObjectUtils.isEmpty(currentPage) && ObjectUtils.isEmpty(pageSize)) { query.limit(pageSize); query.skip(pageSize * (currentPage - 1)); } return mongoTemplate.find(query, clazz, collectName); } /** * 功能描述: 根據條件查詢集合 * * @param collectName 集合名稱 * @param conditions 查詢條件,目前查詢條件處理的比較簡單,僅僅做了相等匹配,沒有做模糊查詢等復雜匹配 * @param clazz 對象類型 * @param currentPage 當前頁碼 * @param pageSize 分頁大小 * @return:java.util.List<T> */ public List<T> selectByCondition(String collectName, Map<String, String> conditions, Class<T> clazz, Integer currentPage, Integer pageSize) { if (ObjectUtils.isEmpty(conditions)) { return selectList(collectName, clazz, currentPage, pageSize); } else { //設置分頁參數 Query query = new Query(); query.limit(pageSize); query.skip(currentPage); // 往query中注入查詢條件 conditions.forEach((key, value) -> query.addCriteria(Criteria.where(key).is(value))); return mongoTemplate.find(query, clazz, collectName); } } /** * 功能描述: 根據條件查詢集合 * @param collectName 集合名稱 * @param query 查詢條件 * @param clazz 對象類型 * @return */ public List<T> selectByQuery(String collectName,Query query,Class<T> clazz){ List<T> result= mongoTemplate.find(query,clazz,collectName); return result; } }