MongoDB详解(有这一篇就够了)-程序员宅基地

技术标签: java  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"});

3.2 查询数据

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

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"}})

3.4 删除数据

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

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" }
    }
  }
])      
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" }
        }
    }
  ])
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降序)
  }
])
3.5.4 限制文档 $redact
//如果 fieldName 字段的值大于等于 10,则保留文档内容($$DESCEND),否则删除文档内容($$PRUNE)。  
db.collection.aggregate([
  // 其他聚合阶段
  {
    $redact: {
      $cond: {
        if: { $gte: ["$fieldName", 10] },
        then: "$$DESCEND",
        else: "$$PRUNE"
      }
    }
  }
])
  

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

img

img

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

1.引入依赖

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

2.配置连接参数

    data:
    mongodb:
      host: 10.0.26.194
      username: wanttop2
      password: Testwanttop2
      port: 27017
      authentication-database: wanttop2
      database: wanttop2

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;
     }
 }
 ```
方式一:使用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> {
}
第二步实现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);
    }
}
方式二:使用MongoTemplate(推荐使用)

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

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

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

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

下面是常用的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.单表查询
        // 判断 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");
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"));
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>

2.连接MongoDB服务

2.1 没有密码连接

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

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);

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;
	}
}	

4、 数据库操作

4.1 获取所有数据库

	@Test
	public void testGetDBS() {
		MongoIterable<String> dbNames = MongoDBUtil.getMongoClient().listDatabaseNames();
		for (String db : dbNames) {
			System.out.println(db);
		}
	}

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

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

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
	}

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
    }

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
    }

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);
        }
    }

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}}

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
		}
	}

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
		}

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
		}
	}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lfnew/article/details/132602500

智能推荐

彻底扒光 通过智能路由器拆解看其本质-程序员宅基地

文章浏览阅读1.7k次。可以看到很多联发科的MT芯片摘自:https://net.zol.com.cn/531/5312999.html彻底扒光 通过智能路由器拆解看其本质2015-07-23 00:40:00[中关村在线 原创] 作者:陈赫|责编:白宁收藏文章 分享到 评论(24)关注智能路由器拆解的朋友们注意啦!我们已经将这五款产品彻底扒开,将主板的真容展现在了大家的眼前。网友们可以看见这些智能路由器主板的做工和用料,我们还为网友们展示了主要的电子元器件,供大家品评观赏。..._路由器拆解

Java--深入JDK和hotspot底层源码剖析Thread的run()、start()方法执行过程_jdk的源码hotspot跟jdk是分开的-程序员宅基地

文章浏览阅读2.1k次,点赞101次,收藏78次。【学习背景】今天主要是来了解Java线程Thread中的run()、start()两个方法的执行有哪些区别,会给出一个简单的测试代码样例,快速理解两者的区别,再从源码层面去追溯start()底层是如何最终调用Thread#run()方法的,个人觉得这样的学习不论对面试,还是实际编程来说都是比较有帮助的。进入正文~学习目录一、代码测试二、源码分析2.1 run()方法2.2 start()方法三、使用总结一、代码测试执行Thread的run()、start()方法的测试代码如下:public_jdk的源码hotspot跟jdk是分开的

透视俄乌网络战之一:数据擦除软件_俄乌网络战观察(一)-程序员宅基地

文章浏览阅读4.4k次,点赞90次,收藏85次。俄乌冲突中,各方势力通过数据擦除恶意软件破坏关键信息基础设施计算机的数据,达到深度致瘫的效果,同时窃取重要敏感信息。_俄乌网络战观察(一)

Maven私服仓库配置-Nexus详解_nexus maven-程序员宅基地

文章浏览阅读1.7w次,点赞23次,收藏139次。Maven 私服是一种特殊的Maven远程仓库,它是架设在局域网内的仓库服务,用来代理位于外部的远程仓库(中央仓库、其他远程公共仓库)。当然也并不是说私服只能建立在局域网,也有很多公司会直接把私服部署到公网,具体还是得看公司业务的性质是否是保密的等等,因为局域网的话只能在公司用,部署到公网的话员工在家里也可以办公使用。_nexus maven

基于AI的计算机视觉识别在Java项目中的使用 (四) —— 准备训练数据_java ocr ai识别训练-程序员宅基地

文章浏览阅读934次。我先用所有的样本数据对模型做几轮初步训练,让深度神经模型基本拟合(数万条记录的训练集,识别率到99%左右),具备初步的识别能力,这时的模型就是“直男”。相较于训练很多轮、拟合程度很高的“油腻男”,它的拟合程度较低,还是“直男愣头青”。..............._java ocr ai识别训练

hibernate 数据库类型 date没有时分秒解决_hibernate解析時間只有年月日沒有時分秒-程序员宅基地

文章浏览阅读688次。一、问题现象:  在数据库表中日期字段中存的日期光有年月日,没有时分秒。二、产生原因:三 解决办法   检查表的相应映射xml文件。 <property name="operateDate" type="Date">如果同上面所写,那问题出在 type类型上了正确写法 :<property name="operateDate" type="java.util..._hibernate解析時間只有年月日沒有時分秒

随便推点

springbbot运行无法编译成功,找不到jar包报错:Error:(3, 46) java: 程序包org.springframework.context.annotation不存在-程序员宅基地

文章浏览阅读1k次,点赞2次,收藏2次。文章目录问题描述:解决方案:问题描述:提示:idea springbbot运行无法编译成功,找不到jar包报错E:\ideaProject\demokkkk\src\main\java\com\example\demo\config\WebSocketConfig.javaError:(3, 46) java: 程序包org.springframework.context.annotation不存在Error:(4, 46) java: 程序包org.springframework.conte_error:(3, 46) java: 程序包org.springframework.context.annotation不存在

react常见面试题_recate面试-程序员宅基地

文章浏览阅读6.4k次,点赞6次,收藏36次。1、redux中间件中间件提供第三方插件的模式,自定义拦截 action -&gt; reducer 的过程。变为 action -&gt; middlewares -&gt; reducer 。这种机制可以让我们改变数据流,实现如异步 action ,action 过滤,日志输出,异常报告等功能。常见的中间件:redux-logger:提供日志输出redux-thunk:处理异步操作..._recate面试

交叉编译jpeglib遇到的问题-程序员宅基地

文章浏览阅读405次。由于要在开发板中加载libjpeg,不能使用gcc编译的库文件给以使用,需要自己配置使用另外的编译器编译该库文件。/usr/bin/ld:.libs/jaricom.o:RelocationsingenericELF(EM:40)/usr/bin/ld:.libs/jaricom.o:RelocationsingenericELF(EM:40)...._jpeg_utils.lo: relocations in generic elf (em: 8) error adding symbols: file

【办公类-22-06】周计划系列(1)“信息窗” (2024年调整版本)-程序员宅基地

文章浏览阅读578次,点赞10次,收藏17次。【办公类-22-06】周计划系列(1)“信息窗” (2024年调整版本)

SEO优化_百度seo resetful-程序员宅基地

文章浏览阅读309次。SEO全称为Search Engine Optimization,中文解释为搜索引擎优化。一般指通过对网站内部调整优化及站外优化,使网站满足搜索引擎收录排名需求,在搜索引擎中提高关键词排名,从而把精准..._百度seo resetful

回归预测 | Matlab实现HPO-ELM猎食者算法优化极限学习机的数据回归预测_猎食者优化算法-程序员宅基地

文章浏览阅读438次。回归预测 | Matlab实现HPO-ELM猎食者算法优化极限学习机的数据回归预测_猎食者优化算法