Spring boot中mongodb的使用

mongodb简介

MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是可以应用于各种规模的企业、各个行业以及各类应用程序的开源数据库。基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种。

MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。

传统的关系数据库一般由数据库(database)、表(table)、记录(record)三个层次概念组成,MongoDB是由数据库(database)、集合(collection)、文档对象(document)三个层次组成。MongoDB对于关系型数据库里的表,但是集合中没有列、行和关系概念,这体现了模式自由的特点。

MongoDB中的一条记录就是一个文档,是一个数据结构,由字段和值对组成。MongoDB文档与JSON对象类似。字段的值有可能包括其它文档、数组以及文档数组。MongoDB支持OS X、Linux及Windows等操作系统,并提供了Python,PHP,Ruby,Java及C++语言的驱动程序,社区中也提供了对Erlang及.NET等平台的驱动程序。

MongoDB的适合对大量或者无固定格式的数据进行存储,比如:日志、缓存等。对事物支持较弱,不适用复杂的多文档(多表)的级联查询。文中演示mongodb版本为3.4。

mongodb的增删改查

Spring Boot对各种流行的数据源都进行了封装,当然也包括了mongodb,下面给大家介绍如何在spring boot中使用mongodb:

1、pom包配置

pom包里面添加spring-boot-starter-data-mongodb包引用

<dependencies>
	<dependency> 
	    <groupId>org.springframework.boot</groupId>
	    <artifactId>spring-boot-starter-data-mongodb</artifactId>
	</dependency> 
</dependencies>

2、mongodb标准 URI 连接语法:

  • mongodb:// 这是固定的格式,必须要指定。

  • username:password@ 可选项,如果设置,在连接数据库服务器之后,驱动都会尝试登陆这个数据库

  • host1 必须的指定至少一个host, host1 是这个URI唯一要填写的。它指定了要连接服务器的地址。如果要连接复制集,请指定多个主机地址。

    扫描二维码关注公众号,回复: 5534116 查看本文章
  • portX 可选的指定端口,如果不填,默认为27017

  • /database 如果指定username:password@,连接并验证登陆指定数据库。若不指定,默认打开 test 数据库。

  • ?options 是连接选项。如果不使用/database,则前面需要加上/。所有连接选项都是键值对name=value,键值对之间通过&或;(分号)隔开

标准的连接格式包含了多个选项(options),如下所示:

选项 描述
replicaSet=name 验证replica set的名称。 Impliesconnect=replicaSet.
slaveOk=true|false
  • true:在connect=direct模式下,驱动会连接第一台机器,即使这台服务器不是主。在connect=replicaSet模式下,驱动会发送所有的写请求到主并且把读取操作分布在其他从服务器。
  • false: 在 connect=direct模式下,驱动会自动找寻主服务器. 在connect=replicaSet 模式下,驱动仅仅连接主服务器,并且所有的读写命令都连接到主服务器。
safe=true|false
    • true: 在执行更新操作之后,驱动都会发送getLastError命令来确保更新成功。(还要参考 wtimeoutMS).
false: 在每次更新之后,驱动不会发送getLastError来确保更新成功。
w=n 驱动添加 { w : n } 到getLastError命令. 应用于safe=true。
wtimeoutMS=ms 驱动添加 { wtimeout : ms } 到 getlasterror 命令. 应用于 safe=true.
fsync=true|false
  • true: 驱动添加 { fsync : true } 到 getlasterror 命令.应用于 safe=true.
  • false: 驱动不会添加到getLastError命令中。
journal=true|false 如果设置为 true, 同步到 journal (在提交到数据库前写入到实体中). 应用于 safe=true
connectTimeoutMS=ms 可以打开连接的时间。
socketTimeoutMS=ms 发送和接受sockets的时间。

3、在application.properties中添加URI配置

spring.data.mongodb.uri=mongodb://name:pass@localhost:27017/test

多个IP集群可以采用以下配置:

spring.data.mongodb.uri=mongodb://user:pwd@ip1:port1,ip2:port2/database

4、使用MongoTemplate创建集合

     1)根据数据实体生成集合及其结构

其效果是自动根据实体内容生成集合结构

@Document(collection="person")//此注解可以省略 如果省略则集合名称为类名的首字母小写对应的名称 即:personEntity
public class PersonEntity implements Serializable {
        private static final long serialVersionUID = -3258839839160856613L;
        private Long id;
        private String zhName;
        private String passWord; 

