当前位置:   article > 正文

MongoDB详解(有这一篇就够了)

mongodb

一、mongoDB简介

MongoDB 是由 C++ 语言编写的,基于分布式文件存储的数据库,是一个介于关系数据库和非关系数据库之间的产品,是最接近于关系型数据库的 NoSQL 数据库。
MongoDB 旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于JSON对象。字段值可以包含其他文档,数组及文档数组

类似于
在这里插入图片描述

  1. MongoDB优点:数据处理能力强,内存级数据库,查询速度快,扩展性强,只是不支持事务
  2. 使用场景:
    1、应用不需要事务;
    2、数据模型无法确定,经常发生变更;
    3、应用存储的数据很大达到TB级别以上;
    4、应用需要大量的地理位置查询
    简单的来说就是数据量比较大,而且主要是查询操作,而且不需要事务支持

二、MongoDB与Mysql的区别

在这里插入图片描述

三、使用

1、安装

安装地址: https://www.mongodb.com/try/download/community
github: https://github.com/mongodb/

下载

在这里插入图片描述

2、软件安装步骤

img

img

​ 选Custom

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
1.我们需要去把他的环境变量配置一下:右击此电脑=>属性=>高级系统设置=>环境变量=>找到Path双击进去,新建,内容是刚刚安装的MongoDB的Bin文件夹位置,我装的是E盘,路径为E:\MongoDB\bin
2.配置完环境变量,我们在C盘的根目录去创建一个data文件夹,在里面再建一个db文件夹
3.我们打开cmd(win+r打开巡行输入cmd),输入mongod,他会跑出来一堆代码,这时候我们再去看刚刚新建的db文件夹,里面已经有东西了
4.我们再新建一个cmd,输入mongo(mongod用来启动服务器,mongo用来启动客户端),出现 >就差不多了

3、数据的增删改查

3.1添加数据(文档)

#**新增数据2种方式**
db.task.save({"name":"zhangsan"});
db.task.insert({"name":"zhangsan"});
  • 1
  • 2
  • 3

3.2 查询数据

**#查询所有数据2种写法**
db.task.find()
db.getCollection("task").find()
**#条件查询**
db.task.find({'name':'张三'})
  • 1
  • 2
  • 3
  • 4
  • 5

3.3 修改数据

**#(1)update首条  update:遇到满足条件的第一条数据修改**
db.task.update({"name":"zhangsan"},{$set:{"name":"lisi"}})

**#(2)update多条 updateMany :修改所有满足条件的**
db.task.updateMany({"name":"zhangsan"},{$set:{"name":"lisi"}})

**#(3)updateOne updateOne:修改满足条件的第一条数据**
db.task.updateOne({"name":"zhangsan"},{$set:{"name":"lisi"}})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

3.4 删除数据

