1. Tổng quan
Trong hướng dẫn này, chúng ta sẽ tìm hiểu cách triển khai một trường tuần tự, được tạo tự động cho MongoDB trong Spring Boot.
Khi chúng tôi đang sử dụng MongoDB làm cơ sở dữ liệu cho ứng dụng Spring Boot, chúng tôi không thể sử dụng @GeneratedValue chú thích trong các mô hình của chúng tôi vì nó không có sẵn. Do đó, chúng tôi cần một phương pháp để tạo ra hiệu ứng giống như chúng tôi sẽ có nếu chúng tôi đang sử dụng JPA và cơ sở dữ liệu SQL.
Giải pháp chung cho vấn đề này rất đơn giản. Chúng tôi sẽ tạo một bộ sưu tập (bảng) sẽ lưu trữ trình tự đã tạo cho các bộ sưu tập khác. Trong quá trình tạo bản ghi mới, chúng tôi sẽ sử dụng bản ghi đó để tìm nạp giá trị tiếp theo.
2. Sự phụ thuộc
Hãy thêm các trình khởi động spring-boot sau vào pom.xml của chúng tôi :
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<versionId>2.2.2.RELEASE</versionId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<versionId>2.2.2.RELEASE</versionId>
</dependency>
</dependencies>
Phiên bản mới nhất cho các phần phụ thuộc được quản lý bởi spring-boot-starter-parent .
3. Bộ sưu tập
Như đã thảo luận trong phần tổng quan, chúng tôi sẽ tạo một bộ sưu tập sẽ lưu trữ trình tự tăng dần tự động cho các bộ sưu tập khác. Chúng tôi sẽ gọi bộ sưu tập này là database_sequences. Nó có thể được tạo bằng mongo shell hoặc MongoDB La bàn. Hãy tạo một lớp mô hình tương ứng:
@Document(collection = "database_sequences")
public class DatabaseSequence {
@Id
private String id;
private long seq;
//getters and setters omitted
}
Sau đó, hãy tạo một người dùng bộ sưu tập và một đối tượng mô hình tương ứng, sẽ lưu trữ thông tin chi tiết về những người đang sử dụng hệ thống của chúng tôi:
@Document(collection = "users")
public class User {
@Transient
public static final String SEQUENCE_NAME = "users_sequence";
@Id
private long id;
private String email;
//getters and setters omitted
}
Trong Người dùng mô hình được tạo ở trên, chúng tôi đã thêm một trường tĩnh SEQUENCE_NAME, là một tham chiếu duy nhất đến chuỗi tự động tăng dần cho người dùng bộ sưu tập.
Chúng tôi cũng chú thích nó bằng @Transient để ngăn nó tồn tại cùng với các thuộc tính khác của mô hình.
4. Tạo bản ghi mới
Cho đến nay, chúng tôi đã tạo ra các bộ sưu tập và mô hình cần thiết. Bây giờ, chúng tôi sẽ tạo một dịch vụ sẽ tạo giá trị tự động tăng dần có thể được sử dụng làm id cho các thực thể của chúng tôi.
Hãy tạo một SequenceGeneratorService có createSequence () :
public long generateSequence(String seqName) {
DatabaseSequence counter = mongoOperations.findAndModify(query(where("_id").is(seqName)),
new Update().inc("seq",1), options().returnNew(true).upsert(true),
DatabaseSequence.class);
return !Objects.isNull(counter) ? counter.getSeq() : 1;
}
Bây giờ, chúng ta có thể sử dụng createSequence () trong khi tạo bản ghi mới:
User user = new User();
user.setId(sequenceGenerator.generateSequence(User.SEQUENCE_NAME));
user.setEmail("[email protected]");
userRepository.save(user);
Để liệt kê tất cả người dùng, chúng tôi sẽ sử dụng UserRepository :
List<User> storedUsers = userRepository.findAll();
storedUsers.forEach(System.out::println);
Như hiện tại, chúng tôi phải đặt trường id mỗi khi chúng tôi tạo một phiên bản mới của mô hình của mình. Chúng ta có thể phá vỡ quá trình này bằng cách tạo trình lắng nghe cho các sự kiện vòng đời Spring Data MongoDB.
Để làm điều đó, chúng tôi sẽ tạo một UserModelListener mở rộng AbstractMongoEventListener
@Override
public void onBeforeConvert(BeforeConvertEvent<User> event) {
if (event.getSource().getId() < 1) {
event.getSource().setId(sequenceGenerator.generateSequence(User.SEQUENCE_NAME));
}
}
Bây giờ, mỗi khi chúng tôi lưu một Người dùng, mới the id sẽ được đặt tự động.