MongoDB
开发环境:
操作系统:windowsxp
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.linuxidc.com/Linux/2015-02/114229.htm
Mongodb的高级操作:
添加对象到数据库
/**
*保存一个对象
*
*@author<ahref='mailto:[email protected]'>Cn.苏若年(En.dennisit)</a>CopyRightsince2013-10-13下午03:37:28
*
*@paramt
*@return
*/
publicvoidsave(Tt){
log.info("[MongoDao]save:"+t);
this.mongoTemplate.save(t);
}
根据Id从库中查询对象
/**
*根据Id从Collection中查询对象
*
*@author<ahref='mailto:[email protected]'>Cn.苏若年(En.dennisit)</a>CopyRightsince2013-10-17下午01:59:55
*
*@paramid
*实体对象的Id,对应Collection中记录的_id字段.
*<p>
*需要说明的是,Mongdo自身没有主键自增机制.解决方法
*<ol>
*<li>实体入库的时候,程序中为实体赋主键值.
*<li>实体入库的时候,在mongodb中自定义函数实现主键自增机制.定义方法同js代码类似
*</ol>
*</p>
*@return
*/
publicTqueryById(Stringid){
Queryquery=newQuery();
Criteriacriteria=Criteria.where("_id").is(id);
query.addCriteria(criteria);
log.info("[MongoDao]queryById:"+query);
returnthis.mongoTemplate.findOne(query,this.getEntityClass());
}
根据条件从库中查询
/**
*根据条件查询集合
*
*@author<ahref='mailto:[email protected]'>Cn.苏若年(En.dennisit)</a>CopyRightsince2013-10-13下午03:32:54
*
*@paramquery
*查询条件
*@return
*满足条件的集合
*/
publicList<T>queryList(Queryquery){
log.info("[MongoDao]queryList:"+query);
returnthis.mongoTemplate.find(query,this.getEntityClass());
}
根据条件查询单个记录
/**
*通过条件查询单个实体
*
*@author<ahref='mailto:[email protected]'>Cn.苏若年(En.dennisit)</a>CopyRightsince2013-10-13下午03:33:12
*
*@paramquery
*@return
*/
publicTqueryOne(Queryquery){
log.info("[MongoDao]queryOne:"+query);
returnthis.mongoTemplate.findOne(query,this.getEntityClass());
}
说明:查询单个用的是mongoTemplate.findOne方法,查询多条的用的是mongoTemplate.find.
分页查询操作
/**
*通过条件进行分页查询
*
*@author<ahref='mailto:[email protected]'>Cn.苏若年(En.dennisit)</a>CopyRightsince2013-10-13下午03:33:30
*
*@paramquery
*查询条件
*@paramstart
*查询起始值
*<strong>类似mysql查询中的limitstart,size中的start</strong>
*@paramsize
*查询大小
*<strong>类似mysql查询中的limitstart,size中的size</strong>
*@return
*满足条件的集合
*/
publicList<T>getPage(Queryquery,intstart,intsize){
query.skip(start);
query.limit(size);
log.info("[MongoDao]queryPage:"+query+"("+start+","+size+")");
List<T>lists=this.mongoTemplate.find(query,this.getEntityClass());
returnlists;
}
/**
*根据条件查询库中符合记录的总数,为分页查询服务
*
*@author<ahref='mailto:[email protected]'>Cn.苏若年(En.dennisit)</a>CopyRightsince2013-10-13下午03:35:44
*
*@paramquery
*查询条件
*@return
*满足条件的记录总数
*/
publicLonggetPageCount(Queryquery){
log.info("[MongoDao]queryPageCount:"+query);
returnthis.mongoTemplate.count(query,this.getEntityClass());
}
根据Id删除操作
/**
*根据Id删除用户
*
*@author<ahref='mailto:[email protected]'>Cn.苏若年(En.dennisit)</a>CopyRightsince2013-10-13下午04:09:20
*
*@paramid
*/
publicvoiddeleteById(Stringid){
Criteriacriteria=Criteria.where("_id").in(id);
if(null!=criteria){
Queryquery=newQuery(criteria);
log.info("[MongoDao]deleteById:"+query);
if(null!=query&&this.queryOne(query)!=null){
this.delete(query);
}
}
}
删除对象操作
/**
*删除对象
*
*@author<ahref='mailto:[email protected]'>Cn.苏若年(En.dennisit)</a>CopyRightsince2013-10-13下午03:45:33
*
*@paramt
*/
publicvoiddelete(Tt){
log.info("[MongoDao]delete:"+t);
this.mongoTemplate.remove(t);
}
修改操作:
说明:Mongodb的修改操作大致有3中.
mongoTemplate.updateFirst操作、mongoTemplate.updateMulti操作、this.mongoTemplate.upsert操作.
分别表示修改第一条、修改符合条件的所有、修改时如果不存在则添加.
修改满足条件的第一条记录
/**
*更新满足条件的第一个记录
*
*@author<ahref='mailto:[email protected]'>Cn.苏若年(En.dennisit)</a>CopyRightsince2013-10-13下午03:47:10
*
*@paramquery
*@paramupdate
*/
publicvoidupdateFirst(Queryquery,Updateupdate){
log.info("[MongoDao]updateFirst:query("+query+"),update("+update+")");
this.mongoTemplate.updateFirst(query,update,this.getEntityClass());
}
修改满足条件的多条记录
/**
*更新满足条件的所有记录
*
*@author<ahref='mailto:[email protected]'>Cn.苏若年(En.dennisit)</a>CopyRightsince2013-10-13下午03:48:02
*
*@paramquery
*@paramupdate
*/
publicvoidupdateMulti(Queryquery,Updateupdate){
log.info("[MongoDao]updateMulti:query("+query+"),update("+update+")");
this.mongoTemplate.updateMulti(query,update,this.getEntityClass());
}
修改,如果要修改的对象不存在则添加
/**
*查找更新,如果没有找到符合的记录,则将更新的记录插入库中
*
*@author<ahref='mailto:[email protected]'>Cn.苏若年(En.dennisit)</a>CopyRightsince2013-10-13下午03:48:58
*
*@paramquery
*@paramupdate
*/
publicvoidupdateInser(Queryquery,Updateupdate){
log.info("[MongoDao]updateInser:query("+query+"),update("+update+")");
this.mongoTemplate.upsert(query,update,this.getEntityClass());
}
上面的操作是Mongodb的基础操作封装,利用泛型实现的抽象类MongoGenDao.java,泛型中定义钩子方法,然后Dao类继承抽象类,实现该钩子方法,返回反射的类型.钩子方法的定义如下:
/**
*钩子方法,由子类实现返回反射对象的类型
*
*@author<ahref='mailto:[email protected]'>Cn.pudp(En.dennisit)</a>CopyRightsince2013-10-13下午03:21:48
*
*@return
*/
protectedabstractClass<T>getEntityClass();
Mongodb基础操作封装大致就这么多
接下来介绍如何在数据Dao中根据需要复写我们的持久层基础操作.实例是会员管理的基础实现.
packagecom.pudp.dao;
importjava.util.List;
importorg.springframework.data.mongodb.core.query.Criteria;
importorg.springframework.data.mongodb.core.query.Query;
importorg.springframework.data.mongodb.core.query.Update;
importorg.springframework.stereotype.Repository;
importcom.pudp.base.MongoGenDao;
importcom.pudp.model.Member;
importcom.pudp.util.StringUtil;
/**
*description:
*
*@author<ahref='mailto:[email protected]'>Cn.苏若年(En.dennisit)</a>CopyRightsince2013-10-13
*
*com.pudp.dao.MemberDao.java
*
*/
@Repository
publicclassMemberDaoextendsMongoGenDao<Member>{
/**
*分页查询对应mongodb操作中的db.member.find().skip(10).limit(10);
*
*@author<ahref='mailto:[email protected]'>Cn.苏若年(En.dennisit)</a>CopyRightsince2013-10-13下午04:09:58
*
*@parammember
*查询的条件
*@paramstart
*用户分页查询的起始值
*@paramsize
*查询的数据数目
*
*@return
*返回查询到的数据集合
*/
publicList<Member>queryPage(Membermember,Integerstart,Integersize){
Queryquery=newQuery();
//此处可以增加分页查询条件Criteria.然后query.addCriteria(criteria);
returnthis.getPage(query,(start-1)*size,size);
}
/**
*查询满足分页的记录总数
*
*@author<ahref='mailto:[email protected]'>Cn.苏若年(En.dennisit)</a>CopyRightsince2013-10-16上午10:20:12
*
*@parammember
*查询的条件
*@return
*返回满足条件的记录总数
*/
publicLongqueryPageCount(Membermember){
Queryquery=newQuery();
//此处可以增加分页查询条件Criteria.然后query.addCriteria(criteria);
returnthis.getPageCount(query);
}
/**
*更新操作
*
*@author<ahref='mailto:[email protected]'>Cn.苏若年(En.dennisit)</a>CopyRightsince2013-10-17下午02:21:26
*
*@parammember
*要更新的数据
*@throwsException
*更新异常
*/
publicvoidupdateFirst(Membermember)throwsException{
Updateupdate=newUpdate();
if(null==member.getId()||"".equals(member.getId().trim())){
//如果主键为空,则不进行修改
thrownewException("UpdatedataIdisNull");
}
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<ahref='mailto:[email protected]'>Cn.苏若年(En.dennisit)</a>CopyRightsince2013-10-17下午02:22:07
*
*@parammember
*更新的数据
*@throwsException
*更新异常
*/
publicvoidupdateMulti(Membermember)throwsException{
Updateupdate=newUpdate();
if(null==member.getId()||"".equals(member.getId().trim())){
//如果主键为空,则不进行修改
thrownewException("UpdatedataIdisNull");
}
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<ahref='mailto:[email protected]'>Cn.苏若年(En.dennisit)</a>CopyRightsince2013-10-17
*
*@return
*反射类型
*/
@Override
protectedClass<Member>getEntityClass(){
returnMember.class;
}
}
业务层调用Dao进行业务数据的交互.这里列出实例中的Service层中对持久层分页操作的实现
/**
*分页查询
*@author<ahref='mailto:[email protected]'>Cn.苏若年(En.dennisit)</a>CopyRightsince2013-10-17
*
*@parammember
*查询的条件
*@paramstart
*对应<code>Page</code>工具类的属性当前页:pageNum
*@paramsize
*对应<code>Page</code>工具类的属性每页显示多少条记录:pageSize
*@return
*/
publicPage<Member>queryPage(Membermember,intstart,intsize){
Page<Member>page=newPage<Member>();
try{
List<Member>list=this.memberDao.queryPage(member,start,size);
LongrecordTotal=this.memberDao.queryPageCount(member);
page=newPage<Member>(list,recordTotal,(long)start,size);
log.info(page);
}catch(Exceptione){
e.printStackTrace();
}
returnpage;
}
至此,SpringMVC整合mongodb的高级操作实例完毕,实例中使用jquery.Pager插件分页.这个属于分页插件的应用,就不介绍了.
运行效果图:
MongoDB的详细介绍:请点这里
MongoDB的下载地址:请点这里
本文永久更新链接地址:http://www.linuxidc.com/Linux/2015-02/114229.htm
https://www.mongodb.org/downloads#production