Spring Data MongoDB 教程

运行命令

您可以使用 MongoTemplate 上的 executeCommand(...) 方法获取 MongoDB 驱动程序的 MongoDatabase.runCommand() 方法。这些方法还将异常转换为 Spring 的 DataAccessException 层次结构异常。

运行命令的方法定义如下:

  • Document executeCommand (Document command)  运行一个Mongo DB命令。

  • Document executeCommand (Document command, ReadPreference readPreference)  使用给定的可为空的 MongoDB ReadPreference 运行 MongoDB 命令。

  • Document executeCommand (String jsonCommand)  运行一个表示为 JSON 字符串的 MongoDB 命令。

MongoDB 读策略 ReadPreference

在副本集 Replica Set 中才涉及到 ReadPreference 策略的设置,默认情况下,读写都是分发到 Primary(主)节点执行,但是对于写少读多的情况,我们希望进行读写分离来分摊压力,所以希望使用 Secondary(从)节点来进行读取,Primary 只承担写的责任(实际上写只能分发到 Primary 节点,不可修改)。

MongoDB 有 5 种 ReadPreference 策略,分别如下:

  • primary   主节点,默认模式,读操作只在主节点,如果主节点不可用,报错或者抛出异常。

  • primaryPreferred   首选主节点,大多情况下读操作在主节点,如果主节点不可用,如故障转移,读操作在从节点。

  • secondary   从节点,读操作只在从节点, 如果从节点不可用,报错或者抛出异常。

  • secondaryPreferred   首选从节点,大多情况下读操作在从节点,特殊情况(如单主节点架构)读操作在主节点。

  • nearest   最邻近节点,读操作在最邻近的成员,可能是主节点或者从节点。

完整示例

(1)application.properties 配置文件

# Log
logging.level.root=debug

# MongoDB
spring.data.mongodb.uri=mongodb://localhost:27017/test

(2)AppConfig.java 配置类,配置 MongoTemplate 对象

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.MongoTemplate;

/**
* 配置 MongoTemplate
* @author hxstrive.com 2022/12/23
*/
@Slf4j
@Configuration
public class AppConfig {

   @Bean
   public MongoTemplate mongoTemplate(MongoDatabaseFactory mongoDatabaseFactory) {
       log.info("mongoTemplate({}, {})", mongoDatabaseFactory);
       return new MongoTemplate(mongoDatabaseFactory);
   }

}

(3)集合 person 对应的实体

import lombok.Builder;
import lombok.Data;
import lombok.ToString;

@Data
@ToString
@Builder
public class Person {
   /** 用户ID */
   private int id;
   /** 用户姓名 */
   private String name;
   /** 年龄 */
   private int age;
}

(4)客户端代码,说明见注释。

import com.hxstrive.springdata.mongodb.entity.Person;
import com.mongodb.ReadPreference;
import org.bson.Document;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.core.MongoTemplate;

/**
* 运行 MongoDB 命令示例
* @author hxstrive.com
*/
@SpringBootTest
public class RunningCommandsDemo {

   @Autowired
   private MongoTemplate mongoTemplate;

   @BeforeEach
   public void init() {
       mongoTemplate.dropCollection(Person.class);

       // 准备数据
       mongoTemplate.insert(Person.builder().id(100).name("Tom").age(27).build());
       mongoTemplate.insert(Person.builder().id(200).name("Helen").age(30).build());
       mongoTemplate.insert(Person.builder().id(300).name("Bill").age(47).build());
       mongoTemplate.insert(Person.builder().id(400).name("Joe").age(20).build());
   }

   @Test
   public void executeCommand() {
       // 获取 person 集合中文档数量
       Document command = new Document();
       command.append("count", "person");

       Document result = mongoTemplate.executeCommand(command);
       System.out.println(result);
       // 结果:
       // Document{{n=4, ok=1.0}}
   }


   @Test
   public void executeCommand2() {
       // 获取 person 集合中文档数量
       Document command = new Document();
       command.append("count", "person");

       // 指定读策略
       // ReadPreference 主要控制客户端driver从副本集(Replica Set)读数据的时候的策略
       ReadPreference readPreference = ReadPreference.primary();

       Document result = mongoTemplate.executeCommand(command, readPreference);
       System.out.println(result);
       // 结果:
       // Document{{n=4, ok=1.0}}
   }


   @Test
   public void executeJSON() {
       // 获取 person 集合中文档数量
       Document result = mongoTemplate.executeCommand("{count: 'person'}");
       System.out.println(result);
       // 结果:
       // Document{{n=4, ok=1.0}}
   }

}
说说我的看法
全部评论(
没有评论
关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号