用 MongoTemplate 操作 documentDB 與 用 Spring Data MongoDB 操作 documentDB 有什麼不同,write concern,transaction

gongchengship發表於2024-07-09

使用 MongoTemplate 和使用 Spring Data MongoDB 的倉庫介面(如 MongoRepository)都是操作 MongoDB 資料庫的常見方法,它們在功能上有些重疊,但也有不同的用例和優點。以下是它們的不同之處以及對 Write Concern 支援的情況。

MongoTemplate 和 MongoRepository 的對比

MongoTemplate

  1. 更細粒度的控制MongoTemplate 提供了對 MongoDB 操作的細粒度控制,允許你執行自定義的查詢、更新、刪除和聚合操作。
  2. 靈活性高:適用於複雜的查詢和自定義的資料庫操作。
  3. 直接操作 MongoDB APIMongoTemplate 直接使用 MongoDB Java Driver 提供的方法,可以更直接地使用 MongoDB 的底層功能。
  4. 寫操作和查詢的靈活配置:可以靈活地配置 Write Concern 和 Read Preference,以確保資料一致性和效能。

Spring Data MongoDB Repository (MongoRepository)

  1. 簡潔易用MongoRepository 提供了一套簡潔的 CRUD 操作介面,極大地簡化了常見資料庫操作。
  2. 自動化功能:支援分頁、排序、查詢方法名解析等自動化功能,減少了樣板程式碼。
  3. 抽象級別高:更適合標準的 CRUD 操作,開發效率更高。
  4. 容易擴充套件:可以很容易地擴充套件自定義查詢。

Write Concern 支援情況

MongoTemplate

MongoTemplate 支援透過 WriteConcern 物件配置寫操作的 Write Concern,從而控制寫操作的確認級別。

示例程式碼:

import com.mongodb.client.MongoClients;
import com.mongodb.WriteConcern;
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.WriteConcernResolver;
import org.springframework.data.mongodb.core.SimpleMongoClientDbFactory;

@Configuration
public class MongoConfig {

    @Bean
    public MongoTemplate mongoTemplate() {
        MongoTemplate mongoTemplate = new MongoTemplate(
            new SimpleMongoClientDbFactory(MongoClients.create("mongodb://<username>:<password>@<documentdb-endpoint>:<port>/<database>?ssl=true&retryWrites=false"), 
            "<database>"));
        
        mongoTemplate.setWriteConcern(WriteConcern.MAJORITY);
        
        return mongoTemplate;
    }
}

MongoRepository

在 Spring Data MongoDB 中,可以透過自定義 MongoTemplate 並將其注入到倉庫中,從而實現對 Write Concern 的配置。

示例程式碼:

import com.mongodb.client.MongoClients;
import com.mongodb.WriteConcern;
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.SimpleMongoClientDbFactory;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

@Configuration
@EnableMongoRepositories(basePackages = "com.example.repository")
public class MongoConfig {

    @Bean
    public MongoTemplate mongoTemplate() {
        MongoTemplate mongoTemplate = new MongoTemplate(
            new SimpleMongoClientDbFactory(MongoClients.create("mongodb://<username>:<password>@<documentdb-endpoint>:<port>/<database>?ssl=true&retryWrites=false"), 
            "<database>"));
        
        mongoTemplate.setWriteConcern(WriteConcern.MAJORITY);
        
        return mongoTemplate;
    }
}

總結

  • MongoTemplate 提供了對 MongoDB 操作的更細粒度控制,適合複雜查詢和自定義操作,支援靈活配置 Write Concern。
  • MongoRepository 提供了一套簡潔的 CRUD 操作介面,適合標準的 CRUD 操作和自動化功能,可以透過注入自定義 MongoTemplate 來配置 Write Concern。

這兩種方法各有優劣,可以根據具體的需求選擇合適的方式。如果需要更復雜的資料庫操作和更高的靈活性,建議使用 MongoTemplate;如果主要是進行標準的 CRUD 操作,並且希望簡化開發流程,建議使用 MongoRepository


對事務 Translate 操作的支援

在使用 Spring Data MongoDB 操作 AWS DocumentDB 時,可以使用 MongoTemplateMongoRepository 進行事務操作。不過需要注意的是,AWS DocumentDB 在事務支援上與 MongoDB 4.0 有所不同,它並不完全支援分散式事務。

MongoTemplate 和事務操作

使用 MongoTemplate 進行事務操作是透過 Spring 的 @Transactional 註解實現的。示例如下:

import com.mongodb.client.MongoClients;
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;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;

@Configuration
@EnableTransactionManagement
public class MongoConfig {

    @Bean
    public MongoDatabaseFactory mongoDbFactory() {
        return new SimpleMongoClientDatabaseFactory(MongoClients.create("mongodb://<username>:<password>@<documentdb-endpoint>:<port>/<database>?ssl=true&retryWrites=false"), 
            "<database>");
    }

    @Bean
    public MongoTemplate mongoTemplate() {
        return new MongoTemplate(mongoDbFactory());
    }
}

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Transactional
    public void performTransactionalOperation(User user1, User user2) {
        mongoTemplate.save(user1);
        mongoTemplate.save(user2);
    }
}

MongoRepository 和事務操作

同樣地,使用 MongoRepository 進行事務操作也是透過 Spring 的 @Transactional 註解實現的。示例如下:

import com.mongodb.client.MongoClients;
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;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement
@EnableMongoRepositories(basePackages = "com.example.repository")
public class MongoConfig {

    @Bean
    public MongoDatabaseFactory mongoDbFactory() {
        return new SimpleMongoClientDatabaseFactory(MongoClients.create("mongodb://<username>:<password>@<documentdb-endpoint>:<port>/<database>?ssl=true&retryWrites=false"), 
            "<database>");
    }

    @Bean
    public MongoTemplate mongoTemplate() {
        return new MongoTemplate(mongoDbFactory());
    }
}

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Transactional
    public void performTransactionalOperation(User user1, User user2) {
        userRepository.save(user1);
        userRepository.save(user2);
    }
}

事務支援的注意事項

  1. 單文件事務:在 MongoDB 和 AWS DocumentDB 中,單文件操作(如插入、更新和刪除)本質上是原子的。
  2. 多文件事務:MongoDB 4.0 及以上版本支援多文件事務,而 AWS DocumentDB 目前支援多文件事務,但不完全相容 MongoDB 的事務模型。

總結

  • MongoTemplateMongoRepository 都支援事務操作,均透過 Spring 的 @Transactional 註解實現。
  • 在進行事務操作時,確保使用的 MongoDB 版本或 AWS DocumentDB 例項支援事務特性。
  • 對於複雜的多文件事務操作,建議詳細瞭解 AWS DocumentDB 的事務支援情況,以確保符合業務需求。

相關文章