前面章节介绍了 MongoDB 的写入策略 WriteConcern,我们通过 MongoTemplate 的 setWriteConcern(WriteConcern) 方法进行全局设置。那么可以对某个一类操作单独设置写入策略吗?
对于这个更高级的需求,即你想在每个操作的基础上设置不同的 WriteConcern 值(对于删除、更新、插入和保存操作),可以在 MongoTemplate 上配置一个名为 WriteConcernResolver 的策略接口。
由于 MongoTemplate 用于持久化 POJO,WriteConcernResolver 让你创建一个策略,可以将特定的 POJO 类映射到不同的 WriteConcern 值。
下面是 WriteConcernResolver 接口的定义:
public interface WriteConcernResolver {
    WriteConcern resolve(MongoAction action);
}你可以使用 MongoAction 参数来决定怎样设置 WriteConcern 值,或者使用模板本身的值作为默认值。
MongoAction 包含被写入的集合名称、POJO 的 java.lang.Class、转换后的 Document、操作(REMOVE、UPDATE、INSERT、INSERT_LIST 或 SAVE),以及其他一些上下文信息。
下面的例子显示了为不同的集合设置不同的 WriteConcern 值,如下:
(1)自定义 WriteConcernResolver 策略解析器,如下:
package com.hxstrive.springdata.mongodb.custom;
import com.mongodb.WriteConcern;
import org.springframework.data.mongodb.core.MongoAction;
import org.springframework.data.mongodb.core.WriteConcernResolver;
/**
* 根据集合名称分配不同的写入策略  WriteConcern
* @author hxstrive.com 2022/12/23
*/
public class MyAppWriteConcernResolver implements WriteConcernResolver {
   @Override
   public WriteConcern resolve(MongoAction action) {
       // 获取集合名称
       String name = action.getCollectionName();
       if("user".equals(name)) {
           return WriteConcern.UNACKNOWLEDGED;
       } else if("order".equals(name)) {
           return WriteConcern.JOURNALED;
       }
       return action.getDefaultWriteConcern();
   }
}(2)配置自定义的 MyAppWriteConcernResolver 策略解析器,如下:
package com.hxstrive.springdata.mongodb.config;
import com.hxstrive.springdata.mongodb.custom.MyAppWriteConcernResolver;
import com.mongodb.WriteConcern;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.WriteResultChecking;
/**
* 配置实例化 MongoTemplate
* @author hxstrive.com 2022/12/23
*/
@Configuration
public class AppConfig {
   @Bean
   public MongoClient mongoClient() {
       // 创建连接到本地的 MongoClient 对象
       return MongoClients.create("mongodb://localhost:27017");
   }
   @Bean
   public MongoTemplate mongoTemplate(MongoClient mongoClient) {
       // 创建链接到本地 test 数据库的 MongoTemplate 实例
       MongoTemplate mongoTemplate = new MongoTemplate(mongoClient, "test");
       // 设置 WriteResultChecking 检查策略
       mongoTemplate.setWriteResultChecking(WriteResultChecking.EXCEPTION);
       // 设置 WriteConcern 写入策略
       mongoTemplate.setWriteConcern(WriteConcern.ACKNOWLEDGED);
       // 设置写入策略解析器
       mongoTemplate.setWriteConcernResolver(new MyAppWriteConcernResolver());
       return mongoTemplate;
   }
}上面代码中,使用 mongoTemplate.setWriteConcernResolver(new MyAppWriteConcernResolver()) 设置写入策略解析器。
