1. Ikhtisar
Dalam tutorial ini, kita akan mempelajari cara mengimplementasikan bidang yang dibuat secara otomatis dan berurutan untuk MongoDB di Spring Boot.
Saat kami menggunakan MongoDB sebagai database untuk aplikasi Spring Boot, kami tidak dapat menggunakan @GeneratedValue anotasi dalam model kami karena tidak tersedia. Oleh karena itu kita membutuhkan sebuah metode untuk menghasilkan efek yang sama seperti yang kita miliki jika kita menggunakan JPA dan database SQL.
Solusi umum untuk masalah ini sederhana. Kami akan membuat koleksi (tabel) yang akan menyimpan urutan yang dihasilkan untuk koleksi lainnya. Selama pembuatan record baru, kami akan menggunakannya untuk mengambil nilai berikutnya.
2. Ketergantungan
Mari tambahkan starter spring-boot berikut ke pom.xml our kami :
<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>
Versi terbaru untuk dependensi dikelola oleh spring-boot-starter-parent .
3. Koleksi
Seperti yang dibahas dalam ikhtisar, kami akan membuat koleksi yang akan menyimpan urutan peningkatan otomatis untuk koleksi lainnya. Kami akan memanggil koleksi ini database_sequences. Itu dapat dibuat menggunakan mongo shell atau Kompas MongoDB. Mari buat kelas model yang sesuai:
@Document(collection = "database_sequences")
public class DatabaseSequence {
@Id
private String id;
private long seq;
//getters and setters omitted
}
Mari kita buat pengguna koleksi, dan objek model terkait, yang akan menyimpan detail orang yang menggunakan sistem kami:
@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
}
Di Pengguna model yang dibuat di atas, kami menambahkan bidang statis SEQUENCE_NAME, yang merupakan referensi unik ke urutan peningkatan otomatis untuk pengguna koleksi.
Kami juga membubuhi keterangan dengan @Transient untuk mencegahnya bertahan di samping properti model lainnya.
4. Membuat Rekor Baru
Sejauh ini, kami telah membuat koleksi dan model yang diperlukan. Sekarang, kami akan membuat layanan yang akan menghasilkan nilai peningkatan otomatis yang dapat digunakan sebagai id untuk entitas kami.
Mari buat SequenceGeneratorService yang memiliki generateSequence() :
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;
}
Sekarang, kita dapat menggunakan generateSequence() saat membuat rekor baru:
User user = new User();
user.setId(sequenceGenerator.generateSequence(User.SEQUENCE_NAME));
user.setEmail("[email protected]");
userRepository.save(user);
Untuk mencantumkan semua pengguna, kami akan menggunakan UserRepository :
List<User> storedUsers = userRepository.findAll();
storedUsers.forEach(System.out::println);
Seperti sekarang, kita harus menyetel bidang id setiap kali kita membuat instance baru dari model kita. Kami dapat menghindari proses ini dengan membuat listener untuk peristiwa siklus hidup Spring Data MongoDB.
Untuk melakukannya, kita akan membuat UserModelListener yang memperluas AbstractMongoEventListener
@Override
public void onBeforeConvert(BeforeConvertEvent<User> event) {
if (event.getSource().getId() < 1) {
event.getSource().setId(sequenceGenerator.generateSequence(User.SEQUENCE_NAME));
}
}
Sekarang, setiap kali kami menyimpan Pengguna baru, id akan disetel secara otomatis.