前面章节介绍了 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()) 设置写入策略解析器。