zoukankan      html  css  js  c++  java
  • Spring MVC中使用Mongodb总结

    近期项目做了次架构调整,原来是使用MySQL+GeoHash来存储LBS数据(地理位置信息),现在使用NOSQL数据库MongoDB来存储LBS数据(地理位置信息)。由于项目是基于spring MVC开发的,今天就Mongodb的使用做下总结。

    Spring MVC 集成Mongodb

    1.加载jar,maven配置

            <!-- 新加入的spring整合mongodb的包 开始 -->
            <dependency>
                <groupId>org.mongodb</groupId>
                <artifactId>mongo-java-driver</artifactId>
                <version>2.13.0-rc0</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.data</groupId>
                <artifactId>spring-data-mongodb</artifactId>
                <version>1.7.1.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.data</groupId>
                <artifactId>spring-data-mongodb-cross-store</artifactId>
                <version>1.7.1.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.data</groupId>
                <artifactId>spring-data-mongodb-log4j</artifactId>
                <version>1.7.1.RELEASE</version>
            </dependency>
            <!-- 新加入的spring整合mongodb的包 结束 -->
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    2.配置 
    Mongodb分2种方法集成,分别是单机和集群方式。 
    单机配置 
    applicationContext.xml

    <mongo:mongo id="mongo" host="${mongo.host}" port="${mongo.port}" >
            <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>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    配置文件common-config.properties

    mongo.dbname = test_db #数据库名称
    mongo.password = test_pwd #密码
    mongo.username = test_user #用户名
    mongo.host = 127.0.0.1 #主机
    mongo.port= 27017 #端口号
    mongo.connectionsPerHost= 8 #一个线程变为可用的最大阻塞数
    mongo.threadsAllowedToBlockForConnectionMultiplier= 4 #线程队列数,它以上面connectionsPerHost值相乘的结果就是线程队列最大值
    mongo.connectTimeout= 1500 #连接超时时间(毫秒)
    mongo.maxWaitTime= 1500 #最大等待时间
    mongo.autoConnectRetry= true #自动重连
    mongo.socketKeepAlive= true #scoket保持活动
    mongo.socketTimeout=1500 #scoket超时时间
    mongo.slaveOk=true #读写分离
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    集群配置 
    applicationContext.xml

    <mongo:mongo  id="mongo"  replica-set="${mongo.replicaSet}">
            <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="${mongo.writeNumber}" write-fsync="${mongodb.writeFsync}" />
        </mongo:mongo>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    配置文件common-config.properties

    mongo.dbname = test_db
    mongo.username = test_user
    mongo.password = test_pwd
    mongo.replicaSet = 192.168.2.193:27017,192.168.2.192:27017
    mongo.connectionsPerHost= 100
    mongo.threadsAllowedToBlockForConnectionMultiplier=50
    mongo.connectTimeout=3000
    mongo.maxWaitTime=5000
    mongo.autoConnectRetry=true
    mongo.socketKeepAlive=true
    mongo.socketTimeout=5000
    mongo.slaveOk=true
    mongo.writeNumber = 1
    mongodb.writeFsync = true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    其他配置

    <!-- 用户验证 -->
        <bean id="userCredentials" class="org.springframework.data.authentication.UserCredentials">
            <constructor-arg name="username" value="${mongo.username}" />
            <constructor-arg name="password" value="${mongo.password}" />
        </bean>
    
    
        <!-- mongo的工厂,通过它来取得mongo实例,dbname为mongodb的数据库名,没有的话会自动创建 -->
        <bean id="mongoDbFactory"
            class="org.springframework.data.mongodb.core.SimpleMongoDbFactory">
            <constructor-arg ref="mongo" />
            <constructor-arg value="${mongo.dbname}" />
            <constructor-arg ref="userCredentials" />
        </bean>
    
        <bean id="mappingContext"
            class="org.springframework.data.mongodb.core.mapping.MongoMappingContext" />
    
        <bean id="defaultMongoTypeMapper"
            class="org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper">
            <constructor-arg name="typeKey">
                <null />
            </constructor-arg>
        </bean>
    
        <!-- collection的映射 -->
        <bean id="mappingMongoConverter"
            class="org.springframework.data.mongodb.core.convert.MappingMongoConverter">
            <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
            <constructor-arg name="mappingContext" ref="mappingContext" />
            <property name="typeMapper" ref="defaultMongoTypeMapper" />
        </bean>
    
        <!-- mongodb的主要操作对象,所有对mongodb的增删改查的操作都是通过它完成 -->
        <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
            <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
            <constructor-arg name="mongoConverter" ref="mappingMongoConverter" />
        </bean>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    Mongodb增删改查

    1.Mongodb对象模型 
    Dynamic.Java

    
    @Document(collection = "Dynamic")
    public class Dynamic implements Serializable{
    
        /**
         * 
         */
        private static final long serialVersionUID = 179822189115264434L;
        private String _id; 
        private String userId;     //用户ID    
        private Date releaseDate;//发布日期 
        private double []loc = new double[2];//位置
    
        public void setId(String _id) {
            this._id = _id;
        }
    
        public String getId() {
            return this._id;
        }
    
        public String getUserId() {
            return userId;
        }
        public void setUserId(String userId) {
            this.userId = userId;
        }
        public Date getReleaseDate() {
            return releaseDate;
        }
        public void setReleaseDate(Date releaseDate) {
            this.releaseDate = releaseDate;
        }
        public double[] getLoc() {
            return loc;
        }
        public void setLoc(double[] loc) {
            this.loc = loc;
        }
    
    
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    2.代码示例 
    新增

    Dynamic dynamic = New Dynamic();
    dynamic.setUserId("10023");
    // ...
    // set属性,自己补全
    // 转换为DBObject
    DBObject dbObject = BeanUtil.bean2DBObject(dynamic);
            db.removeField("serialVersionUID");
    // 保存
    mongoTemplate.getCollection(collection).save(dbObject)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    更新 
    普通更新

    DBObject aim = new BasicDBObject("_id", id);
    DBObject setValue = new BasicDBObject();
    setValue.put("loc", loc.getLoc());
    // 更新的值,用$set
    DBObject updateSetValue = new BasicDBObject("$set", setValue);
    
    //更新,aim:where条件 updateSetValue:更新值 true:是否没有记录时插入 false:是否多行更新
    mongoTemplate.getCollection(collection).update(aim, updateSetValue , true,
                    false);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    数组更新

    DBObject addAim = new BasicDBObject();
            addAim.put("_id", id);
    //数据中push值
    DBObject updateSetValue = new BasicDBObject("$push", addedValue);
    //增加
    updateSetValue.put("$inc", new BasicDBObject("commentSize", 1));
    mongoTemplate.getCollection(collection).update(addAim, updateSetValue);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    查询 
    单条查询

    DBObject query = new BasicDBObject("_id", id);
    DBObject fields = new BasicDBObject();
    mongoTemplate.getCollection(collection).findOne(query, fields)
    • 1
    • 2
    • 3
    • 1
    • 2
    • 3

    分页查询

    int pageSize = 20;
    int pageNum = 1;
    DBObject fields = new BasicDBObject();
    //排序,-1 降序
    DBObject orderBy = new BasicDBObject("release_date", -1);
    
    //分页查询
    List<DBObject> list = new ArrayList<>();
    Cursor cursor = mongoTemplate.getCollection(collection)
            .find(query, fields).skip((pageNum - 1) * pageSize)
            .limit(pageSize).sort(orderBy);
    while (cursor.hasNext()) {
        list.add(cursor.next());
    }       
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    范围查询

    DBObject query = new BasicDBObject();
    // $lte 小于等于,$lt 小于
    query.put(
            "release_date",
            new BasicDBObject("$lte", DateUtil.parseDate(
                    maxTime, DateStyle.YYYY_MM_DD_HH_MM_SS_SSS
                            .getValue())));
    // $gte 大于等于,$gt 大于
    query.put(
            "release_date",
            new BasicDBObject("$gte", DateUtil.parseDate(
                    minTime, DateStyle.YYYY_MM_DD_HH_MM_SS_SSS
                            .getValue())));
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    in 和not in 查询

    // $in 查询
    DBObject query = new BasicDBObject("qd_id", new BasicDBObject(
                        "$in", idStr))
    // $nin 查询
    DBObject query = new BasicDBObject("qd_id", new BasicDBObject(
                        "$nin", idStr))
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    or 查询

    List orArry = new ArrayList<>();
                    orArry.add(new BasicDBObject("qd_id", new BasicDBObject(
                            "$in", qd_ids.toArray())));
                    orArry.add(new BasicDBObject("_id", new BasicDBObject("$in", recommondIds.toArray())));
                    query.put("$or", orArry);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 1
    • 2
    • 3
    • 4
    • 5

    聚合查询sum和group by

    Map retMap = new HashMap<>();
    // $group 分组,newsCount别名,$sum和,$commentSize字段名
            String groupStr = "{$group:{_id:null,newsCount:{$sum:1},commentCount:{$sum:"$commentSize"},supportCount:{$sum:"$supportSize"}}}";
            DBObject group = (DBObject) JSON.parse(groupStr);
            String minTime = (String)params.get("start") + " 00:00:00:000";
            String maxTime = (String)params.get("end") + " 00:00:00:000";
            BasicDBObject query = new BasicDBObject();
            query.put(
                    "release_date",
                    new BasicDBObject("$gte", DateUtil.parseDate(
                            minTime, DateStyle.YYYY_MM_DD_HH_MM_SS_SSS
                                    .getValue())));
            query.put(
                    "release_date",
                    new BasicDBObject("$lte", DateUtil.parseDate(
                            maxTime, DateStyle.YYYY_MM_DD_HH_MM_SS_SSS
                                    .getValue())).append("$gte",
                            DateUtil.parseDate(minTime,
                                    DateStyle.YYYY_MM_DD_HH_MM_SS_SSS
                                            .getValue())));
            DBObject match = new BasicDBObject("$match", query);
    // 聚合查询
            AggregationOutput output = mongoTemplate.getCollection(collection).aggregate(match,group);
            for( Iterator< DBObject > it = output.results().iterator(); it.hasNext(); ){
                BasicDBObject dbo = ( BasicDBObject ) it.next();
                retMap = com.alibaba.fastjson.JSON.parseObject(dbo.toString(), Map.class);
            }
            return retMap;
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    LBS查询(附近的人)

    if (query == null)
                query = new BasicDBObject();
    
    List<DBObject> pipeLine = new ArrayList<>();
    BasicDBObject pipeBasicDBObject = new BasicDBObject();
    
    pipeBasicDBObject.append("near", new double[] { longitude, latitude })
    .append("distanceField", "dist.calculated")
    .append("spherical", true).append("query", query)
    .append("distanceMultiplier", 6371);
    
    if (qType == 1) {
        double maxDistance = distance/6371.0000;
        pipeBasicDBObject.append("maxDistance", maxDistance);
    }
    
    BasicDBObject aggregate = new BasicDBObject("$geoNear",
            pipeBasicDBObject);
    BasicDBObject orderObject = new BasicDBObject("$sort",
            new BasicDBObject().append("dist.calculated", 1));
    
    pipeLine.add(aggregate);
    pipeLine.add(orderObject);
    
    int startNo = (pageNum-1)*pageSize;
    int limit = pageSize;
    
    if(pageNum == 1)
    {
        limit = limit+1;
    }
    else
    {
        startNo = startNo+1;
    }
    
    if (qType == 1) {
        BasicDBObject skipObject = new BasicDBObject("$skip", startNo);
        pipeLine.add(skipObject);
    }
    
    BasicDBObject limitObject = new BasicDBObject("$limit", limit);
    pipeLine.add(limitObject);
    List<DBObject> list = new LinkedList<>();
    try {
        Cursor cursor = mongoTemplate.getCollection(collection).aggregate(
                pipeLine, AggregationOptions.builder().build());
        while (cursor.hasNext()) {
            DBObject dBObject = cursor.next();
            list.add(dBObject);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return list;
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    删除

    DBObject deleAim = new BasicDBObject();
    deleAim.put("_id", id);
    mongoTemplate.getCollection(collection).remove(dbObject)
    • 1
    • 2
    • 3
    • 1
    • 2
    • 3

    ps:上面示例不全,只附上了重要的代码。

  • 相关阅读:
    node
    前端工程师的思考
    前端工程师需要具备的条件
    产品经理必须掌握的名词
    金融人必须掌握的词汇
    央企降两金、降杠杆的 “兵器谱”
    抽屉协议
    清分、清算、结算的关系
    如何有效规避风险
    浅谈在项目管理过程中风险管理
  • 原文地址:https://www.cnblogs.com/alexxs/p/6067946.html
Copyright © 2011-2022 走看看