开发环境:
操作系统: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:[email protected]'>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:[email protected]'>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:[email protected]'>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:[email protected]'>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:[email protected]'>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:[email protected]'>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:[email protected]'>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:[email protected]'>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:[email protected]'>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:[email protected]'>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:[email protected]'>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:[email protected]'>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:[email protected]'> 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:[email protected]'>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:[email protected]'>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:[email protected]'>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:[email protected]'>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:[email protected]'>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:[email protected]'>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插件分页. 这个属于分页插件的应用,就不介绍了.
运行效果图:
转载请注明出处:[http://www.cnblogs.com/dennisit/p/3374297.html]