SpringBoot 集成 MongoDB

发表于 2023-02-28

官方文档

MongoDB Java 驱动

使用原生依赖

添加依赖

<dependencies>
    <dependency>
        <groupId>org.mongodb</groupId>
        <artifactId>mongodb-driver-sync</artifactId>
        <version>4.5.1</version>
    </dependency>
</dependencies>

创建连接对象

void testConnect() {
    // MongoDB 连接 URI
    String uri = "mongodb://demo:123456@192.168.1.15:27017/demo?maxPoolSize=20&w=majority";
    try (MongoClient mongoClient = MongoClients.create(uri)) {
        // 获取 DataBase
        MongoDatabase database = mongoClient.getDatabase("demo");
        // 获取 Collection
        MongoCollection<Document> order = database.getCollection("order");
        // 执行查询
        FindIterable<Document> documents = order.find();
        for (Document next : documents) {
            System.out.println(next.toString());
        }
    }
}

注入 MongoClient 并配置 CodecRegistry

CodecRegistry 可以让对象与 BSON 自动转换

@Bean
public MongoClient mongoClient() {
    String uri = "mongodb://demo:123456@192.168.1.15:27017/demo?maxPoolSize=20&w=majority";
    // 创建 Codec 注册器
    CodecRegistry codecRegistry = CodecRegistries.fromRegistries(
            MongoClientSettings.getDefaultCodecRegistry(),
            // 设置 true 实现自动映射
            CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build())
    );
    MongoClientSettings se = MongoClientSettings.builder().codecRegistry(codecRegistry).applyConnectionString(new ConnectionString(uri)).build();
    return MongoClients.create(se);
}

使用 Spring Boot Starter

添加依赖

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

获取 MongoTemplate

s 配置参数

spring:
  data:
    mongodb:
      # 使用 uri
      # uri: mongodb://user:pwd@ip1:port1,ip2:port2/database
      uri: mongodb://demo:123456@192.168.1.15:27017/demo
      # 使用多个参数配置
      #host: 192.168.1.15
      #port: 27017
      #database: demo
      #username: demo
      #password: 123456
@Autowired
private MongoTemplate mongoTemplate;

API 说明

API 文档

MongoDatabase

  • 获取 Collection
    • MongoCollection<Document> getCollection(String collectionName)
      • 根据 collectionName 获取 Collection
    • <T> MongoCollection<T> getCollection(String collectionName, Class<T> documentClass)
      • 根据 collectionName 获取 Collection,并指定文档类型(Class)
  • 创建 Collection
    • void createCollection(String collectionName)
      • 根据 collectionName 创建 Collection
    • void createCollection(String collectionName, CreateCollectionOptions createCollectionOptions)
      • 根据 collectionName 创建 Collection,并指定 Collection 设置参数
  • 删除 DataBase
    • void drop()
      • 删除当前 DataBase
  • 获取所有 Collection 的名字
    • MongoIterable<String> listCollectionNames()
      • 获取所有 Collection 的名字
  • 获取所有 Collection 操作对象
    • ListCollectionsIterable<Document> listCollections()
      • 获取所有 Collection 操作对象

MongoCollection

命令执行

void testInsert() {
    MongoDatabase demo = mongoClient.getDatabase("demo");
    Document document = new Document();
    document.put("ping", 1);
    Document result = demo.runCommand(document);
}

插入文档

  • insertMany(List<? extends T> documents)
  • insertOne(T document)

需要设置 CodecRegistry,能够让对象与 BSON 互相转化

// 报错
//     org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class
// 需要 Codec
void testInsert() {
    MongoCollection<Order> collection = mongoClient.getDatabase("demo").getCollection("order", Order.class);
    Order order = new Order();
    order.initValue();
    InsertOneResult insertOneResult = collection.insertOne(order);
    System.out.println(insertOneResult.wasAcknowledged());
}
/**************************************************** 改正后 ****************************************************/
void testInsert() {
    // 创建 Codec 注册器
    CodecRegistry codecRegistry = CodecRegistries.fromRegistries(
            MongoClientSettings.getDefaultCodecRegistry(),
            // 设置 true 实现自动映射
            CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build())
    );
    // 根据 Codec 注册器获取 MongoCollection
    MongoCollection<Order> collection = mongoClient.getDatabase("demo").getCollection("order", Order.class)
        .withCodecRegistry(codecRegistry);
    Order order = new Order();
    order.initValue();
    InsertOneResult insertOneResult = collection.insertOne(order);
    System.out.println(insertOneResult.wasAcknowledged());
}

