轉載: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插件分頁. 這個屬於分頁插件的應用,就不介紹了.
運行效果圖:

