SpringBoot2.x集成Mongodb

1. 加入依赖

        
        
            org.springframework.boot
            spring-boot-starter-data-mongodb
        

2. 连接配置

spring:
  data:
    mongodb:
      host: localhost   #同127.0.0.1
      port: 27017
      database: test    #指定操作的数据库

3. 对Monodb进行查询

详细代码见附录。

3.1 简单查询

数据准备:

db.stus.insert([
{ "_id" : ObjectId("5e64bf9a2a16affa306b8b93"), "name" : "数组1", "age" : "18","gender" : "男","scope" : 77.0},
{"_id" : ObjectId("5e64cc2b6ef8da42f1854b11"), "name" : "数组2","age" : "13", "gender" : "女","scope" : 89},
{ "_id" : ObjectId("5e663e7379bbd40eb81de8eb"),"name" : "数组3","age" : "13","gender" : "男","scope" : 60},
{"_id" : ObjectId("5e6648d179bbd40eb81de8ee"),"name" : "数组4","age" : "14","gender" : "男","scope" : 59},
{"_id" : ObjectId("5e6648d479bbd40eb81de8f0"),"name" : "数组5","age" : "18","gender" : "男","scope" : 68},
{"_id" : ObjectId("5e6648d879bbd40eb81de8f1"),"name" : "数组6","age" : "24","gender" : "男","scope" : 56},
{"_id" : ObjectId("5e6648d979bbd40eb81de8f2"),"name" : "数组7","age" : "25","gender" : "女", "scope" : 90},
{ "_id" : ObjectId("5e6648d979bbd40eb81de8f3"),"name" : "数组8","age" : "24","gender" : "男","scope" : 98},
{ "_id" : ObjectId("5e6648d979bbd40eb81de8f4"),"name" : "数组9", "age" : "18","gender" : "男","scope" : 45},
{ "_id" : ObjectId("5e6648d979bbd40eb81de8f5"),"name" : "数组10", "age" : "14", "gender" : "女", "scope" : 67}
]);

1. 对数据进行简单查询:

/** 
 * Criteria—条件 
 * Sort—排序 
 * Query—查询语句 
 * findOne(Query query, Class entityClass)会获取传入的entityClass名的`简单类名`去寻找集合。 
 * findOne(Query query, Class entityClass, String collectionName) 也可以使用该方法指定集合 
 */  
//常规查询操作  
public static void find() {  
    //排序(降序处理)  
    Sort sort = new Sort(Sort.Direction.DESC, "scope");  
    //配置查询的条件  
    Query query = new Query(Criteria.where("gender").is("男")).  //先$match筛选  
            with(sort).    //在$sort排序  
            limit(1);     //在$limit截取  
    Student student = mongoTemplate.findOne(query, Student.class, "stus");  
    log.info("MongoDB最终输出:" + JSON.toJSONString(student));  
}  

最终返回结果:

MongoDB最终输出:{"age":"24","gender":"男","id":"5e6648d979bbd40eb81de8f3","name":"数组8","scope":"98"}

2. 对数据进行查询

/** 
 * scope字段大于60小于90 
 */  
public static void find2() {  
    Query query = new Query(Criteria.where("scope").gt(60).lt(90));  
    List students = mongoTemplate.find(query, Student.class, "stus");  
    log.info(JSON.toJSONString(students));  
}  

最终返回结果:

[{"age":"18","gender":"男","id":"5e64bf9a2a16affa306b8b93","name":"数组1","scope":"77.0"},
{"age":"13","gender":"女","id":"5e64cc2b6ef8da42f1854b11","name":"数组2","scope":"89"},
{"age":"18","gender":"男","id":"5e6648d479bbd40eb81de8f0","name":"数组5","scope":"68"},
{"age":"14","gender":"女","id":"5e6648d979bbd40eb81de8f5","name":"数组10","scope":"67"}]

3.2 聚合查询

public class Aggregation {
    public static Aggregation newAggregation(AggregationOperation... operations) {
        return new Aggregation(operations);
    }

    public static  TypedAggregation newAggregation(Class type, AggregationOperation... operations) {
        return new TypedAggregation(type, operations);
    }

    public static  TypedAggregation newAggregation(Class type, List operations) {
        return newAggregation(type, operations.toArray(new AggregationOperation[operations.size()]));
    }

    public static Aggregation newAggregation(List operations) {
        return newAggregation(operations.toArray(new AggregationOperation[operations.size()]));
    }
}

聚合函数的原生语法:

db.collection.aggregate(pipeline,options);
  • pipeline一系列的聚合操作,可以对文档进行一连串的处理,包括筛选(match)、映射(project)、分组(group)、排序(sort)、限制(limit)、跳跃(skip)
  • options(可选)控制聚合函数的执行的一些参数。