         //getter、setter省略

    2)根据java代码命令先生成一个空结构的集合

         CollectionOptions collectionOptions=new CollectionOptions(6142800,10000,true);//第一个参数size(可选)指定上限集合的  //最大大小(以字节为单位),目前限制为6142800字节。 如果cappedtrue,那么还需要指定此字段的值。第二个参数max(可选) //指定上限集合中允许的最大文档数。目前为10000 第三个参数capped(可选)如果为true,则启用封闭的集合。上限集合是固定大 //小的集合,它在达到其最大大小时自动覆盖其最旧的条目。 如果指定true,则还需要指定size参数。
         DBCollection dBCollection=mongoTemplate.createCollection("mycol",collectionOptions);                                                      注:mongoTemplate.getCollection("mycol").drop() 删除一个指定集合

5、集合的使用:例如增删改查

1)使用实体对集合进行增删改查

@Component
public class PersonDaoImpl implements PersonDao {

    @Autowired
    private MongoTemplate mongoTemplate;

/**
     * 创建对象
     * @param person
     */
    @Override
    public void savePerson(PersonEntity person) {
        mongoTemplate.save(person);//如果集合不存在,则按照实体的属性创建集合结构
    }

    /**
     * 根据用户名查询对象
     * @param zhName
     * @return
     */
    @Override
    public PersonEntity findPersonByZhName(String zhName) {
        Query query=new Query(Criteria.where("zhName").is(zhName));
        query.with(new Sort(new Order(Direction.ASC,"zhName")));
        PersonEntity person=  mongoTemplate.findOne(query , PersonEntity.class);
        return person;
    }

    /**
     * 更新对象
     * @param person
     */
    @Override
    public int updatePerson(PersonEntity person) {
        Query query=new Query(Criteria.where("id").is(person.getId()));
        Update update= new Update().set("zhName", person.getZhName()).set("passWord", person.getPassWord());
        //更新查询返回结果集的第一条
        WriteResult result =mongoTemplate.updateFirst(query,update,PersonEntity.class);
        //更新查询返回结果集的所有
        // mongoTemplate.updateMulti(query,update,PersonEntity.class);
        if(result!=null)
            return result.getN();
        else
            return 0;
    }

    /**
     * 删除对象
     * @param id
     */
    @Override
    public void deleteUserById(Long id) {
        Query query=new Query(Criteria.where("id").is(id));
        mongoTemplate.remove(query,PersonEntity.class);
    }

}

2)根据java命令对已存在的集合生成指定结构                                                                                                                                 

 @Override                                          
    public void addData() {
        DBCollection dBCollection=mongoTemplate.getCollection("mycol");
        if(dBCollection==null) {
            CollectionOptions collectionOptions=new CollectionOptions(6142800,10000,true);
            dBCollection=mongoTemplate.createCollection("mycol",collectionOptions);
        }
        //添加操作  
        //下面分别是创建文档的几种方式:1. .append()  
 
        DBObject english = new BasicDBObject().append("name","english").append("score", 5).append("id",1);  
        dBCollection.insert(english);  
        //2.put()
        DBObject math = new BasicDBObject();  
        math.put("id", 2);  
        math.put("name", "math");  
        math.put("score", 10);  
        dBCollection.insert(math);  
        //3. 通过map
        Map<String,Object> map = new HashMap<String,Object>();  
        map.put("name","physics" );  
        map.put("score", 10);  
        map.put("id", 3);  
        DBObject physics= new BasicDBObject(map);  
        dBCollection.insert(physics);  
        // 4. 将json转换成DBObject对象
        String json ="{'name':'chemistry','score':10,'id':4}";  
        DBObject chemistry =(DBObject)JSON.parse(json);  
        dBCollection.insert(chemistry);  
        //4.1.1将json转换成DBObject对象添加内嵌文档  
        String json2 =" {'name':'english','score':10,'teacher':[{'name':'柳松','id':'1'},{'name':'柳松松','id':2}]}";  
        DBObject english2= (DBObject)JSON.parse(json2);  
        dBCollection.insert(english2);                                                                                                                                                    
    }

//常用操作

