轉載:http://www.cnblogs.com/dennisit/p/3374297.html
開發環境:
操作系統:windows xp
Mongodb:2.0.6
依 賴 包:Spring3.2.2 + spring-data-mongodb-1.3.0 + Spring-data-1.5 + mongodb2.7.3
說 明:Springmvc整合Mongodb的時候建議選擇穩定版的Spring-data-mongdb。Mongodb1.0.1中存在數據映射bug.所以使用1.3.0.
項目結構圖:
說明:
持久層操作使用MongoTemplate類操作.實現將對象與Mongodb庫中的數據交互操作.
這里需要說明的是我的實體對象中的id屬性對應的是庫中記錄中的_id屬性.
Mongodb與SpringMVC整合參見文檔: http://www.cnblogs.com/dennisit/p/3372568.html
Mongodb的高級操作:
添加對象到數據庫
/** * 保存一個對象 * * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-10-13 下午03:37:28 * * @param t * @return */ public void save(T t){ log.info("[Mongo Dao ]save:" + t); this.mongoTemplate.save(t); }
根據Id從庫中查詢對象
/** * 根據Id從Collection中查詢對象 * * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-10-17 下午01:59:55 * * @param id * 實體對象的Id,對應Collection中記錄的_id字段. * <p> * 需要說明的是,Mongdo自身沒有主鍵自增機制.解決方法 * <ol> * <li>實體入庫的時候,程序中為實體賦主鍵值. * <li>實體入庫的時候,在mongodb中自定義函數實現主鍵自增機制.定義方法同js代碼類似 * </ol> * </p> * @return */ public T queryById(String id) { Query query = new Query(); Criteria criteria = Criteria.where("_id").is(id); query.addCriteria(criteria); log.info("[Mongo Dao ]queryById:" + query); return this.mongoTemplate.findOne(query, this.getEntityClass()); }
根據條件從庫中查詢
/** * 根據條件查詢集合 * * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-10-13 下午03:32:54 * * @param query * 查詢條件 * @return * 滿足條件的集合 */ public List<T> queryList(Query query){ log.info("[Mongo Dao ]queryList:" + query); return this.mongoTemplate.find(query, this.getEntityClass()); }
根據條件查詢單個記錄
/** * 通過條件查詢單個實體 * * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-10-13 下午03:33:12 * * @param query * @return */ public T queryOne(Query query){ log.info("[Mongo Dao ]queryOne:" + query); return this.mongoTemplate.findOne(query, this.getEntityClass()); }
說明:查詢單個用的是mongoTemplate.findOne方法,查詢多條的用的是mongoTemplate.find.
分頁查詢操作
/** * 通過條件進行分頁查詢 * * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-10-13 下午03:33:30 * * @param query * 查詢條件 * @param start * 查詢起始值 * <strong> 類似mysql查詢中的 limit start, size 中的 start</strong> * @param size * 查詢大小 * <strong> 類似mysql查詢中的 limit start, size 中的 size</strong> * @return * 滿足條件的集合 */ public List<T> getPage(Query query, int start, int size){ query.skip(start); query.limit(size); log.info("[Mongo Dao ]queryPage:" + query + "(" + start +"," + size +")"); List<T> lists = this.mongoTemplate.find(query, this.getEntityClass()); return lists; } /** * 根據條件查詢庫中符合記錄的總數,為分頁查詢服務 * * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-10-13 下午03:35:44 * * @param query * 查詢條件 * @return * 滿足條件的記錄總數 */ public Long getPageCount(Query query){ log.info("[Mongo Dao ]queryPageCount:" + query); return this.mongoTemplate.count(query, this.getEntityClass()); }
根據Id刪除操作
/** * 根據Id刪除用戶 * * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-10-13 下午04:09:20 * * @param id */ public void deleteById(String id) { Criteria criteria = Criteria.where("_id").in(id); if(null!=criteria){ Query query = new Query(criteria); log.info("[Mongo Dao ]deleteById:" + query); if(null!=query && this.queryOne(query)!=null){ this.delete(query); } } }
刪除對象操作
/** * 刪除對象 * * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-10-13 下午03:45:33 * * @param t */ public void delete(T t){ log.info("[Mongo Dao ]delete:" + t); this.mongoTemplate.remove(t); }
修改操作:
說明:Mongodb的修改操作大致有3中.
mongoTemplate.updateFirst操作、mongoTemplate.updateMulti操作、this.mongoTemplate.upsert操作.
分別表示修改第一條、修改符合條件的所有、修改時如果不存在則添加.
修改滿足條件的第一條記錄
/** * 更新滿足條件的第一個記錄 * * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-10-13 下午03:47:10 * * @param query * @param update */ public void updateFirst(Query query,Update update){ log.info("[Mongo Dao ]updateFirst:query(" + query + "),update(" + update + ")"); this.mongoTemplate.updateFirst(query, update, this.getEntityClass()); }
修改滿足條件的多條記錄
/** * 更新滿足條件的所有記錄 * * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-10-13 下午03:48:02 * * @param query * @param update */ public void updateMulti(Query query, Update update){ log.info("[Mongo Dao ]updateMulti:query(" + query + "),update(" + update + ")"); this.mongoTemplate.updateMulti(query, update, this.getEntityClass()); }
修改,如果要修改的對象不存在則添加
/** * 查找更新,如果沒有找到符合的記錄,則將更新的記錄插入庫中 * * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-10-13 下午03:48:58 * * @param query * @param update */ public void updateInser(Query query, Update update){ log.info("[Mongo Dao ]updateInser:query(" + query + "),update(" + update + ")"); this.mongoTemplate.upsert(query, update, this.getEntityClass()); }
上面的操作是Mongodb的基礎操作封裝,利用泛型實現的抽象類MongoGenDao.java,泛型中定義鈎子方法,然后Dao類繼承抽象類,實現該鈎子方法,返回反射的類型.鈎子方法的定義如下:
/** * 鈎子方法,由子類實現返回反射對象的類型 * * @author <a href='mailto:dennisit@163.com'>Cn.pudp(En.dennisit)</a> Copy Right since 2013-10-13 下午03:21:48 * * @return */ protected abstract Class<T> getEntityClass();
Mongodb基礎操作封裝大致就這么多
接下來介紹如何在數據Dao中根據需要復寫我們的持久層基礎操作.實例是會員管理的基礎實現.
package com.pudp.dao; import java.util.List; 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.Repository; import com.pudp.base.MongoGenDao; import com.pudp.model.Member; import com.pudp.util.StringUtil; /** * description: * * @author <a href='mailto:dennisit@163.com'> Cn.蘇若年 (En.dennisit)</a> Copy Right since 2013-10-13 * * com.pudp.dao.MemberDao.java * */ @Repository public class MemberDao extends MongoGenDao<Member>{ /** * 分頁查詢 對應mongodb操作中的 db.member.find().skip(10).limit(10); * * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-10-13 下午04:09:58 * * @param member * 查詢的條件 * @param start * 用戶分頁查詢的起始值 * @param size * 查詢的數據數目 * * @return * 返回查詢到的數據集合 */ public List<Member> queryPage(Member member, Integer start, Integer size) { Query query = new Query(); //此處可以增加分頁查詢條件Criteria.然后query.addCriteria(criteria); return this.getPage(query,(start-1)*size,size); } /** * 查詢滿足分頁的記錄總數 * * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-10-16 上午10:20:12 * * @param member * 查詢的條件 * @return * 返回滿足條件的記錄總數 */ public Long queryPageCount(Member member){ Query query = new Query(); //此處可以增加分頁查詢條件Criteria.然后query.addCriteria(criteria); return this.getPageCount(query); } /** * 更新操作 * * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-10-17 下午02:21:26 * * @param member * 要更新的數據 * @throws Exception * 更新異常 */ public void updateFirst(Member member) throws Exception { Update update = new Update(); if(null==member.getId()||"".equals(member.getId().trim())){ //如果主鍵為空,則不進行修改 throw new Exception("Update data Id is Null"); } if(StringUtil.isNotNullValue(member.getUsername())){ update.set("username", member.getUsername()); } if(StringUtil.isNotNullValue(member.getPassword())){ update.set("password", member.getPassword()); } if(StringUtil.isNotNullValue(member.getSex())){ update.set("sex", member.getSex()); } if(StringUtil.isNotNullValue(member.getEmail())){ update.set("email", member.getEmail()); } this.updateFirst(Query.query(Criteria.where("_id").is(member.getId())),update); } /** * 更新庫中所有數據 * * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-10-17 下午02:22:07 * * @param member * 更新的數據 * @throws Exception * 更新異常 */ public void updateMulti(Member member) throws Exception { Update update = new Update(); if(null==member.getId()||"".equals(member.getId().trim())){ //如果主鍵為空,則不進行修改 throw new Exception("Update data Id is Null"); } if(StringUtil.isNotNullValue(member.getUsername())){ update.set("username", member.getUsername()); } if(StringUtil.isNotNullValue(member.getPassword())){ update.set("password", member.getPassword()); } if(StringUtil.isNotNullValue(member.getSex())){ update.set("sex", member.getSex()); } if(StringUtil.isNotNullValue(member.getEmail())){ update.set("email", member.getEmail()); } this.updateMulti(Query.query(Criteria.where("_id").is(member.getId())),update); } /** * 實現鈎子方法,返回反射的類型 * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-10-17 * * @return * 反射類型 */ @Override protected Class<Member> getEntityClass() { return Member.class; } }
業務層調用Dao進行業務數據的交互.這里列出實例中的Service層中對持久層分頁操作的實現
/** * 分頁查詢 * @author <a href='mailto:dennisit@163.com'>Cn.蘇若年(En.dennisit)</a> Copy Right since 2013-10-17 * * @param member * 查詢的條件 * @param start * 對應<code>Page</code>工具類的屬性當前頁:pageNum * @param size * 對應<code>Page</code>工具類的屬性每頁顯示多少條記錄:pageSize * @return */ public Page<Member> queryPage(Member member, int start, int size) { Page<Member> page = new Page<Member>(); try { List<Member> list = this.memberDao.queryPage(member, start, size); Long recordTotal = this.memberDao.queryPageCount(member); page= new Page<Member>(list, recordTotal, (long)start, size); log.info(page); } catch (Exception e) { e.printStackTrace(); } return page; }
至此,SpringMVC整合mongodb的高級操作實例完畢,實例中使用jquery.Pager插件分頁. 這個屬於分頁插件的應用,就不介紹了.
運行效果圖: