Ich muss eine Anwendung schreiben, mit der ich komplexe Abfragen mit Spring-Data und Mongodb durchführen kann. Ich habe mit der Verwendung des MongoRepository begonnen, hatte jedoch Probleme mit komplexen Abfragen, um Beispiele zu finden oder die Syntax tatsächlich zu verstehen.
Ich spreche von Fragen wie diesen:
@Repository
public interface UserRepositoryInterface extends MongoRepository<User, String> {
List<User> findByEmailOrLastName(String email, String lastName);
}
oder die Verwendung von JSON-basierten Abfragen, die ich durch Ausprobieren ausprobiert habe, weil ich die Syntax nicht richtig verstanden habe. Auch nach dem Lesen der Mongodb-Dokumentation (nicht funktionierendes Beispiel aufgrund falscher Syntax).
@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);
}
Nach dem Durchlesen der gesamten Dokumentation scheint dies mongoTemplate
weitaus besser dokumentiert zu sein MongoRepository
. Ich beziehe mich auf folgende Dokumentation:
http://static.springsource.org/spring-data/data-mongodb/docs/current/reference/html/
Können Sie mir sagen, was bequemer und leistungsfähiger zu verwenden ist? mongoTemplate
oder MongoRepository
? Sind beide gleich ausgereift oder fehlt einem von ihnen mehr Funktionen als dem anderen?
quelle
YourRepository
, muss die Implementierungsklasse benannt werdenYourRepositoryImpl
. Ist das der Fall? Wenn ja, schaue ich mir gerne ein Beispielprojekt auf GitHub oder ähnlichem an…CustomUserRepository
und nichtCustomerUserRepository
.Diese Antwort kann etwas verzögert sein, aber ich würde empfehlen, die gesamte Repository-Route zu vermeiden. Sie erhalten sehr wenig implementierte Methoden von großem praktischem Wert. Damit es funktioniert, stoßen Sie auf den Unsinn der Java-Konfiguration, an dem Sie Tage und Wochen ohne viel Hilfe in der Dokumentation arbeiten können.
Gehen Sie stattdessen zur
MongoTemplate
Route und erstellen Sie Ihre eigene Datenzugriffsschicht, die Sie von den Konfigurations-Albträumen befreit, mit denen Spring-Programmierer konfrontiert sind.MongoTemplate
ist wirklich der Retter für Ingenieure, die ihre eigenen Klassen und Interaktionen gut gestalten können, da es viel Flexibilität gibt. Die Struktur kann ungefähr so aussehen:MongoClientFactory
Klasse, die auf Anwendungsebene ausgeführt wird, und geben Sie einMongoClient
Objekt an. Sie können dies als Singleton oder mit einem Enum Singleton implementieren (dies ist threadsicher).quelle
FWIW zu Updates in einer Multithread-Umgebung:
MongoTemplate
bietet „atomare“ out-of-the-Box - OperationenupdateFirst
,updateMulti
,findAndModify
,upsert
... , das Ihnen ein Dokument in einem einzigen Vorgang modifizieren lassen. Mit demUpdate
von diesen Methoden verwendeten Objekt können Sie auch nur auf die relevanten Felder abzielen .MongoRepository
nur gibt Ihnen die grundlegenden CRUD - Operationenfind
,insert
,save
,delete
, die Arbeit mit POJOs enthält alle Felder . Dies zwingt Sie, entweder die Dokumente in mehreren Schrittenfind
zu aktualisieren (1. das zu aktualisierende Dokument, 2. die relevanten Felder aus dem zurückgegebenen POJO zu ändern und dann 3.save
es) oder Ihre eigenen Aktualisierungsabfragen von Hand mit zu definieren@Query
.In einer Multithread-Umgebung, z. B. einem Java-Back-End mit mehreren REST-Endpunkten, sind Aktualisierungen mit einer Methode der richtige Weg, um die Wahrscheinlichkeit zu verringern, dass zwei Aktualisierungen gleichzeitig die Änderungen des anderen überschreiben.
Beispiel: ein Dokument wie dieses gegeben:
{ _id: "ID1", field1: "a string", field2: 10.0 }
und zwei verschiedene Threads, die es gleichzeitig aktualisieren ...Damit
MongoTemplate
würde es ungefähr so aussehen:und der Endzustand für das Dokument ist immer,
{ _id: "ID1", field1: "another string", field2: 15.0 }
da jeder Thread nur einmal auf die Datenbank zugreift und nur das angegebene Feld geändert wird.Während das gleiche Szenario mit
MongoRepository
so aussehen würde:und das endgültige Dokument ist entweder
{ _id: "ID1", field1: "another string", field2: 10.0 }
oder{ _id: "ID1", field1: "a string", field2: 15.0 }
abhängig davon, welchesave
Operation die Datenbank zuletzt trifft.(HINWEIS: Selbst wenn wir die in den Kommentaren vorgeschlagene Annotation von Spring Data
@Version
verwenden würden, würde sich nicht viel ändern: Eine dersave
Operationen würde eine auslösenOptimisticLockingFailureException
, und das endgültige Dokument wäre immer noch eine der oben genannten, wobei nur ein Feld anstelle von beiden aktualisiert wird. )Daher würde ich sagen, dass dies
MongoTemplate
eine bessere Option ist , es sei denn, Sie haben ein sehr ausgefeiltes POJO-Modell oder benötigenMongoRepository
aus irgendeinem Grund die Funktionen für benutzerdefinierte Abfragen .quelle
@Version
würde "vermeiden", dass der zweite Thread die vom ersten gespeicherten Daten überschreibt - "vermeiden" in dem Sinne, dass das Update verworfen undOptimisticLockingFailureException
stattdessen ein geworfen wird. Sie müssten also einen Wiederholungsmechanismus implementieren, wenn das Update erfolgreich sein soll. Mit MongoTemplate können Sie das gesamte Szenario vermeiden.