Necesito escribir una aplicación con la que pueda hacer consultas complejas usando spring-data y mongodb. Empecé usando MongoRepository, pero luché con consultas complejas para encontrar ejemplos o para comprender realmente la sintaxis.
Estoy hablando de consultas como esta:
@Repository
public interface UserRepositoryInterface extends MongoRepository<User, String> {
List<User> findByEmailOrLastName(String email, String lastName);
}
o el uso de consultas basadas en JSON que probé por ensayo y error porque no entiendo la sintaxis correcta. Incluso después de leer la documentación de mongodb (ejemplo que no funciona debido a una sintaxis incorrecta).
@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);
}
Después de leer toda la documentación, parece que mongoTemplate
está mucho mejor documentada MongoRepository
. Me refiero a la siguiente documentación:
http://static.springsource.org/spring-data/data-mongodb/docs/current/reference/html/
¿Puede decirme qué es más conveniente y poderoso de usar? mongoTemplate
o MongoRepository
? ¿Ambos son iguales o uno de ellos carece de más características que el otro?
fuente
YourRepository
, la clase de implementación tiene que ser identificadoYourRepositoryImpl
. ¿Es ese el caso? Si es así, estoy feliz de echar un vistazo a un proyecto de muestra en GitHub o similar…CustomUserRepository
y noCustomerUserRepository
.Esta respuesta puede retrasarse un poco, pero recomendaría evitar toda la ruta del repositorio. Obtiene muy pocos métodos implementados de gran valor práctico. Para que funcione, se encuentra con la tontería de la configuración de Java en la que puede pasar días y semanas sin mucha ayuda en la documentación.
En su lugar, siga la
MongoTemplate
ruta y cree su propia capa de acceso a datos que lo libere de las pesadillas de configuración que enfrentan los programadores de Spring.MongoTemplate
es realmente el salvador para los ingenieros que se sienten cómodos diseñando sus propias clases e interacciones, ya que hay mucha flexibilidad. La estructura puede ser algo como esto:MongoClientFactory
clase que se ejecutará a nivel de aplicación y te dará unMongoClient
objeto. Puede implementar esto como Singleton o usando un Enum Singleton (esto es seguro para subprocesos)fuente
FWIW, con respecto a las actualizaciones en un entorno de subprocesos múltiples:
MongoTemplate
proporciona "atómica" out-of-the-box operacionesupdateFirst
,updateMulti
,findAndModify
,upsert
..., que le permiten modificar un documento en una sola operación. ElUpdate
objeto utilizado por estos métodos también le permite apuntar solo a los campos relevantes .MongoRepository
sólo le da las operaciones básicas CRUDfind
,insert
,save
,delete
, que trabajan con POJOs que contienen todos los campos . Esto le obliga a actualizar los documentos en varios pasos (1.find
el documento a actualizar, 2. modificar los campos relevantes del POJO devuelto, y luego 3.save
), o definir sus propias consultas de actualización manualmente usando@Query
.En un entorno de subprocesos múltiples, como por ejemplo, un back-end de Java con varios puntos finales REST, las actualizaciones de un solo método son el camino a seguir, para reducir las posibilidades de que dos actualizaciones simultáneas sobrescriban los cambios entre sí.
Ejemplo: dado un documento como este:
{ _id: "ID1", field1: "a string", field2: 10.0 }
y dos subprocesos diferentes actualizándolo simultáneamente ...Con
MongoTemplate
se vería algo así:y el estado final del documento es siempre,
{ _id: "ID1", field1: "another string", field2: 15.0 }
ya que cada hilo accede a la base de datos solo una vez y solo se cambia el campo especificado.Considerando que el mismo escenario de caso con
MongoRepository
se vería así:y el documento final es
{ _id: "ID1", field1: "another string", field2: 10.0 }
o{ _id: "ID1", field1: "a string", field2: 15.0 }
depende desave
la última operación que llegue a la base de datos.(NOTA: Incluso si usáramos la
@Version
anotación de Spring Data como se sugiere en los comentarios, no cambiaría mucho: una de lassave
operaciones arrojaría unOptimisticLockingFailureException
, y el documento final aún sería uno de los anteriores, con solo un campo actualizado en lugar de ambos. )Entonces, diría que
MongoTemplate
es una mejor opción , a menos que tenga un modelo POJO muy elaborado o necesite las capacidades de consultas personalizadas deMongoRepository
por alguna razón.fuente
@Version
"evitaría" que el segundo subproceso sobrescribiera los datos guardados por el primero - "evitar" en el sentido de que descartaría la actualización y lanzaría unaOptimisticLockingFailureException
. Por lo tanto, tendría que implementar un mecanismo de reintento si desea que la actualización se realice correctamente. MongoTemplate le permite evitar todo el escenario.