MongoDB 针对嵌套对象,多层级结构存储,增删改查

来源:互联网 发布:利润率高的行业 知乎 编辑:程序博客网 时间:2024/06/05 23:54

简要介绍NOSQL


mongoDB 是属于NOSQL.什么是nosql,NoSQL(NoSQL = Not Only SQL ),意即”不仅仅是SQL”。 
NoSQL,指的是非关系型的数据库。NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。

NoSQL用于超大规模数据的存储。(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。 
这里写图片描述

mongodb介绍

  • MongoDB的提供了一个面向文档存储,操作起来比较简单和容易。你可以在MongoDB记录中设置任何属性的索引 (如:FirstName=”Sameer”,Address=”8 Gandhi Road”)来实现更快的排序。
  • 你可以通过本地或者网络创建数据镜像,这使得MongoDB有更强的扩展性。
  • 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#等多种语言。
  • MongoDB安装简单。

spring 集成使用mongodb

我自己使用mongodb ,是用spring 中带的mongodb包来使用的。只要的jar包是,下面是maven引用包

        <dependency>            <groupId>org.mongodb</groupId>            <artifactId>mongo-java-driver</artifactId>            <version>2.13.0</version>        </dependency>        <dependency>            <groupId>org.springframework.data</groupId>            <artifactId>spring-data-mongodb</artifactId>            <version>1.6.2.RELEASE</version>        </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

配置mongodb 数据源

  1. 数据连接地址。用一个properties保存。
mongo.dburl=172.16.40.18:27017mongo.dbname=qingxingmongo.connectionsPerHost=100mongo.threadsAllowedToBlockForConnectionMultiplier=4mongo.maxWaitTime=1500mongo.socketTimeout=1500mongo.connectTimeout=1000mongo.autoConnectRetry=truemongo.socketKeepAlive=truemongo.slaveOk=true
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  1. 在spring 配置文件中配置数据源
<!-- ****************************** mongoDB begin **********************************  -->    <!-- 一些连接属性的设置 -->    <mongo:mongo id="mongo" replica-set="${mongo.dburl}">        <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的工厂,通过它来取得mongo实例,dbname为mongodb的数据库名,没有的话会自动创建 -->    <mongo:db-factory dbname="${mongo.dbname}" mongo-ref="mongo" />    <bean id="mappingContext"        class="org.springframework.data.mongodb.core.mapping.MongoMappingContext" />    <!-- 去除集合里的_class属性 -->    <bean id="defaultMongoTypeMapper"        class="org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper">        <constructor-arg name="typeKey">            <null />        </constructor-arg>    </bean>    <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>    <!-- 映射转换器,扫描back-package目录下的文件,根据注释,把它们作为mongodb的一个collection的映射 -->    <mongo:mapping-converter base-package="com.qx.mongodb.doc" />    <!-- mongodb bean的仓库目录,会自动扫描扩展了MongoRepository接口的接口进行注入 -->    <mongo:repositories base-package="com.qx.mongodb.dao" />    <!-- ***************************** mongoDB over **********************************  -->
  • 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
  1. 对象的操作。建立映射关系对应。
/** * 教练版的语音播报 *  * @author luoyang * */@Document(collection = "mg_voice")  //存入的表名称public class MgVoice {    @Id  //标志为主键    private Long cid;    /**     * M 男声  F 女声     */    private String voiceType;    /**     * 速度     */    private Integer voiceSpeed;    private List<MgVoiceLibrary> voiceLibrarys;    private List<MgVoicePlan> voicePlans;   public Long getCid(){      return cid;   }....
  • 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

内嵌对象 MgVoiceLibrary

/** * 教练版的语音库 *  * @author luoyang * */public class MgVoiceLibrary {    private String lid;    /**     * 2 科目二 3 科目三   4 起步灯光     */    private Integer type;    private String title;    private String content;    /**     * 0 不是  1 是     */    private Integer isTemp;    private String tempCode;    private String tempTitle;    private String tempContent;    private Date updateDate;   public String getLid(){      return lid;   }   .....
  • 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

增删改查操作

在做一下的操作之前先介绍spring 中操作mongodb的类。 
在之前的配置中可以看到,我们已经引入了一个类:mongoTemplate 
import org.springframework.data.mongodb.core.MongoTemplate;

其中所引用的包

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.Service;import com.alibaba.fastjson.JSON;import com.mongodb.BasicDBObject;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

所以在我们的service 层 ,利用注解直接使用这个类

   @Autowired   protected MongoTemplate mongoTemplate;
  • 1
  • 2
  1. 新增
 //新增很简单,将新增的对象设置好值,直接保存 MgVoice mgVoice = new MgVoice(); mgVoice.set ....// mongoTemplate.save(mgVoice);
  • 1
  • 2
  • 3
  • 4
  1. 修改。(修改对象的直接属性)
 {        "cid": 1100658, //教练ID        "voiceType": "F",//语音类型 F女声 M 男声        "voiceSpeed": 30, //语音速度        "voiceLibrarys": [            {                "lid": "p2_b9dc7616-b476-40ee-8fd7-982711cece98",//语音ID                "type": 2,//语音类型 2科目二 3科目三                "title": "上坡起步",  //标题                "content": "上坡起步和定点停车",//内容                "isTemp": 1,  //是否是模板 0 不是 1 是                "tempCode": "k2_spqb",//模板代码  ,也是模板图片标题                "tempTitle": "上坡起步",//模板标题                "tempContent": "上坡起步和定点停车",//模板内容,供恢复默认使用                "updateDate": "2016-04-28 00:00:00"            },            {                "lid": "p3_ead65a9a-c659-4f55-a7d4-067d8935ee19",                "type": 3,                "title": "靠边停车",                "content": "请靠边停车",                "isTemp": 1,                "tempCode": "k3_kbtc",                "tempTitle": "靠边停车",                "tempContent": "请靠边停车",                "updateDate": "2016-04-28 00:00:00"            }]            }
  • 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
我们要修改对象中的 voiceType 和 voiceSpeed  属性代码如下
   @Override   public void updateCfg(Long cid,                         Integer speed,                         String type){      Criteria criteria = Criteria.where("cid").is(cid);      Query query = new Query(criteria);      Update update = Update.update("voiceType", type).set("voiceSpeed", speed);      mongoTemplate.updateFirst(query, update, MgVoice.class);   }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  1. 修改。(对象中的 嵌套对象) 
    我们要修改 voiceLibrarys 数组 中 lid = “p2_b9dc7616-b476-40ee-8fd7-982711cece98”,的对象中的 title 和 content 属性。使用set
   //是修改         Query query = new Query(Criteria.where("cid").is(cid).and("voiceLibrarys.lid").is(lid));         Update update = Update.update("voiceLibrarys.$.title", title).set("voiceLibrarys.$.content", content);         mongoTemplate.updateFirst(query, update, MgVoice.class);
  • 1
  • 2
  • 3
  • 4

如果是要再voiceLibrarys 这个数组中新增一个对象 使用addToset

  //语音的ID 为空是新增         lid = getCreateId(type);         MgVoiceLibrary voice = new MgVoiceLibrary();         voice.setLid(lid);         voice.setType(type);         voice.setTitle(title);         voice.setContent(content);         voice.setIsTemp(0);         voice.setUpdateDate(RDate.getCurrentDate());         Query query = Query.query(Criteria.where("cid").is(cid));         Update update = new Update();         update.addToSet("voiceLibrarys", voice);         mongoTemplate.upsert(query, update, MgVoice.class);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

如果要删除数组voiceLibrarys 中的一个对象,对象lid=”p2_b9dc7616-b476-40ee-8fd7-982711cece98” 。 使用pull 属性

  //删除 语音 cid  记录的ID  plid 数组中的一个标记         Query query = Query.query(Criteria.where("cid").is(cid));         BasicDBObject s = new BasicDBObject();         s.put("lid", plid);         Update update = new Update();         update.pull("voiceLibrarys", s);         mongoTemplate.updateFirst(query, update, MgVoice.class);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

除了以上的操作 还有一些属性,例如 unset. 
如果update.upset 一个数组。 就会清空对象,但是数组大小不会变。

modifies 
使用 update.modifies(key) 。 就会把这个对象里面除了ID 以外的值全部删除。

如果对象是这样的。voiceLibrarys 是一个对象,不是数组。同样要修改title 和 content 对象。

{        "cid": 1100658, //教练ID        "voiceType": "F",//语音类型 F女声 M 男声        "voiceSpeed": 30, //语音速度        "voiceLibrarys":             {                "lid": "p2_b9dc7616-b476-40ee-8fd7-982711cece98",//语音ID                "type": 2,//语音类型 2科目二 3科目三                "title": "上坡起步",  //标题                "content": "上坡起步和定点停车",//内容                "isTemp": 1,  //是否是模板 0 不是 1 是                "tempCode": "k2_spqb",//模板代码  ,也是模板图片标题                "tempTitle": "上坡起步",//模板标题                "tempContent": "上坡起步和定点停车",//模板内容,供恢复默认使用                "updateDate": "2016-04-28 00:00:00"            }            }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

代码

 //是修改         Query query = new Query(Criteria.where("cid").is(cid));         Update update = Update.update("voiceLibrarys.title", title).set("voiceLibrarys.content", content);         mongoTemplate.updateFirst(query, update, MgVoice.class);
  • 1
  • 2
  • 3
  • 4

如果要删除整条记录。 使用remove

   @Override   public boolean removeVoice(Long cid){         //删除 语音      Query query = Query.query(Criteria.where("cid").is(cid));      mongoTemplate.remove(query, MgVoice.class);      return true;   }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这里只是简单的介绍一些基本的操作方法。 
本人只是简单的看了一下。spring mongodb源码包中的代码。源码包中 也并没有写的很详细。只是给了其他的文档地址。例如

/**     * Update using the {@literal $pull} update modifier     *      * @see http://docs.mongodb.org/manual/reference/operator/update/pull/     * @param key     * @param value     * @return     */    public Update pull(String key, Object value) {        addMultiFieldOperation("$pull", key, value);        return this;    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

根据 
http://docs.mongodb.org/manual/reference/operator/update/pull/ 
再去查看一些基本的方法的使用。

原创粉丝点击