Saya perlu menulis aplikasi yang dapat saya gunakan untuk melakukan kueri kompleks menggunakan data musim semi dan mongodb. Saya telah mulai dengan menggunakan MongoRepository tetapi berjuang dengan kueri kompleks untuk menemukan contoh atau benar-benar memahami Sintaksnya.
Saya berbicara tentang pertanyaan seperti ini:
@Repository
public interface UserRepositoryInterface extends MongoRepository<User, String> {
List<User> findByEmailOrLastName(String email, String lastName);
}
atau penggunaan kueri berbasis JSON yang saya coba dengan coba-coba karena saya tidak mendapatkan sintaks yang benar. Bahkan setelah membaca dokumentasi mongodb (contoh tidak berfungsi karena sintaks yang salah).
@Repository
public interface UserRepositoryInterface extends MongoRepository<User, String> {
@Query("'$or':[{'firstName':{'$regex':?0,'$options':'i'}},{'lastName':{'$regex':?0,'$options':'i'}}]")
List<User> findByEmailOrFirstnameOrLastnameLike(String searchText);
}
Setelah membaca semua dokumentasi, tampaknya itu mongoTemplate
jauh lebih baik didokumentasikan MongoRepository
. Saya mengacu pada dokumentasi berikut:
http://static.springsource.org/spring-data/data-mongodb/docs/current/reference/html/
Bisakah Anda memberi tahu saya apa yang lebih nyaman dan kuat untuk digunakan? mongoTemplate
atau MongoRepository
? Apakah keduanya sama dewasa atau apakah salah satu dari mereka kekurangan lebih banyak fitur daripada yang lain?
sumber
YourRepository
, kelas implementasi harus dinamaiYourRepositoryImpl
. Apakah itu masalahnya? Jika demikian, saya senang melihat proyek sampel di GitHub atau sejenisnya…CustomUserRepository
dan tidakCustomerUserRepository
.Jawaban ini mungkin sedikit tertunda, tetapi saya akan merekomendasikan untuk menghindari seluruh rute repositori. Anda mendapatkan sangat sedikit metode yang diimplementasikan dengan nilai praktis yang besar. Untuk membuatnya berfungsi, Anda mengalami omong kosong konfigurasi Java yang dapat Anda habiskan berhari-hari dan berminggu-minggu tanpa banyak bantuan dalam dokumentasi.
Sebaliknya, ikuti
MongoTemplate
rute dan buat lapisan akses Data Anda sendiri yang membebaskan Anda dari mimpi buruk konfigurasi yang dihadapi oleh pemrogram Spring.MongoTemplate
benar-benar penyelamat bagi para insinyur yang merasa nyaman merancang kelas dan interaksi mereka sendiri karena ada banyak fleksibilitas. Strukturnya bisa seperti ini:MongoClientFactory
kelas yang akan berjalan di tingkat aplikasi dan memberi AndaMongoClient
objek. Anda dapat menerapkan ini sebagai Singleton atau menggunakan Enum Singleton (ini thread safe)sumber
FWIW, terkait pembaruan di lingkungan multi-utas:
MongoTemplate
memberikan "atom" out-of-the-box operasiupdateFirst
,updateMulti
,findAndModify
,upsert
... yang memungkinkan Anda untuk memodifikasi dokumen dalam satu operasi. TheUpdate
objek yang digunakan oleh metode ini juga memungkinkan Anda untuk menargetkan hanya bidang yang relevan .MongoRepository
hanya memberikan Anda operasi CRUD dasarfind
,insert
,save
,delete
, yang bekerja dengan POJOs yang berisi semua bidang . Ini memaksa Anda untuk memperbarui dokumen dalam beberapa langkah (1.find
dokumen untuk diperbarui, 2. memodifikasi bidang yang relevan dari POJO yang dikembalikan, dan 3. kemudiansave
), atau menentukan kueri pembaruan Anda sendiri dengan menggunakan tangan@Query
.Dalam lingkungan multi-utas, seperti misalnya back-end Java dengan beberapa titik akhir REST, pembaruan metode tunggal adalah cara yang harus dilakukan, untuk mengurangi kemungkinan dua pembaruan bersamaan menimpa perubahan satu sama lain.
Contoh: diberi dokumen seperti ini:
{ _id: "ID1", field1: "a string", field2: 10.0 }
dan dua utas berbeda secara bersamaan memperbaruinya ...Dengan
MongoTemplate
itu akan terlihat seperti ini:THREAD_001 THREAD_002 | | |update(query("ID1"), Update().set("field1", "another string")) |update(query("ID1"), Update().inc("field2", 5)) | | | |
dan status akhir untuk dokumen selalu
{ _id: "ID1", field1: "another string", field2: 15.0 }
karena setiap utas mengakses DB hanya sekali dan hanya bidang yang ditentukan yang diubah.Sedangkan skenario kasus yang sama dengan
MongoRepository
akan terlihat seperti ini:THREAD_001 THREAD_002 | | |pojo = findById("ID1") |pojo = findById("ID1") |pojo.setField1("another string") /* field2 still 10.0 */ |pojo.setField2(pojo.getField2()+5) /* field1 still "a string" */ |save(pojo) |save(pojo) | | | |
dan dokumen akhir menjadi salah satu
{ _id: "ID1", field1: "another string", field2: 10.0 }
atau{ _id: "ID1", field1: "a string", field2: 15.0 }
bergantung padasave
operasi mana yang terakhir kali mencapai DB.(CATATAN: Bahkan jika kita menggunakan anotasi Spring Data
@Version
seperti yang disarankan dalam komentar, tidak banyak yang akan berubah: salah satusave
operasi akan membuangOptimisticLockingFailureException
, dan dokumen terakhir akan tetap menjadi salah satu dari yang di atas, dengan hanya satu bidang yang diperbarui, bukan keduanya. )Jadi menurut saya itu
MongoTemplate
adalah opsi yang lebih baik , kecuali Anda memiliki model POJO yang sangat rumit atau memerlukan kemampuan kueri khususMongoRepository
karena alasan tertentu.sumber
@Version
akan "menghindari" utas kedua menimpa data yang disimpan oleh yang pertama - "menghindari" dalam arti bahwa ia akan membuang pembaruan dan sebagaiOptimisticLockingFailureException
gantinya. Jadi, Anda harus menerapkan mekanisme coba lagi jika ingin pembaruan berhasil. MongoTemplate memungkinkan Anda menghindari seluruh skenario.