查询文档

更新文档

删除文档

MongoTemplate

插入文档

  • <T> T insert(T objectToSave, String collectionName)
  • <T> Collection<T> insertAll(Collection<? extends T> objectsToSave)
// 插入文档
void testInsert() {
    Order order = new Order();
    order.setName("Set Order Name");
    mongoTemplate.insert(order, "order");
}
/******************** MongoDB 中的结果 ******************** /
{
  "_id": {
    "$oid": "626213847ad9c763dc4e94bc"
  },
  "name": "Set Order Name",
  "_class": "com.example.mongo.model.Order"
}

查询文档

  • MongoTemplate
    • 查询总数
      • long count(Query query, String collectionName)
    • 查询
      • List<T> findAll(Class<T> entityClass, String collectionName)
      • List<T> find(Query query, Class<T> entityClass, String collectionName)
      • T findById(Object id, Class<T> entityClass, String collectionName)
      • T findOne(Query query, Class<T> entityClass, String collectionName)
  • Query
    • 排序
      • Query with(Sort sort)
    • 分页
      • Query skip(long skip)
      • Query limit(int limit)
  • Criteria
    • WHERE
      • Criteria where(String key)
    • EQ
      • Criteria is(@Nullable Object value)
    • AND
      • Criteria and(String key)
    • OR
      • Criteria orOperator(Criteria... criteria)
      • Criteria orOperator(Collection<Criteria> criteria)
    • IN
      • Criteria in(Object... values)
      • Criteria in(Collection<?> values)
    • Not EQ
      • Criteria ne(@Nullable Object value)
    • Not OR
      • Criteria norOperator(Criteria... criteria)
      • Criteria norOperator(Collection<Criteria> criteria)
    • Not IN
      • Criteria nin(Object... values)
      • Criteria nin(Collection<?> values)
    • >
      • Criteria gt(Object value)
    • >=
      • Criteria gte(Object value)
    • <
      • Criteria lt(Object value)
    • <=
      • Criteria lte(Object value)
    • LIKE
      • 正则匹配
      • Criteria regex(String regex)
void testFind() {
    Criteria where = Criteria.where("name").is("Set Order Name");
    Query query = new Query(where);
    List<Order> orderList = mongoTemplate.find(query, Order.class, "order");
}

更新文档

  • MongoTemplate
    • UpdateResult updateFirst(Query query, UpdateDefinition update, String collectionName)
    • UpdateResult updateMulti(Query query, UpdateDefinition update, String collectionName)
  • Query
    • ......
  • Update
    • SET
      • Update set(String key, @Nullable Object value)
    • UPDATE
      • Update update(String key, @Nullable Object value)
      • 针对存在的值进行更新
    • 自增
      • Update inc(String key, Number inc)
    • 数组操作
      • Update pop(String key, Position pos)
      • Update pull(String key, @Nullable Object value)
      • Update pullAll(String key, Object[] values)
      • Update push(String key, @Nullable Object value)
      • Update addToSet(String key, @Nullable Object value)
void testUpdate() {
    Criteria where = Criteria.where("name").is("Set Order Name");
    Query query = new Query(where);
    Update update = Update.update("name", "Update Oreder Name");
    mongoTemplate.updateFirst(query, update, Order.class);
}

删除文档

  • MongoTemplate
    • DeleteResult remove(Query query, String collectionName)
    • T findAndRemove(Query query, Class<T> entityClass, String collectionName)
    • List<T> findAllAndRemove(Query query, Class<T> entityClass, String collectionName)
void testDelete() {
    Criteria where = Criteria.where("name").is("Set Order Name");
    Query query = new Query(where);
    mongoTemplate.remove(query, "order");
}

分组查询

  • MongoTemplate
    • AggregationResults<T> aggregate(Aggregation aggregation, String collectionName, Class<T> outputType)
  • Aggregation
    • 创建查询对象
      • Aggregation newAggregation(List<? extends AggregationOperation> operations)
    • $match
      • MatchOperation match(Criteria criteria)
    • $project
      • ProjectionOperation project(String... fields)
      • 例子:投影时运算
        • Aggregation aggregation = Aggregation.project(Fields.fields("amount")).and("amount").multiply(100).as("amount"));
    • $sort
      • SortOperation sort(Sort sort)
    • $group
      • GroupOperation group(String... fields)
    • $skip
      • SkipOperation skip(long elementsToSkip)
    • $limit
      • LimitOperation limit(long maxElements)
    • $lookup
      • LookupOperation lookup(String from, String localField, String foreignField, String as)
    • $unwind
      • UnwindOperation unwind(String field)
    • $graphLookup
      • StartWithBuilder graphLookup(String fromCollection)
    • $bucket
      • BucketOperation bucket(AggregationExpression groupByExpression)
    • $facet
      • FacetOperationBuilder facet(AggregationOperation... aggregationOperations)
void testInsert() {
    //封装查询条件
    List<AggregationOperation> operations = new ArrayList<>();
    operations.add(Aggregation.group("null").sum("amount").as("amount"));
    Aggregation aggregation = Aggregation.newAggregation(operations);
    AggregationResults<Order> order = mongoTemplate.aggregate(aggregation, "order", Order.class);
    System.out.println(order.getMappedResults());
}

配置

创建 MongoDB 用户

  • roles(角色)
    • Database User Roles(数据库角色)
      • read
      • readWrite
    • Database Administration Roles(数据库管理角色)
      • dbAdmin
      • dbOwner
      • userAdmin
    • Cluster Administration Roles(集群管理角色)
      • clusterAdmin
      • clusterManager
      • clusterMonitor
      • hostManager
    • Backup and Restoration Roles(备份和恢复角色)
      • backup
      • restore
    • All-Database Roles(所有数据库角色)
      • readAnyDatabase
      • readWriteAnyDatabase
      • userAdminAnyDatabase
      • dbAdminAnyDatabase
    • Superuser Roles(超级用户角色)
      • root
db.createUser(
    {
        "user": "<user_name>",
        "pwd": "<password>",
        "customData": {
            # 任何描述用户信息的文档
            "customDocument": "Custom Document"
        },
        "roles": [
            {
                role: "<role>",
                db: "<database>"
            },
            "readWrite",
            ...
        ]
    }
)

MongoDB URI

s 官方文档

  • MongoDB URI 格式

  • Java 驱动连接可选项

  • 连接池

    • maxPoolSize
      • 连接池最大数量
      • Default: 100
    • minPoolSize
      • 连接池最小数量
      • Default: 0
    • maxIdleTimeMS
      • 连接最大空闲时间
      • Default: 0
    • waitQueueTimeoutMS
      • 连接池等待超时时间
      • Default: 120000 (120 seconds)
    • 例子
      • mongodb://user:pwd@ip1:port1/database?maxPoolSize=50&maxIdleTimeMS=60000
  • 复制集

    • replicaSet
      • 复制集名
  • 事务

    • w
      • 写事务
      • 指定写级别:0、1 ~ 集群节点数、majority
    • readPreference
      • 读事务
      • 指定读的方式:primary、primaryPreferred、secondary、secondaryPreferred、nearest

配置读写分离

spring:
  data:
    mongodb:
      # 通过 URI 中的
      #     readPreference 配置读写分离
      #     slaveOk 配置从节点能读
      uri: mongodb://user:password@ip_1:27017,ip_2:27017/demo?slaveOk=true&replicaSet=replicaName&write=1&readPreference=secondaryPreferred&connectTimeoutMS=300000