@Override
    public void mongoDbOperate() {
        try { 
            DBCollection dBCollection=mongoTemplate.getCollection("score");
            if(dBCollection==null) {
                CollectionOptions collectionOptions=new CollectionOptions(6142800,10000,true);
                dBCollection=mongoTemplate.createCollection("score",collectionOptions);
            }
        /*  //批量添加     

         List<DBObject> documents=new ArrayList<DBObject>();
            for(int i=0;i<10;i++) {
                DBObject query=new BasicDBObject();
                query.put("name", i);
                query.put("subject", "语文"+i%3);
                query.put("score",Math.random()*100);
                query.put("status",i%2);
                documents.add(query);
            }
            dBCollection.insert(documents); */
           /* //mogonDb mapReduce使用                                                                                                                                                           String map = "function() { "+   
                    "emit(this.subject,this.score);}";  
              String reduce = "function(key, values) { " +  
                                       "var sum = 0; " +  
                                       "var count = 0; " +  
                                       "values.forEach(function(score) { " +  
                                       "sum += score; "+  
                                       "count += 1"+  
                                       "}); " +  
                                       "var avg = sum/count; " +
                                       "return {totalScore: sum,avg:avg,count:count};} ";  
              DBObject quesry=new BasicDBObject();
              quesry.put("status", 0);//取出状态为0的数据进行mapReduce运算
              MapReduceCommand cmd = new MapReduceCommand(dBCollection, map, reduce,  null, MapReduceCommand.OutputType.INLINE, quesry);  
              MapReduceOutput out = dBCollection.mapReduce(cmd);  
              for (DBObject o : out.results()) {  
                  System.out.println(o.toString());  
              }  */

            /*//根据多条件查询数据以及将结果排序
              DBObject query=new BasicDBObject();
              query.put("status", 0);//取出status为0的数据
              query.put("name", new BasicDBObject("$type","int"));//取出name属性中数据类型为int的数据 具体对应关系可参照MongoDB $type 操作符int等价于16
              //query.put("name", new BasicDBObject("$type",16));//取出name属性中数据类型为int的数据 具体对应关系可参照MongoDB $type 操作符 int等价于16
             // query.put("score", new BasicDBObject("$gt",30).append("$lt", 90));//取出score大于30 小于90分的数据
              DBCursor dbCursor= dBCollection.find(query).sort(new BasicDBObject("name",1));//new BasicDBObject("name",1) 按照name属性的升序方式排序
              dBCollection.setWriteConcern(WriteConcern.SAFE);
              try {  
                  while (dbCursor.hasNext()) {  
                      System.out.println(dbCursor.next());  
                  }  
              } finally {  
                  dbCursor.close();  
              }*/ 
              //MongoDB中聚合的方法使用aggregate()
              DBObject totalscore = new BasicDBObject("$sum","$score");  //依据subject进行分组后对score求总分
              DBObject avg = new BasicDBObject("$avg","$score");  /依据subject进行分组后对score求平均分
              DBObject groupFileds = new BasicDBObject("_id", "$subject"); //依据subject进行分组
              groupFileds.put("totalscore", totalscore);  
              groupFileds.put("avg", avg);  
              groupFileds.put("max", new BasicDBObject("$max","$score"));  //依据subject进行分组后对score求最大值
              groupFileds.put("min", new BasicDBObject("$min","$score"));  //依据subject进行分组后对score求最小值
              groupFileds.put("count", new BasicDBObject("$sum",1));  //依据subject进行分组后,统计各个分组项的个数
              DBObject group = new BasicDBObject("$group", groupFileds);  
              DBObject match = new BasicDBObject("$match", new BasicDBObject("status",0));  //取出status为0的数据 然后依据subject进行分组
              DBObject sort = new BasicDBObject("$sort",new BasicDBObject("_id",1));//依据_id属性升序排列
              AggregationOutput output = dBCollection.aggregate(Arrays.asList(match,group,sort));
              //注意:管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。
              //MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。
              //表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。
              //由此可知MongoDB的聚合管道的先后顺序是很重要的,因为上一管道操作命令的结果会作为下一个管道操作的参数

              List<DBObject> dbObjects = (List<DBObject>) output.results(); 
              for(DBObject dBObject:dbObjects) {
                  System.out.println(dBObject.toString());
              }
        } catch (Exception e) {  
              e.printStackTrace();  
         }
    }

更多的mongoDB的使用方式参见:http://www.runoob.com/mongodb/mongodb-tutorial.html

猜你喜欢

转载自blog.csdn.net/QQ1012470073/article/details/85089074