org.springframework.data.mongodb.core.aggregation.Aggregation提供了上述4个newAggregation方法,来接收pipeline数组。即AggregationOperation集合。

案例1:

public static void find3() {  
    TypedAggregation typedAggregation = Aggregation.newAggregation(Student.class,  
            Aggregation.match(Criteria.where("scope").gt(60).lt(90))  //相当于where操作  
    );  
    //打印出原生的聚合命令  
    log.info("输出聚合对象{}", typedAggregation.toString());  
    AggregationResults aggregate = mongoTemplate.aggregate(typedAggregation, "stus", BasicDBObject.class);  
    //输出结果  
    List mappedResults = aggregate.getMappedResults();  
    log.info("输出结果{}", mappedResults.toString());  
}  

输出结果:

输出聚合对象{ "aggregate" : "__collection__", "pipeline" : [{ "$match" : { "scope" : { "$gt" : 60, "$lt" : 90 } } }] }
输出结果[Document{{_id=5e64bf9a2a16affa306b8b93, name=数组1, age=18, gender=男, scope=77.0}},
 Document{{_id=5e64cc2b6ef8da42f1854b11, name=数组2, age=13, gender=女, scope=89}},
 Document{{_id=5e6648d479bbd40eb81de8f0, name=数组5, age=18, gender=男, scope=68}},  
 Document{{_id=5e6648d979bbd40eb81de8f5, name=数组10, age=14, gender=女, scope=67}}]

注:上述日志输出的“聚合对象”是原生的Mongodb语句,可进行参考

案例2:

数据准备

    db.items.insert([
    { "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-03-01T08:00:00Z") },
    { "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-03-01T09:00:00Z") },
    { "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-03-15T09:00:00Z") },
    { "_id" : 4, "item" : "xyz", "price" : 5, "quantity" : 20, "date" : ISODate("2014-04-04T11:21:39.736Z") },
    { "_id" : 5, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-04-04T21:23:13.331Z") }
    ]);
    public static void find4() {
        List collection = new ArrayList<>();
        collection.add(10.0);
        collection.add(5.0);
        TypedAggregation itemsTypedAggregation = Aggregation.newAggregation(Items.class,
                Aggregation.match(Criteria.where("price").in(collection)),
                Aggregation.project("date").andExpression("month(date)").as("month"),
                Aggregation.group("month").count().as("num"),
                Aggregation.project("num").and("month").previousOperation()
        );
        //打印表达式
        log.info("聚合表达式:{}",itemsTypedAggregation.toString());
        AggregationResults result = mongoTemplate.aggregate(itemsTypedAggregation, BasicDBObject.class);
        //打印数据
        log.info(JSON.toJSONString(result.getMappedResults()));
    }

最终会在Mongodb中执行如下代码:

db.items.aggregate(
[{ "$match" : { "price" : { "$in" : [10.0, 5.0] } } }, //使用in去筛选
{ "$project" : { "date" : 1, "month" : { "$month" : "$date" } } }, //映射数据
{ "$group" : { "_id" : "$month", "num" : { "$sum" : 1 } } }, //以映射的数据分组,在进行统计
{ "$project" : { "num" : 1, "_id" : 0, "month" : "$_id" } }] //打印统计数据和month月份信息
)   

最终结果:

[{"num":2,"month":3},{"num":2,"month":4}]

案例3:group中使用表达式进行分组

Mongodb(2)—聚合操作(1)原生命令

按date的月份、日期、年份对文档进行分组,并计算total price和average quantity,并汇总各文档的数量。

image.png
错误示例.png

正确示例:

    public static void find6() {
        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.project("quantity")
                        .andExpression("year(date)").as("year")
                        .andExpression("month(date)").as("month")
                        .andExpression("dayOfMonth(date)").as("day")
                        .andExpression("price * quantity").as("grossPrice"),
                //     .and("quantity"), 等效于project("quantity")
                Aggregation.group("month", "year", "day")
                        .sum("grossPrice").as("totalPrice")
                        .avg("quantity").as("averageQuantity")
                        .count().as("count")
        );
        log.info("聚合表达式:{}", aggregation);
        AggregationResults items = mongoTemplate.aggregate(aggregation, "items", BasicDBObject.class);
        log.info(JSON.toJSONString(items.getMappedResults()));
    }

输出结果:

[{"month":4,"year":2014,"day":4,"totalPrice":200,"averageQuantity":15,"count":2},
{"month":3,"year":2014,"day":15,"totalPrice":50,"averageQuantity":10,"count":1},
{"month":3,"year":2014,"day":1,"totalPrice":40,"averageQuantity":1.5,"count":2}]

