J'ai besoin d'écrire une application avec laquelle je peux faire des requêtes complexes en utilisant spring-data et mongodb. J'ai commencé par utiliser MongoRepository mais j'ai eu du mal avec des requêtes complexes pour trouver des exemples ou pour comprendre réellement la syntaxe.
Je parle de requêtes comme celle-ci:
@Repository
public interface UserRepositoryInterface extends MongoRepository<User, String> {
List<User> findByEmailOrLastName(String email, String lastName);
}
ou l'utilisation de requêtes basées sur JSON que j'ai essayées par essais et erreurs parce que je ne comprends pas la bonne syntaxe. Même après avoir lu la documentation de mongodb (exemple qui ne fonctionne pas en raison d'une syntaxe incorrecte).
@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);
}
Après avoir lu toute la documentation, il semble que ce mongoTemplate
soit bien mieux documenté MongoRepository
. Je fais référence à la documentation suivante:
http://static.springsource.org/spring-data/data-mongodb/docs/current/reference/html/
Pouvez-vous me dire ce qui est plus pratique et plus puissant à utiliser? mongoTemplate
ou MongoRepository
? Les deux sont-ils les mêmes matures ou l'un d'eux manque-t-il plus de fonctionnalités que l'autre?
la source
YourRepository
, la classe d'implémentation doit être nomméeYourRepositoryImpl
. Est-ce le cas? Si c'est le cas, je suis heureux de jeter un coup d'œil à un exemple de projet sur GitHub ou similaire…CustomUserRepository
et nonCustomerUserRepository
.Cette réponse peut être un peu retardée, mais je recommanderais d'éviter toute la route du référentiel. Vous obtenez très peu de méthodes implémentées d'une grande valeur pratique. Pour que cela fonctionne, vous rencontrez des absurdités de configuration Java sur lesquelles vous pouvez passer des jours et des semaines sans beaucoup d'aide dans la documentation.
Au lieu de cela, suivez l'
MongoTemplate
itinéraire et créez votre propre couche d'accès aux données qui vous libère des cauchemars de configuration auxquels sont confrontés les programmeurs Spring.MongoTemplate
est vraiment le sauveur pour les ingénieurs qui sont à l'aise pour concevoir leurs propres classes et interactions car il y a beaucoup de flexibilité. La structure peut être quelque chose comme ceci:MongoClientFactory
classe qui s'exécutera au niveau de l'application et vous donnera unMongoClient
objet. Vous pouvez l'implémenter en tant que Singleton ou en utilisant un Enum Singleton (c'est thread-safe)la source
FWIW, concernant les mises à jour dans un environnement multi-thread:
MongoTemplate
fournit des opérations « atomique » out-of-the-boxupdateFirst
,updateMulti
,findAndModify
,upsert
... qui vous permettent de modifier un document en une seule opération. L'Update
objet utilisé par ces méthodes vous permet également de cibler uniquement les champs pertinents .MongoRepository
ne vous donne les opérations CRUD de basefind
,insert
,save
,delete
, qui travaillent avec POJO contenant tous les champs . Cela vous oblige soit à mettre à jour les documents en plusieurs étapes (1.find
le document à mettre à jour, 2. à modifier les champs pertinents du POJO renvoyé, puis 3. àsave
le), soit à définir manuellement vos propres requêtes de mise à jour à l'aide de@Query
.Dans un environnement multi-thread, comme par exemple un back-end Java avec plusieurs points de terminaison REST, les mises à jour à méthode unique sont la voie à suivre, afin de réduire les chances que deux mises à jour simultanées écrasent les modifications de l'autre.
Exemple: étant donné un document comme celui-ci:
{ _id: "ID1", field1: "a string", field2: 10.0 }
et deux threads différents le mettant à jour simultanément ...Avec
MongoTemplate
cela ressemblerait un peu à ceci:et l'état final du document est toujours
{ _id: "ID1", field1: "another string", field2: 15.0 }
puisque chaque thread n'accède au DB qu'une seule fois et que seul le champ spécifié est modifié.Alors que le même scénario de cas
MongoRepository
ressemblerait à ceci:et le document final étant l'un
{ _id: "ID1", field1: "another string", field2: 10.0 }
ou l' autre ou{ _id: "ID1", field1: "a string", field2: 15.0 }
selon quellesave
opération atteint le dernier DB.(REMARQUE: même si nous utilisions l'
@Version
annotation de Spring Data comme suggéré dans les commentaires, rien ne changerait: l'une dessave
opérations lèverait unOptimisticLockingFailureException
, et le document final serait toujours l'un des ci-dessus, avec un seul champ mis à jour au lieu des deux. )Je dirais donc que
MongoTemplate
c'est une meilleure option , à moins que vous n'ayez un modèle POJO très élaboré ou que vous ayez besoin des capacités de requêtes personnalisées deMongoRepository
pour une raison quelconque.la source
@Version
"éviterait" le deuxième thread d'écraser les données sauvegardées par le premier - "éviterait" dans le sens où il rejetterait la mise à jour et lancerait un à laOptimisticLockingFailureException
place. Vous devrez donc implémenter un mécanisme de nouvelle tentative si vous voulez que la mise à jour réussisse. MongoTemplate vous permet d'éviter tout le scénario.