1. Ikhtisar
Artikel ini akan menjadi pengantar Spring Data MongoDB yang cepat dan praktis.
Kami akan membahas dasar-dasarnya menggunakan MongoTemplate serta MongoRepository , dengan contoh praktis untuk mengilustrasikan setiap operasi.
Bacaan lebih lanjut:
Dukungan Geospasial di MongoDB
Lihat cara menyimpan, mengindeks, dan mencari data geospasial dengan MongoDBBaca lebih lanjut →Pengujian Integrasi Boot Musim Semi dengan MongoDB Tersemat
Pelajari cara menggunakan solusi MongoDB tertanam Flapdoodle bersama dengan Spring Boot untuk menjalankan tes integrasi MongoDB dengan lancar. Baca lebih lanjut →2. Templat Mongo dan MongoRepository
Template Mongo mengikuti pola template standar di Spring dan menyediakan API dasar yang siap pakai ke mesin persistensi yang mendasarinya.
Repositori mengikuti pendekatan Spring Data-centric dan dilengkapi dengan operasi API yang lebih fleksibel dan kompleks, berdasarkan pola akses yang terkenal di semua proyek Spring Data.
Untuk keduanya, kita harus mulai dengan mendefinisikan ketergantungan — misalnya, di pom.xml , dengan Maven:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>3.0.3.RELEASE</version>
</dependency>
Untuk memeriksa apakah ada versi baru perpustakaan yang telah dirilis, lacak rilisnya di sini.
3. Konfigurasi untuk MongoTemplate
3.1. Konfigurasi XML
Mari kita mulai dengan konfigurasi XML sederhana untuk template Mongo:
<mongo:mongo-client id="mongoClient" host="localhost" />
<mongo:db-factory id="mongoDbFactory" dbname="test" mongo-client-ref="mongoClient" />
Pertama-tama kita perlu mendefinisikan kacang pabrik yang bertanggung jawab untuk membuat instance Mongo.
Selanjutnya, kita harus benar-benar mendefinisikan (dan mengonfigurasi) kacang template:
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg ref="mongoDbFactory"/>
</bean>
Dan terakhir, kita perlu mendefinisikan prosesor pos untuk menerjemahkan MongoExceptions any dilemparkan ke @Repositori kelas beranotasi:
<bean class=
"org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
3.2. Konfigurasi Java
Sekarang mari kita buat konfigurasi serupa menggunakan konfigurasi Java dengan memperluas kelas dasar untuk konfigurasi MongoDB AbstractMongoConfiguration :
@Configuration
public class MongoConfig extends AbstractMongoClientConfiguration {
@Override
protected String getDatabaseName() {
return "test";
}
@Override
public MongoClient mongoClient() {
ConnectionString connectionString = new ConnectionString("mongodb://localhost:27017/test");
MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
.applyConnectionString(connectionString)
.build();
return MongoClients.create(mongoClientSettings);
}
@Override
public Collection getMappingBasePackages() {
return Collections.singleton("com.baeldung");
}
}
Perhatikan bahwa kita tidak perlu mendefinisikan MongoTemplate bean di konfigurasi sebelumnya karena sudah didefinisikan di AbstractMongoClientConfiguration .
Kami juga dapat menggunakan konfigurasi kami dari awal tanpa memperluas AbstractMongoClientConfiguration :
@Configuration
public class SimpleMongoConfig {
@Bean
public MongoClient mongo() {
ConnectionString connectionString = new ConnectionString("mongodb://localhost:27017/test");
MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
.applyConnectionString(connectionString)
.build();
return MongoClients.create(mongoClientSettings);
}
@Bean
public MongoTemplate mongoTemplate() throws Exception {
return new MongoTemplate(mongo(), "test");
}
}
4. Konfigurasi untuk MongoRepository
4.1. Konfigurasi XML
Untuk menggunakan repositori khusus (memperluas MongoRepository ), kita perlu melanjutkan konfigurasi dari bagian 3.1. dan atur repositori:
<mongo:repositories
base-package="com.baeldung.repository" mongo-template-ref="mongoTemplate"/>
4.2. Konfigurasi Java
Demikian pula, kita akan membangun konfigurasi yang telah kita buat di bagian 3.2. dan tambahkan anotasi baru ke dalam campuran:
@EnableMongoRepositories(basePackages = "com.baeldung.repository")
4.3. Buat Repositori
Setelah konfigurasi, kita perlu membuat repositori — memperluas MongoRepository antarmuka:
public interface UserRepository extends MongoRepository<User, String> {
//
}
Sekarang kita dapat melakukan auto-wire UserRepository . ini dan gunakan operasi dari MongoRepository atau tambahkan operasi khusus.
5. Menggunakan MongoTemplate
5.1. Sisipkan
Mari kita mulai dengan operasi penyisipan serta database kosong:
{
}
Sekarang jika kita memasukkan pengguna baru:
User user = new User();
user.setName("Jon");
mongoTemplate.insert(user, "user");
databasenya akan terlihat seperti ini:
{
"_id" : ObjectId("55b4fda5830b550a8c2ca25a"),
"_class" : "com.baeldung.model.User",
"name" : "Jon"
}
5.2. Simpan – Sisipkan
simpan operasi memiliki semantik simpan-atau-perbarui:jika ada id, ia melakukan pembaruan, dan jika tidak, ia melakukan penyisipan.
Mari kita lihat semantik pertama — sisipan.
Berikut status awal database:
{
}
Saat kita sekarang menyimpan pengguna baru:
User user = new User();
user.setName("Albert");
mongoTemplate.save(user, "user");
entitas akan dimasukkan ke dalam database:
{
"_id" : ObjectId("55b52bb7830b8c9b544b6ad5"),
"_class" : "com.baeldung.model.User",
"name" : "Albert"
}
Selanjutnya, kita akan melihat operasi yang sama — simpan — dengan semantik pembaruan.
5.3. Simpan – Perbarui
Sekarang mari kita lihat simpan dengan semantik pembaruan, beroperasi pada entitas yang ada:
{
"_id" : ObjectId("55b52bb7830b8c9b544b6ad5"),
"_class" : "com.baeldung.model.User",
"name" : "Jack"
}
Saat kita menyimpan pengguna yang ada, kami akan memperbaruinya:
user = mongoTemplate.findOne(
Query.query(Criteria.where("name").is("Jack")), User.class);
user.setName("Jim");
mongoTemplate.save(user, "user");
Basis data akan terlihat seperti ini:
{
"_id" : ObjectId("55b52bb7830b8c9b544b6ad5"),
"_class" : "com.baeldung.model.User",
"name" : "Jim"
}
Kita dapat melihat bahwa dalam contoh khusus ini, simpan menggunakan semantik update karena kita menggunakan objek dengan _id yang diberikan .
5.4. PerbaruiPertama
perbaruiPertama memperbarui dokumen pertama yang cocok dengan kueri.
Mari kita mulai dengan keadaan awal database:
[
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Alex"
},
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614c"),
"_class" : "com.baeldung.model.User",
"name" : "Alex"
}
]
Saat kita menjalankan updateFirst :
Query query = new Query();
query.addCriteria(Criteria.where("name").is("Alex"));
Update update = new Update();
update.set("name", "James");
mongoTemplate.updateFirst(query, update, User.class);
hanya entri pertama yang akan diperbarui:
[
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "James"
},
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614c"),
"_class" : "com.baeldung.model.User",
"name" : "Alex"
}
]
5.5. Perbarui Multi
Perbarui Multi memperbarui semua dokumen yang cocok dengan kueri yang diberikan.
Pertama, inilah keadaan database sebelum melakukan updateMulti :
[
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Eugen"
},
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614c"),
"_class" : "com.baeldung.model.User",
"name" : "Eugen"
}
]
Sekarang mari kita jalankan updateMulti operasi:
Query query = new Query();
query.addCriteria(Criteria.where("name").is("Eugen"));
Update update = new Update();
update.set("name", "Victor");
mongoTemplate.updateMulti(query, update, User.class);
Kedua objek yang ada akan diperbarui di database:
[
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Victor"
},
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614c"),
"_class" : "com.baeldung.model.User",
"name" : "Victor"
}
]
5.6. TemukanDanUbah
Operasi ini bekerja seperti updateMulti , tetapi mengembalikan objek sebelum diubah.
Pertama, ini adalah keadaan database sebelum memanggil findAndModify :
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Markus"
}
Mari kita lihat kode operasi yang sebenarnya:
Query query = new Query();
query.addCriteria(Criteria.where("name").is("Markus"));
Update update = new Update();
update.set("name", "Nick");
User user = mongoTemplate.findAndModify(query, update, User.class);
objek pengguna yang dikembalikan memiliki nilai yang sama dengan status awal dalam database.
Namun, ini adalah status baru dalam database:
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Nick"
}
5.7. Upser
tambahan bekerja pada temukan dan ubah yang lain buat semantik :jika dokumen cocok, perbarui, atau buat dokumen baru dengan menggabungkan objek kueri dan pembaruan.
Mari kita mulai dengan keadaan awal database:
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Markus"
}
Sekarang mari kita jalankan upsert :
Query query = new Query();
query.addCriteria(Criteria.where("name").is("Markus"));
Update update = new Update();
update.set("name", "Nick");
mongoTemplate.upsert(query, update, User.class);
Berikut keadaan database setelah operasi:
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Nick"
}
5.8. Hapus
Kita akan melihat status database sebelum memanggil remove :
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Benn"
}
Sekarang mari kita jalankan hapus :
mongoTemplate.remove(user, "user");
Hasilnya akan seperti yang diharapkan:
{
}
6. Menggunakan MongoRepository
6.1. Sisipkan
Pertama, kita akan melihat status database sebelum menjalankan insert :
{
}
Sekarang kita akan memasukkan pengguna baru:
User user = new User();
user.setName("Jon");
userRepository.insert(user);
Dan inilah keadaan akhir dari database:
{
"_id" : ObjectId("55b4fda5830b550a8c2ca25a"),
"_class" : "com.baeldung.model.User",
"name" : "Jon"
}
Perhatikan cara kerja operasi yang sama dengan insert di Template Mongo API.
6.2. Simpan – Sisipkan
Demikian pula, simpan bekerja sama dengan simpan operasi di MongoTemplate API.
Mari kita mulai dengan melihat sisipan semantik operasi.
Berikut keadaan awal database:
{
}
Sekarang kita jalankan simpan operasi:
User user = new User();
user.setName("Aaron");
userRepository.save(user);
Ini mengakibatkan pengguna ditambahkan ke database:
{
"_id" : ObjectId("55b52bb7830b8c9b544b6ad5"),
"_class" : "com.baeldung.model.User",
"name" : "Aaron"
}
Perhatikan lagi cara menyimpan bekerja dengan masukkan semantik karena kita memasukkan objek baru.
6.3. Simpan – Perbarui
Sekarang mari kita lihat operasi yang sama tetapi dengan perbarui semantik.
Pertama, inilah keadaan database sebelum menjalankan simpan baru :
{
"_id" : ObjectId("55b52bb7830b8c9b544b6ad5"),
"_class" : "com.baeldung.model.User",
"name" : "Jack"81*6
}
Sekarang kita jalankan operasinya:
user = mongoTemplate.findOne(
Query.query(Criteria.where("name").is("Jack")), User.class);
user.setName("Jim");
userRepository.save(user);
Akhirnya, inilah keadaan database:
{
"_id" : ObjectId("55b52bb7830b8c9b544b6ad5"),
"_class" : "com.baeldung.model.User",
"name" : "Jim"
}
Perhatikan lagi cara menyimpan bekerja dengan perbarui semantik karena kita menggunakan objek yang sudah ada.
6.4. Hapus
Berikut status database sebelum memanggil delete :
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Benn"
}
Ayo jalankan hapus :
userRepository.delete(user);
Dan inilah hasil kami:
{
}
6.5. Temukan Satu
Selanjutnya, ini adalah status database saat findOne disebut:
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Chris"
}
Sekarang mari kita jalankan findOne :
userRepository.findOne(user.getId())
Dan hasilnya akan mengembalikan data yang ada:
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Chris"
}
6.6. Ada
Status database sebelum memanggil ada :
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Harris"
}
Sekarang mari kita jalankan exists , yang tentu saja akan mengembalikan true :
boolean isExists = userRepository.exists(user.getId());
6.7. Temukan Semua Dengan Urutkan
Status database sebelum memanggil findAll :
[
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Brendan"
},
{
"_id" : ObjectId("67b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Adam"
}
]
Sekarang mari kita jalankan findAll dengan Urutkan :
List<User> users = userRepository.findAll(Sort.by(Sort.Direction.ASC, "name"));
Hasilnya akan diurutkan berdasarkan nama dalam urutan menaik :
[
{
"_id" : ObjectId("67b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Adam"
},
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Brendan"
}
]
6.8. Temukan Semua Dengan Dapat Dihalaman
Status database sebelum memanggil findAll :
[
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Brendan"
},
{
"_id" : ObjectId("67b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Adam"
}
]
Sekarang mari kita jalankan findAll dengan permintaan penomoran halaman:
Pageable pageableRequest = PageRequest.of(0, 1);
Page<User> page = userRepository.findAll(pageableRequest);
List<User> users = pages.getContent();
Pengguna . yang dihasilkan list hanya akan menjadi satu pengguna:
{
"_id" : ObjectId("55b5ffa5511fee0e45ed614b"),
"_class" : "com.baeldung.model.User",
"name" : "Brendan"
}
7. Anotasi
Terakhir, mari kita juga membahas anotasi sederhana yang digunakan Spring Data untuk mendorong operasi API ini.
Tingkat bidang @Id anotasi dapat menghiasi semua jenis, termasuk panjang dan string :
@Id
private String id;
Jika nilai @Id bidang tidak nol, itu disimpan dalam database apa adanya; jika tidak, konverter akan menganggap kita ingin menyimpan ObjectId dalam database (baik ObjectId , String atauBigInteger kerja).
Selanjutnya kita akan melihat @Document :
@Document
public class User {
//
}
Anotasi ini hanya menandai kelas sebagai objek domain yang perlu disimpan ke database, bersama dengan memungkinkan kita untuk memilih nama koleksi yang akan digunakan.