zoukankan      html  css  js  c++  java
  • SpringMVC整合Mongodb开发,高级操作

    开发环境:

    操作系统:windows xp
    Mongodb2.0.6
    依 赖 包:Spring3.2.2 + spring-data-mongodb-1.3.0 + Spring-data-1.5 + mongodb2.7.3
    说    明:Springmvc整合Mongodb的时候建议选择稳定版的Spring-data-mongdbMongodb1.0.1中存在数据映射bug.所以使用1.3.0.

    项目结构图:



    说明:
    持久层操作使用MongoTemplate类操作.实现将对象与Mongodb库中的数据交互操作.


    这里需要说明的是我的实体对象中的id属性对应的是库中记录中的_id属性.

    MongodbSpringMVC整合参见文档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插件分页这个属于分页插件的应用,就不介绍了.

    运行效果图:


    转载请注明出处:[http://www.cnblogs.com/dennisit/p/3374297.html]

    ÔÚÏß½»Ì¸

  • 相关阅读:
    Hive 中parse_url的使用
    作为首席架构师,我是如何选择并落地架构方案的?
    漫谈数据仓库之拉链表(原理、设计以及在Hive中的实现)
    纸上得来终觉浅
    年薪50万的大数据分析师养成记【摘抄】
    如果有人问你数据库的原理,叫他看这篇文章(完)
    开源大数据引擎:Greenplum 数据库架构分析
    【阿里在线技术峰会】李金波:企业大数据平台仓库架构建设思路
    ETL Automation完整安装方法_(元数据存放在mysql数据库)
    js定时器 离开当前页面任然执行的问题
  • 原文地址:https://www.cnblogs.com/dennisit/p/3374297.html
Copyright © 2011-2022 走看看