zoukankan      html  css  js  c++  java
  • 像我这样优雅地进行Spring整合MongoDB

    本文重点是要将mongodb与spring整合到项目中去,在实践中发现问题,追踪问题,然后解决问题。

    一、准备

    • Maven、Spring(spring-data-mongodb)
    • spring Data for MongoDB是Spring Data的一个子模块。 目标是为mongodb提供一个相近的一致的基于Spring的编程模型。
    • Spring Data for MongoDB核心功能是映射POJO到Mongo的DBCollection中的文档,并且提供Repository 风格数据访问层。

    二、特性

    • MongoDB的提供了一个面向文档存储,操作起来比较简单和容易。
    • 你可以在MongoDB记录中设置任何属性的索引 (如:FirstName="Ning",Address="Beijing")来实现更快的排序。
    • 你可以通过本地或者网络创建数据镜像,这使得MongoDB有更强的扩展性。
    • 如果负载的增加(需要更多的存储空间和更强的处理能力) ,它可以分布在计算机网络中的其他节点上这就是所谓的分片。
    • Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。
    • MongoDb 使用update()命令可以实现替换完成的文档(数据)或者一些指定的数据字段 。
    • Mongodb中的Map/reduce主要是用来对数据进行批量处理和聚合操作。
    • Map和Reduce。Map函数调用emit(key,value)遍历集合中所有的记录,将key与value传给Reduce函数进行处理。
    • Map函数和Reduce函数是使用Javascript编写的,并可以通过db.runCommand或mapreduce命令来执行MapReduce操作。
    • GridFS是MongoDB中的一个内置功能,可以用于存放大量小文件。
    • MongoDB允许在服务端执行脚本,可以用Javascript编写某个函数,直接在服务端执行,也可以把函数的定义存储在服务端,下次直接调用即可。
    • MongoDB支持各种编程语言:RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言。

    三、依赖包

    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-mongodb</artifactId>
        <version>1.5.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.5.10</version>
    </dependency>

    spring 相关依赖

    <!-- spring web相关依赖 -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>3.1.2.RELEASE</version>
            </dependency>
            <!-- spring test依赖 -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>4.3.1.RELEASE</version>
            </dependency>

     

    四、集成MongoDB

    【注:MongoDB添加权限管理请参见我的这篇文章:MongDB开启权限认证

    mongodb.properties

    mongo.hostport=172.16.4.166:27017
    mongo.dbname=ad_api_count
    mongo.username=hehaitao
    mongo.password=hehaitao
    mongo.connectionsPerHost=8
    mongo.threadsAllowedToBlockForConnectionMultiplier=4
    #u8FDEu63A5u8D85u65F6u65F6u95F4
    mongo.connectTimeout=1000
    #u7B49u5F85u65F6u95F4
    mongo.maxWaitTime=1500
    mongo.autoConnectRetry=true
    mongo.socketKeepAlive=true
    #Socketu8D85u65F6u65F6u95F4
    mongo.socketTimeout=1500
    mongo.slaveOk=true

    mongoDB.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"  
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
        xmlns:context="http://www.springframework.org/schema/context"  
        xmlns:mongo="http://www.springframework.org/schema/data/mongo"  
        xsi:schemaLocation="http://www.springframework.org/schema/context   
              http://www.springframework.org/schema/context/spring-context-3.1.xsd   
              http://www.springframework.org/schema/data/mongo   
              http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd   
              http://www.springframework.org/schema/beans   
              http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
        <!-- 加载mongodb的属性配置文件 -->
        <context:property-placeholder location="classpath:mongodb.properties" ignore-unresolvable="true"/>
        
        <!-- 定义mongo对象,对应的是mongodb官方jar包中的Mongo,replica-set设置集群副本的ip地址和端口 -->
        <mongo:mongo id="mongo" replica-set="${mongo.hostport}">
            <mongo:options
                 connections-per-host="${mongo.connectionsPerHost}"
                 threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}"
                 connect-timeout="${mongo.connectTimeout}"
                 max-wait-time="${mongo.maxWaitTime}"
                 auto-connect-retry="${mongo.autoConnectRetry}"
                 socket-keep-alive="${mongo.socketKeepAlive}"
                 socket-timeout="${mongo.socketTimeout}"
                 slave-ok="${mongo.slaveOk}"
                 write-number="1"
                 write-timeout="0"
                 write-fsync="true"/>        
        </mongo:mongo>
        <mongo:db-factory id="mgFactory" 
            dbname="${mongo.dbname}"  
            username="${mongo.username}" 
            password="${mongo.password}"
             mongo-ref="mongo" />
        
        <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
            <constructor-arg name="mongoDbFactory" ref="mgFactory"/>
        </bean>
    </beans>

    spring-contex.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:task="http://www.springframework.org/schema/task"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.1.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
        http://www.springframework.org/schema/task
        http://www.springframework.org/schema/task/spring-task-3.1.xsd">
        
        <aop:aspectj-autoproxy proxy-target-class="true"/>
        
        <!--使用注解管理bean  -->
        <context:annotation-config/>
        
        <!-- 扫描com.lutongnet下的所有类 -->
        <context:component-scan base-package="com.lutong.cps">
            <context:exclude-filter type = "annotation" expression = "org.springframework.stereotype.Controller"/>
        </context:component-scan>
    
       <import resource="mongoDB.xml"/> 
    </beans>

    五、代码实现

    基础实现MongoDBService

    /**
     * File Name   : MongoDBService.java
     * Package     : com.lutongnet.ad.service
     * Description : TODO
     * Author      : zhangfj
     * Date        : 2012-11-29
     * Version     : V1.0 
     */
    package com.lutong.cps.schedule.service.fj;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.data.mongodb.core.MongoTemplate;
    import org.springframework.data.mongodb.core.query.Query;
    import org.springframework.stereotype.Service;
    /**  
     * @author zhangfj
     *
     */
    @Service("mongoDBService")
    public class MongoDBService
    {
        /*@Resource(name = "mongoTemplate")
        protected MongoTemplate mongoTemplate;*/
    
    
        /**
         * 
         * @param query 
         * @param entityClass 
         * @return T 
         */
        public <T> T findOne(Query query, Class<T> entityClass)
        {
            ApplicationContext context=new ClassPathXmlApplicationContext("mongoDB.xml");
            MongoTemplate mongoTemplate= (MongoTemplate) context.getBean("mongoTemplate");
            // 可以直接调用
            return mongoTemplate.findOne(query, entityClass);
        }
    
    }

    继承类UserAdCountService 

    /**
     * File Name   : UserAdCountService.java
     * Package     : com.lutongnet.ad.service
     * Description : TODO
     * Author      : zhangfj
     * Date        : 2012-11-29
     * Version     : V1.0 
     */
    package com.lutong.cps.schedule.service.fj;
    
    import org.springframework.data.mongodb.core.query.Criteria;
    import org.springframework.data.mongodb.core.query.Query;
    import org.springframework.stereotype.Service;
    
    import com.lutong.cps.schedule.entity.UserAdCount;
    /**  
     * @author zhangfj
     *
     */
    @Service("userAdCountService")
    public class UserAdCountService extends MongoDBService
    {
        /**
         * 获取单个广告的观看次数,查询不到则返回0
         * 
         * @param adCode 
         * @return int 
         */
        public int getUserAdCount(UserAdCount adCode)
        {
            Criteria criteria = new Criteria();
            criteria.andOperator(Criteria.where("userAd").is(adCode.getUserAd()),
                    Criteria.where("adCode").is(adCode.getAdCode()),
                    Criteria.where("countDate").is(adCode.getCountDate()));
            Query query = new Query(criteria);
            UserAdCount result = findOne(query, UserAdCount.class);
            if (null != result)
            {
                return result.getTimesCount();
            }
            return 0;
        }
    }

    实体类UserAdCount

    package com.lutong.cps.schedule.entity;
    
    import java.util.Date;
    
    import org.springframework.data.annotation.PersistenceConstructor;
    import org.springframework.data.mongodb.core.mapping.Document;
    
    /**
     * mongo专用统计单个用户的单个广告观看次数
     * @author cancer
     *
     */
    @Document(collection="userAdCount")
    public class UserAdCount
    {
        private int timesCount;
        
        /**
         * 用户账号
         */
        private String userAd;
        
        private String adCode;
    
        private String countDate;
        
        private Date expireAt;
    @PersistenceConstructor
        public UserAdCount(int timesCount, String userAd,String adCode,String countDate,Date expireAt)
        {
            this.timesCount = timesCount;
            this.userAd = userAd;
            this.adCode = adCode;
            this.countDate = countDate;
            this.expireAt = expireAt;
        }
        
        public UserAdCount(String userAd,String adCode,String countDate)
        {
            this.userAd = userAd;
            this.adCode = adCode;
            this.countDate = countDate;
        }
        
        public UserAdCount(String userAd,String adCode,String countDate,Date expireAt)
        {
            this.userAd = userAd;
            this.adCode = adCode;
            this.countDate = countDate;
            this.expireAt = expireAt;
        }
    public UserAdCount(String countDate)
        {
            this.countDate = countDate;
        }
    
        public int getTimesCount()
        {
            return timesCount;
        }
    
        public void setTimesCount(int timesCount)
        {
            this.timesCount = timesCount;
        }
    
        public String getUserAd()
        {
            return userAd;
        }
    
        public void setUserAd(String userAd)
        {
            this.userAd = userAd;
        }
    
        public String getAdCode()
        {
            return adCode;
        }
    
        public void setAdCode(String adCode)
        {
            this.adCode = adCode;
        }
    
        public String getCountDate() {
            return countDate;
        }
    
        public void setCountDate(String countDate) {
            this.countDate = countDate;
        }
    
        public Date getExpireAt() {
            return expireAt;
        }
    
        public void setExpireAt(Date expireAt) {
            this.expireAt = expireAt;
        }
        
        
    }

    最后写一个测试类来测试下

    import java.util.List;
    import javax.annotation.Resource;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    import com.acts.web.modules.mark.model.Users;
    import com.lutong.cps.schedule.service.fj.UserAdCountService;
    @ContextConfiguration({ "classpath:spring-context.xml",
            "classpath:mongoDB.xml"})
    @RunWith(SpringJUnit4ClassRunner.class)
    public class UserTest {
       @Resource(name = "userAdCountService")
        private UserAdCountService userAdCountService;
        @Test
        public void testDao() {
            try {
                UserAdCount userAdCount = new UserAdCount("hehaitao", "pos001",
                                DateTime.now().toString("yyyy-MM-dd"));
                    int count = userAdCountService
                                .getUserAdCount(userAdCount);
                    System.out.println(count);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    
    
  • 相关阅读:
    我又来定计划了~2015-8至年底
    Spark官方文档中推荐的硬件配置
    java 多线程之:sleep() 方法
    Referrer Policy 介绍
    js 操作 cookie
    顶级域名和子级域名之间的cookie共享和相互修改、删除
    关于 Cookie-free Domains (为什么将静态图片,js,css存放到单独的域名?)
    cookie 知识点
    java 多线程之:yield() 方法
    java 多线程之:wait()、notify()、notifyAll()等方法
  • 原文地址:https://www.cnblogs.com/zishengY/p/8467176.html
Copyright © 2011-2022 走看看