注意:使用group分组后,_id字段是分组字段!

4. CURD操作

@Service
@Slf4j
public class MongoDbService {

    @Autowired
    private MongoTemplate mongoTemplate;


    public String saveObj(Book book) {

        book.setCreateTime(new Date());
        book.setUpdateTime(new Date());
        Book save = mongoTemplate.save(book);
        return "添加成功";
    }


    public List findAll() {
        return mongoTemplate.findAll(Book.class);
    }

    public Book getBookById(String id) {
        Query query = new Query(Criteria.where("_id").is(id));
        return mongoTemplate.findOne(query, Book.class);
    }

    public Book getBookByName(String name) {
        Query query = new Query(Criteria.where("name").is(name));
        return mongoTemplate.findOne(query, Book.class);
    }

    public String updateBook(Book book) {
        Query query = new Query(Criteria.where("_id").is(book.getId()));
        Update update = new Update().
                set("publish", book.getPublish()).
                set("info", book.getInfo()).
                set("updateTime", new Date());
        //更新查询返回结果集的第一条
        UpdateResult updateResult = mongoTemplate.updateFirst(query, update, Book.class);
        log.info(JSON.toJSONString(updateResult));
        return "success";
//        return updateResult.getModifiedCount();
    }

    //删除对象
    public String deleteBook(Book book) {
        DeleteResult remove = mongoTemplate.remove(book);
        log.info(JSON.toJSONString(remove));
        return "success";
    }

    //根据id去删除

    public String deleteBookById(String id) {
        Book book = getBookById(id);
        return deleteBook(book);
    }

}
@RestController
@Slf4j
public class BaseController {

    @Autowired
    private MongoDbService mongoDbService;

    @PostMapping("/mongo/save")
    public String saveObj(@RequestBody Book book) {return mongoDbService.saveObj(book);}

    @GetMapping("/mongo/findAll")
    public List findAll() {return mongoDbService.findAll();}

    @GetMapping("/mongo/findOne")
    public Book findOne(@RequestParam String id) {return mongoDbService.getBookById(id);}

    @GetMapping("/mongo/findOneByName")
    public Book findOneByName(@RequestParam String name) {return mongoDbService.getBookByName(name);}

    @PostMapping("/mongo/update")
    public String update(@RequestBody Book book) {return mongoDbService.updateBook(book);}

    @PostMapping("/mongo/delOne")
    public String delOne(@RequestBody Book book) {return mongoDbService.deleteBook(book);}

    @GetMapping("/mongo/delById")
    public String delById(@RequestParam String id) {return mongoDbService.deleteBookById(id);}
}
@Data
public class Book {
    private String id;
    //价格
    private Integer price;
    //书名
    private String name;
    //简介
    private String info;
    //出版社
    private String publish;
    //创建时间
    private Date createTime;
    //修改时间
    private Date updateTime;
}

附录

使用如下代码去获取mongoTemplate对象,可以将对Mongodb的操作整合为一个工具类方法,直接通过静态方法便可以完成调用。

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class SpringContextUtil implements ApplicationContextAware {

    private static ApplicationContext context;
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        log.info("ApplicationContextAware初始化完毕");
         SpringContextUtil.context=applicationContext;

    }

    public static  T getBean(String name, Class requiredType){
        return context.getBean(name, requiredType);
    }

    public static  T getBean(Class requiredType){
        return context.getBean(requiredType);
    }

    /**
     * 获取beanName数组
     * @return
     */
    public static String[] getBeanNamesForType(Class clazz){
        return context.getBeanNamesForType(clazz);
    }
}

package com.tellme.config.mongodb;

import com.alibaba.fastjson.JSON;
import com.mongodb.BasicDBObject;
import com.tellme.config.context.SpringContextUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.Iterator;
import java.util.List;
@Slf4j
public class MongodbUtils {

    //在Spring容器中获取Bean
    private static MongoTemplate mongoTemplate = SpringContextUtil.getBean("mongoTemplate", MongoTemplate.class);


    @Data
    private class Items {
        private String id;
        private String item;
        private double price;
        private double quantity;
        private Date date;
    }

    @Data
    private class Student {
        private String id;
        private String name;
        private String age;
        private String gender;
        private String scope;
    }
}

推荐阅读

MongoDB mongoTemplate查询条作组合例子(超多案例)

按时间进行分组

历史文章

win7下安装mongodb4.2.3及可视化工具

Mongodb(1)—基本CRUD操作

Mongodb(2)—聚合操作(1)原生命令

SpringBoot2.x集成Mongodb

你可能感兴趣的:(SpringBoot2.x集成Mongodb)