**(#1)删除**
db.task.remove({name:"zhangsan"})
**#(2)删除所有**
db.task.remove({})
  • 1
  • 2
  • 3
  • 4

3.5 聚合 aggregate (注意以下的操作符必须在aggregate聚合函数中使用)

命令功能描述
$project指定输出文档里的字段.
$match选择要处理的文档,与fine()类似。
$limit限制传递给下一步的文档数量。
$skip跳过一定数量的文档。
$unwind扩展数组,为每个数组入口生成一个输出文档。
$group根据key来分组文档。
$sort排序文档。
$geoNear选择某个地理位置附近的的文档。
$out把管道的结果写入某个集合。
$redact控制特定数据的访问。
$lookup多表关联(3.2版本新增)
3.5.1 分组 $group (根据名称分组并求和)
db.task.aggregate([        
        {
          $group :{
              _id : "$name",
              num_tutorial : {$sum : 1}
            }
           }
          ])
//_id分组字段如果有多个则需要这样写, $sum是累加后面1代表匹配的每一条数据加1,当然他也可以用来求和只需要将1替换成字段名称就行
db.task.aggregate([
  {
    $group: {
      _id: {
        size: "$size",
        color: "$color"
      },
       num_tutorial: { $sum: "1" }
    }
  }
])      
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
3.5.2 文档筛选 $match(根据名称分组并且同级类型为L型号的商品有那些)
//match为聚合函数的查询条件$addToSet,$addToSet 累加器操作符用于向一个数组或集合字段中添加唯一的元素。他与$sum是有区别的names是新加字段
  这个查询的意思是根据name字段分组让后查询出数据中type为L的数据将商品的name添加到names里面去
db.task.aggregate([
    {
        $match: { "type": "L" },
    },
    {
        $group: {
            "_id": "$name",
            "names": { "$addToSet": "$name" }
        }
    }
  ])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
3.5.3 连表查询 $lookup
//连表查询返回前五条数据
db.task.aggregate([
 
    {
       $lookup: {
           from: "docs", //附表名称
           localField: "_id.name",//主表关联字段
           foreignField: "name",//附表关联字段
           as: "child"//当连接查询查询出来之后,外表的查询结果会在本表查询结果中开辟一个新的字段进行存储,而字段名就是这个字段设置的,只有一个存储结果时                        //为单独的对象字段,多个结果时为对象数组 :
        }
    }, 
    {
       $project: {
            names: "$names",
            type: "$type",
       // 添加其他你想要显示的字段
    }
  },
  {
       $limit: 5 // 返回前 5 条文档
  }
])

//连表查询跳过前五条数据
db.task.aggregate([
 
    {
       $lookup: {
           from: "docs", //附表名称
           localField: "_id.name",//主表关联字段
           foreignField: "name",//附表关联字段
           as: "child"//当连接查询查询出来之后,外表的查询结果会在本表查询结果中开辟一个新的字段进行存储,而字段名就是这个字段设置的,只有一个存储结果时                        //为单独的对象字段,多个结果时为对象数组 :
        }
    }, 
    {
       $project: {
            names: "$names",
            type: "$type",
       // 添加其他你想要显示的字段
    }
  },
 {
    $skip: 5 // 跳过前 5 条文档
  },
  {
    $sort: { "_id": 1 }//升序排序(1升序,-1降序)
  }
])
  • 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
3.5.4 限制文档 $redact
//如果 fieldName 字段的值大于等于 10,则保留文档内容($$DESCEND),否则删除文档内容($$PRUNE)。  
db.collection.aggregate([
  // 其他聚合阶段
  {
    $redact: {
      $cond: {
        if: { $gte: ["$fieldName", 10] },
        then: "$$DESCEND",
        else: "$$PRUNE"
      }
    }
  }
])
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

4、总结一些常用操作命令

img

img

5、在springBoot项目中整合MongoDB数据库

1.引入依赖

      <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
  • 1
  • 2
  • 3
  • 4

2.配置连接参数

    data:
    mongodb:
      host: 10.0.26.194
      username: wanttop2
      password: Testwanttop2
      port: 27017
      authentication-database: wanttop2
      database: wanttop2
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

3.MongoDB的CRUD(有2种方法实现)

3.1 创建实体类
 ```
 package com.pkslow.mongo.model;
 
 import org.springframework.data.annotation.Id;
 import java.util.Date;
 
 public class User {
     @Id
     private String userId;
     private String name;
     private Integer age;
     private Date createTime = new Date();
 
     public String getUserId() {
         return userId;
     }
 
     public void setUserId(String userId) {
         this.userId = userId;
     }
 
     public String getName() {
         return name;
     }
 
     public void setName(String name) {
         this.name = name;
     }
 
     public Integer getAge() {
         return age;
     }
 
     public void setAge(Integer age) {
         this.age = age;
     }
 
     public Date getCreateTime() {
         return createTime;
     }
 
     public void setCreateTime(Date createTime) {
         this.createTime = createTime;
     }
 }
 ```
  • 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
方式一:使用MongoRepository
第一步定义数据访问层UserRepository

使用过Spring Jpa的都清楚,Repository实际就是用于操作数据库的类。在非关系型数据库MongoDB的整合中,也是一样的。Spring会帮我们实现好对应接口的方法,开发人员连SQL都不用写,非常省心。代码如下:

package com.pkslow.mongo.dal;

import com.pkslow.mongo.model.User;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends MongoRepository<User, String> {
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
第二步实现Controller
package com.pkslow.mongo.contrlloer;

import com.pkslow.mongo.dal.UserRepository;
import com.pkslow.mongo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private final UserRepository userRepository;

    public UserController(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    @GetMapping("")
    public List<User> getAllUsers() {
        return userRepository.findAll();
    }

    @GetMapping("/{userId}")
    public User getByUserId(@PathVariable String userId) {
        return userRepository.findById(userId).orElse(new User());
    }

    @PostMapping("")
    public User addNewUser(@RequestBody User user) {
        return userRepository.save(user);
    }

    @DeleteMapping("/{userId}")
    public String delete(@PathVariable String userId) {
        User user = new User();
        user.setUserId(userId);
        userRepository.deleteById(userId);
        return "deleted: " + userId;
    }

    @PutMapping("")
    public User update(@RequestBody User user) {
        return userRepository.save(user);
    }
}
  • 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
方式二:使用MongoTemplate(推荐使用)

这个就比较符合我们写代码习惯

MongoTemplate是Spring Data MongoDB依赖提供的一个主要类,用于在Spring应用程序中与MongoDB数据库进行交互。里面有丰富的操作数据的方法

//使用也非常简单直接在service层注入就行  
@Autowired
private MongoTemplate mongoTemplate;
  • 1
  • 2
  • 3

当然如果你不需要这么多的使用方法可以自己根据需求自己封装一个工具类

下面是常用的mongoDB的方法封装工具类

@Component
public class MongoDBUtil {

    public static MongoDBUtil mongodbUtil;

    @PostConstruct
    public void init() {
        mongodbUtil = this;
        mongodbUtil.mongoTemplate = this.mongoTemplate;
    }

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 查询全部数据
     *
     * @param entity 实体类class
     * @param collName 集合名称
     * @return
     */
    public static <T> List<T> queryAll(Class<T> entity, String collName) {

        return mongodbUtil.mongoTemplate.findAll(entity, collName);
    }

    public static <T> List<T> queryAll(Class<T> entity) {

        return mongodbUtil.mongoTemplate.findAll(entity);
    }




    /**
     * 根据id查询集合中的数据
     *
     * @param id 集合数据id
     * @param entity 实体类class
     * @param collName 集合名称
     * @return
     */
    public static <T> T queryById(Long id, Class<T> entity, String collName) {

        return mongodbUtil.mongoTemplate.findById(id, entity, collName);
    }

    public static <T> T queryById(Long id, Class<T> entity) {

        return mongodbUtil.mongoTemplate.findById(id, entity);
    }

    /**
     * 查询集合中的一条数据
     *
     * @param query
     * @param entity
     * @param collName
     * @param <T>
     * @return
     */
    public static <T> T findOne(Query query, Class<T> entity, String collName) {

        return mongodbUtil.mongoTemplate.findOne(query, entity, collName);
    }

    public static <T> T findOne(Query query, Class<T> entity) {

        return mongodbUtil.mongoTemplate.findOne(query, entity);
    }

    /**
     * 根据条件查询集合中的数据
     *
     * @param query 查询条件
     * @param entity 实体类class
     * @param collName 集合名称
     * @return
     */
    public static <T> List<T> conditionalQuery(Query query, Class<T> entity, String collName) {

        return mongodbUtil.mongoTemplate.find(query, entity, collName);
    }

    public static <T> List<T> conditionalQuery(Query query, Class<T> entity) {

        return mongodbUtil.mongoTemplate.find(query, entity);
    }

    /**
     * 根据条件分页查询集合中的数据
     *
     * @param query 查询条件
     * @param entity 实体类class
     * @param collName 集合名称
     * @return
     */
    public static <T> IPage<T> queryListPage(Page<T> page, Query query, Class<T> entity, String collName) {

        // 数量
        long count = mongodbUtil.mongoTemplate.count(query, entity, collName);

        // 数据
        query.skip((page.getCurrent() - 1) * page.getSize());//当前页
        query.limit((int) page.getSize());//每页条数
        List<T> list = mongodbUtil.mongoTemplate.find(query, entity, collName);
        // 总页数
        int pages = (int) Math.ceil((double) count / (double) page.getSize());
        page.setRecords(list);
        page.setTotal(count);
        page.setPages(pages);
        page.setCurrent(page.getCurrent());

        return page;
    }

    public static <T> IPage<T> queryListPage(Page<T> page, Query query, Class<T> entity) {
        // 数据
        List<T> list = mongodbUtil.mongoTemplate.find(query, entity);
        // 数量
        long count = mongodbUtil.mongoTemplate.count(query, entity);
        // 总页数
        int pages = (int) Math.ceil((double) count / (double) page.getSize());
        page.setRecords(list);
        page.setTotal(count);
        page.setPages(pages);
        page.setRecords(list);

        return page;
    }

    public static <T> void batchInsert(List<T> entities, String collName) {
        MongoCollection<T> collection = (MongoCollection<T>) mongodbUtil.mongoTemplate.getCollection(collName);
        List<InsertOneModel<? extends T>> insertModels = new ArrayList<>();
        for (T entity : entities) {
            insertModels.add(new InsertOneModel<>(entity));
        }
        BulkWriteOptions options = new BulkWriteOptions();
        options.ordered(false);
        BulkWriteResult result = collection.bulkWrite(insertModels, options);
    }
    /**
     * 查询返回指定字段
     *
     * @param fields   需要返回的指定字段
     * @param clazz    返回实体类class
     * @param collName 集合名称
     * @param map      Map<查询条件key,查询条件value>
     * @param returnId 返回字段的时候id默认为返回,不返回id则field设置
     * @return
     */
    public static <T> List<T> findDesignField(List<String> fields, Map<String, Object> map, Class<T> clazz, String collName, boolean returnId) {
        Criteria criteria = null;
        for (String key : map.keySet()) {
            Assert.notNull(key, "查询条件不能为null");
        }
        for (String key : map.keySet()) {
            criteria = Criteria.where(key).is(map.get(key));
        }
        Query query = new Query(criteria);
        for (String field : fields) {
            query.fields().include(field);
        }
        if (!returnId) {
            query.fields().exclude("id");
        }
        return mongodbUtil.mongoTemplate.find(query, clazz, collName);
    }

    /**
     * 查询数据数量
     *
     * @param query 查询条件
     * @param entity 实体class
     * @param collName 集合名称
     * @return
     */
    public static Long count(Query query, Class<?> entity, String collName) {

        return mongodbUtil.mongoTemplate.count(query, entity, collName);
    }

    public static Long count(Query query, Class<?> entity) {

        return mongodbUtil.mongoTemplate.count(query, entity);
    }

    public static Long count(Query query, String collName) {

        return mongodbUtil.mongoTemplate.count(query, collName);
    }

    /**
     * 将一条数据存储到集合中
     *
     * @param entity 实体class
     * @param collName 集合名称
     */
    public static <T> T save(T entity, String collName) {

        return mongodbUtil.mongoTemplate.insert(entity, collName);
    }

    public static <T> T save(T entity) {

        return mongodbUtil.mongoTemplate.insert(entity);
    }

    /**
     * 存储多条数据到集合中
     *
     * @param list 数据集合
     * @param collName 集合名称
     */
    public static <T> Collection<T> batchSave(Collection<? extends T> list, String collName ) {

        return mongodbUtil.mongoTemplate.insert(list, collName);
    }

    public static <T> Collection<T> batchSave(Collection<? extends T> list, Class<?> clazz ) {

        return mongodbUtil.mongoTemplate.insert(list, clazz);
    }

    public static <T> Collection<T> batchSave(Collection<? extends T> list) {

        return mongodbUtil.mongoTemplate.insertAll(list);
    }

    /**
     * 根据条件更新一条数据到集合
     *
     * @param query 查询条件
     * @param update 更新内容
     * @param clazz 实体类class
     * @param collName 集合名称
     */
    public static void updateFirst(Query query, Update update, Class<?> clazz, String collName) {

        mongodbUtil.mongoTemplate.updateFirst(query, update, clazz, collName);
    }

    public static void updateFirst(Query query, Update update, String collName) {

        mongodbUtil.mongoTemplate.updateFirst(query, update, collName);
    }

    public static void updateFirst(Query query, Update update, Class<?> clazz) {

        mongodbUtil.mongoTemplate.updateFirst(query, update, clazz);
    }

    /**
     * 根据条件更新多条数据到集合
     *
     * @param query 查询条件
     * @param update 更新内容
     * @param clazz 实体类class
     * @param collName 集合名称
     */
    public static void batchUpdate(Query query, Update update, Class<?> clazz, String collName) {

        mongodbUtil.mongoTemplate.updateMulti(query, update, clazz, collName);
    }

    public static void batchUpdate(Query query, Update update, String collName) {

        mongodbUtil.mongoTemplate.updateMulti(query, update, collName);
    }

    public static void batchUpdate(Query query, Update update, Class<?> clazz) {

        mongodbUtil.mongoTemplate.updateMulti(query, update, clazz);
    }

    /**
     * 根据条件更新多条数据到集合(如果数据不存在则新增)
     *
     * @param query 查询条件
     * @param update 更新内容
     * @param clazz 实体类class
     * @param collName 集合名称
     */
    public static void upsert(Query query, Update update, Class<?> clazz, String collName) {

        mongodbUtil.mongoTemplate.upsert(query, update, clazz, collName);
    }

    public static void upsert(Query query, Update update, String collName) {

        mongodbUtil.mongoTemplate.upsert(query, update, collName);
    }

    public static void upsert(Query query, Update update, Class<?> clazz) {

        mongodbUtil.mongoTemplate.upsert(query, update, clazz);
    }

    /**
     * 删除数据
     *
     * @param query 查询条件
     * @param entity 实体class
     * @param collName 集合名称
     */
    public static void removeData(Query query, Class<?> entity, String collName) {

        mongodbUtil.mongoTemplate.remove(query, entity, collName);
    }

    public static void removeData(Class<?> entity) {

        mongodbUtil.mongoTemplate.remove(entity);
    }

    public static void removeData(Query query) {

        mongodbUtil.mongoTemplate.remove(query);
    }

    public static void removeData(Object entity) {

        mongodbUtil.mongoTemplate.remove(entity);
    }


}

  • 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
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
1.单表查询
        // 判断 dataType 是否存在,如果存在则添加到查询条件中
        if (performanceRank.getDataType() != null) {
            query.addCriteria(Criteria.where("dataType").is(performanceRank.getDataType()));
        }
        // 判断 divisionCode 是否存在,如果存在则添加到查询条件中
        if (performanceRank.getDivisionCode() != null) {
            query.addCriteria(Criteria.where("divisionCode").is(performanceRank.getDivisionCode()));

        }

        List<SysDimensionDataMarket> sysDimensionDataMarketList = MongoDBUtil.conditionalQuery(query, SysDimensionDataMarket.class, "SysDimensionDataMarket");
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
2.多表连接查询

mongoDB中没有sql的left join 和right join 的类似的概念而是用到了lookup管道操作符
mongoDB3.2版本新增(聚合管道$lookup操作)
完整代码

    //连表
    LookupOperation cusAndInfoLookup = LookupOperation.newLookup().
                    from("SysProduct").//1.副表表名字
                    localField("prodItemCode").//2.主表的关联字段
                    foreignField("productCode").//3.副表的关联字段
                    as("SysProduct");//4.建议和1一致,结果的别名
    //如果需要多连表就在写一个
    //LookupOperation cusAndInfoLookup1 = LookupOperation.newLookup().
    //                from("SysProduct").//1.副表表名字
    //               localField("prodItemCode").//2.主表的关联字段
    //              foreignField("productCode").//3.副表的关联字段
    //                as("SysProduct");//4.建议和1一致,结果的别名
            //多表的关联条件,查询条件均传入到此
    //创建查询条件
    Criteria criteria = new Criteria();
       if (totalPerformanceCross.getDataCrossType() != null) {
                criteria.and("dataCrossType").is(totalPerformanceCross.getDataCrossType());
            }
            // 判断 areaCode 是否存在,如果存在则添加到查询条件中
            if (totalPerformanceCross.getAreaCode() != null) {
                criteria.and("areaCode").is(totalPerformanceCross.getAreaCode());
            }
            // 判断 companyCode 是否存在,如果存在则添加到查询条件中
            if (totalPerformanceCross.getCompanyCode() != null) {
                criteria.and("companyCode").is(totalPerformanceCross.getCompanyCode());
            }
            //如果查询的字段为附表则需要加上附表名字 
            if (totalPerformanceCross.getDateType() != null) {
                criteria.and("SysProduct.dateType").is(totalPerformanceCross.getDateType());
            }
      //多表的关联条件,查询条件均传入到此
            Aggregation aggregation = Aggregation.newAggregation(
                    //连表条件
                    cusAndInfoLookup,
                    //cusAndInfoLookup1,
                    //查询条件
                    Aggregation.match(criteria),
                    //最后查询结果集显示字段
                    Aggregation.project("pmLineCode", "prodItemCode", "prodItemName", "performance", "growthRate", "monthPerformance", "fullMonthPerformance", "SysProduct.productPicUrl"));
  • 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
3.2 两种方法的优缺点

MongoRepository的优点:

  1. 简化开发:MongoRepository是Spring Data MongoDB提供的高级抽象,它自动为你生成常见的CRUD方法,减少了手动编写重复代码的工作量。
  2. 高度抽象:MongoRepository通过提供一个泛型接口,使得数据访问层与具体实现解耦,你可以专注于定义领域模型和业务逻辑。
  3. 自定义查询:除了自动生成的CRUD方法外,你还可以使用方法命名规则创建自定义查询方法,Spring Data MongoDB会根据方法名自动生成查询语句。

MongoRepository的缺点:

  1. 限制功能:MongoRepository提供了一组预定义的方法,但是在处理复杂查询、聚合操作以及原生命令等方面的能力有限。对于较为复杂的查询需求,可能需要编写自定义的查询方法或者使用MongoTemplate。

MongoTemplate的优点:

  1. 强大灵活:MongoTemplate提供了大量的方法和功能,可以执行复杂的查询、聚合框架操作、原生命令等。它为你提供了更大的灵活性和控制权,适合处理复杂的业务逻辑。
  2. 数据转换:MongoTemplate支持数据的序列化和反序列化,你可以将文档映射为Java对象,并实现自定义转换逻辑。

MongoTemplate的缺点:

  1. 编写更多的代码:相对于MongoRepository,使用MongoTemplate需要编写更多的代码来执行各种操作。你需要手动构建查询、编写聚合管道、处理结果等。
  2. 学习成本高:MongoTemplate的使用相对较复杂,需要熟悉MongoDB的查询语法、聚合框架等,对于初学者来说可能需要一些时间的学习和调试。

6 使用mongodb-driver驱动包操作MongoDB(不推荐使用)

最后来简单介绍一下由mongodb 官方推出的Java连接MongoDB的驱动包,相当于JDBC驱动

为什么不推荐使用

  1. 复杂性:与原生的mongodb-driver相比,一些抽象层和框架可以提供更简单和易于使用的API,并隐藏了一些底层细节。这使得开发人员可以更快速地实现数据库操作,减少了编写样板代码的需要。

  2. 生产力和开发效率:通过使用更高级别的ORM工具,例如Spring Data MongoDB,可以通过提供自动生成的CRUD方法、查询方法和关联管理等功能,加快开发速度,减少了手动编写大量重复性代码的工作量。

  3. 社区支持和文档资源:抽象层和ORM工具通常有更大的用户社区以及更广泛的文档资源支持。这意味着你能够更容易找到解决问题的答案、学习新功能和技巧。

  4. 项目一致性:对于大型项目或团队,在整个应用程序中使用相同的抽象层或ORM工具可以提供更一致的代码风格和项目结构,从而提高维护性和团队协作效率。

1.引入 mongodb-driver依赖。

<dependency>
      <groupId>org.mongodb</groupId>
      <artifactId>mongo-java-driver</artifactId>
      <version>3.12.7</version>
    </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

2.连接MongoDB服务

2.1 没有密码连接

MongoClient mongoClient = new MongoClient(“localhost”, 27017);
  • 1

2.2有密码连接

		List<ServerAddress> adds = new ArrayList<>();
		// ServerAddress()两个参数分别为 服务器地址 和 端口
		ServerAddress serverAddress = new ServerAddress("localhost", 27017);
		adds.add(serverAddress);

		List<MongoCredential> credentials = new ArrayList<>();
		// MongoCredential.createScramSha1Credential()三个参数分别为 用户名 数据库名称 密码
		MongoCredential mongoCredential = MongoCredential.createScramSha1Credential("username", "databaseName", "password".toCharArray());
		credentials.add(mongoCredential);

		// 通过连接认证获取MongoDB连接
		MongoClient mongoClient = new MongoClient(adds, credentials);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

3.将连接信息封装成工具类

import com.mongodb.*;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoIterable;
import org.bson.Document;

import java.util.ArrayList;
import java.util.List;
public class MongoDBUtil {

	private static MongoClient mongoClient;

	static {
		System.out.println("===============MongoDBUtil初始化========================");
		List<ServerAddress> adds = new ArrayList<>();
		//ServerAddress()两个参数分别为 服务器地址 和 端口
		ServerAddress serverAddress = new ServerAddress("localhost", 27017);
		adds.add(serverAddress);
		List<MongoCredential> credentials = new ArrayList<>();
		//MongoCredential.createScramSha1Credential()三个参数分别为 用户名 数据库名称 密码
		MongoCredential mongoCredential = MongoCredential.createScramSha1Credential("username", "databaseName", "password".toCharArray());
		credentials.add(mongoCredential);
		//通过连接认证获取MongoDB连接
		mongoClient = new MongoClient(adds, credentials);
		System.out.println("==========Connect to MongoDB successfully================");
	}

	public static MongoClient getMongoClient() {
		return mongoClient;
	}
}	

  • 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

4、 数据库操作

4.1 获取所有数据库

	@Test
	public void testGetDBS() {
		MongoIterable<String> dbNames = MongoDBUtil.getMongoClient().listDatabaseNames();
		for (String db : dbNames) {
			System.out.println(db);
		}
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

4.2 获取指定数据库 - 若DB不存在则创建

	@Test
	public void testGetDB() {
		MongoDatabase db3 = MongoDBUtil.getMongoClient().getDatabase("m_db3");
		System.out.println(db3); //com.mongodb.client.internal.MongoDatabaseImpl@1d9b7cce
	}
  • 1
  • 2
  • 3
  • 4
  • 5

4.3获取某数据库中的某个集合

	@Test
	public void testGetCollection() {
		MongoDatabase db1 = MongoDBUtil.getMongoClient().getDatabase("m_db1");
		MongoCollection<Document> coll3 = db1.getCollection("coll3");
		System.out.println(coll3.countDocuments()); //7
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

5、对数据库进行CRUD

5.1插入一个文档

    @Test
    public void test() {
        // 创建一个数据库
        MongoDatabase db3 = MongoDBUtil.getMongoClient().getDatabase("m_db3");
        // 创建一个集合,获取该集合
        db3.createCollection("coll1");
        MongoCollection<Document> coll1 = db3.getCollection("coll1");

        // 创建文档
        Map<String, Object> map = new HashMap<>();
        map.put("_id", "11");
        map.put("name", "zhaoyun");
        map.put("age", 18);
        map.put("sex", 1);
        Document document = new Document(map);
        //向集合中插入文档
        coll1.insertOne(document);
        System.out.println(coll1.countDocuments()); //1
    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

5.2插入多个文档

 @Test
    public void test() {
        MongoDatabase db3 = MongoDBUtil.getMongoClient().getDatabase("m_db3");
        MongoCollection<Document> coll1 = db3.getCollection("coll1");

        //要插入的文档
        List<Document> documents = new ArrayList<>();
        for(int i = 2; i <= 4; i++) {
            Document document = new Document();
            document.append("_id", i * 11 + "");
            document.append("name", "luna" + i);
            document.append("age", i + 10);
            document.append("sex", 0);
            documents.add(document);
        }
        //向集合中插入文档
        coll1.insertMany(documents);
        System.out.println(coll1.countDocuments()); //4
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

5.3 查询集合中所有记录

    @Test
    public void test() {
        MongoDatabase db3 = MongoDBUtil.getMongoClient().getDatabase("m_db3");
        MongoCollection<Document> coll1 = db3.getCollection("coll1");
        FindIterable<Document> documents = coll1.find();
        for (Document document : documents) {
            System.out.println(document);
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

5.4查询集合中某个记录

        //指定查询过滤器
        Bson filter = Filters.eq("_id", "22");
        FindIterable<Document> documents = coll1.find(filter);
        System.out.println(documents.first()); // Document{{_id=22, name=luna2, age=12, sex=0}}

  • 1
  • 2
  • 3
  • 4
  • 5

5.5更新集合中的一条记录

	@Test
	public void test() {
		MongoDatabase db3 = MongoDBUtil.getMongoClient().getDatabase("m_db3");
		MongoCollection<Document> coll1 = db3.getCollection("coll1");
		// 指定查询过滤器
		Bson filter = Filters.eq("_id", "44");
		//指定修改的更新文档
		Document updateDocument = new Document("$set", new Document("age", 100).append("name", "安琪拉"));
		UpdateResult updateResult = coll1.updateOne(filter, updateDocument);
		if (updateResult.getModifiedCount() == 0) {
			System.out.println(false);
		} else {
			System.out.println(true);
			System.out.println(updateResult.getModifiedCount()); //1
		}
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

5.6更新集合中的多条记录

	// 指定查询过滤器
		Bson filter = Filters.eq("sex", 0);
		//指定修改的更新文档
		Document updateDocument = new Document("$set", new Document("age", 99).append("name", "xiaobing"));
		UpdateResult updateResult = coll1.updateMany(filter, updateDocument);
		if (updateResult.getModifiedCount() == 0) {
			System.out.println(false);
		} else {
			System.out.println(true);
			System.out.println(updateResult.getModifiedCount()); //3
		}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

5.7删除操作

@Test
	public void test() {
		MongoDatabase db3 = MongoDBUtil.getMongoClient().getDatabase("m_db3");
		MongoCollection<Document> coll1 = db3.getCollection("coll1");
		// 指定查询过滤器
		Bson filter = Filters.eq("sex", 0);
		DeleteResult deleteResult = coll1.deleteOne(filter);
//		DeleteResult deleteResult = coll1.deleteMany(filter);
		if (deleteResult.getDeletedCount() == 0) {
			System.out.println(false);
		} else {
			System.out.println(true);
			System.out.println(deleteResult.getDeletedCount()); //1
		}
	}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/698899
推荐阅读
相关标签
  

闽ICP备14008679号