美文网首页设计方案
SpringBoot2.x集成Mongodb

SpringBoot2.x集成Mongodb

作者: 小胖学编程 | 来源:发表于2020-03-10 21:20 被阅读0次

    1. 加入依赖

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

    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<T> entityClass)会获取传入的entityClass名的`简单类名`去寻找集合。 
     * findOne(Query query, Class<T> 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<Student> 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 <T> TypedAggregation<T> newAggregation(Class<T> type, AggregationOperation... operations) {
            return new TypedAggregation<T>(type, operations);
        }
    
        public static <T> TypedAggregation<T> newAggregation(Class<T> type, List<? extends AggregationOperation> operations) {
            return newAggregation(type, operations.toArray(new AggregationOperation[operations.size()]));
        }
    
        public static Aggregation newAggregation(List<? extends AggregationOperation> 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<Student> typedAggregation = Aggregation.newAggregation(Student.class,  
                Aggregation.match(Criteria.where("scope").gt(60).lt(90))  //相当于where操作  
        );  
        //打印出原生的聚合命令  
        log.info("输出聚合对象{}", typedAggregation.toString());  
        AggregationResults<BasicDBObject> aggregate = mongoTemplate.aggregate(typedAggregation, "stus", BasicDBObject.class);  
        //输出结果  
        List<BasicDBObject> 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<Double> collection = new ArrayList<>();
            collection.add(10.0);
            collection.add(5.0);
            TypedAggregation<Items> 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<BasicDBObject> 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<BasicDBObject> 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<Book> 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<Book> 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> T getBean(String name, Class<T> requiredType){
            return context.getBean(name, requiredType);
        }
    
        public static <T> T getBean(Class<T> 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

        本文链接:https://www.haomeiwen.com/subject/mdhbhhtx.html