Preciso escrever um aplicativo com o qual possa fazer consultas complexas usando spring-data e mongodb. Comecei usando o MongoRepository, mas lutei com consultas complexas para encontrar exemplos ou realmente entender a sintaxe.
Estou falando de consultas como esta:
@Repository
public interface UserRepositoryInterface extends MongoRepository<User, String> {
List<User> findByEmailOrLastName(String email, String lastName);
}
ou o uso de consultas baseadas em JSON que tentei por tentativa e erro porque não entendi a sintaxe certa. Mesmo depois de ler a documentação do mongodb (exemplo que não funciona devido à sintaxe errada).
@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);
}
Depois de ler toda a documentação, parece que mongoTemplate
está muito melhor documentado MongoRepository
. Estou me referindo à seguinte documentação:
http://static.springsource.org/spring-data/data-mongodb/docs/current/reference/html/
Você pode me dizer o que é mais conveniente e poderoso de usar? mongoTemplate
ou MongoRepository
? Ambos são maduros ou um deles não tem mais recursos do que o outro?
fonte
YourRepository
, a classe de implementação terá que ser nomeadaYourRepositoryImpl
. É esse o caso? Se sim, estou feliz em dar uma olhada em um projeto de amostra no GitHub ou algo semelhante ...CustomUserRepository
e não deveriaCustomerUserRepository
.Esta resposta pode demorar um pouco, mas eu recomendo evitar toda a rota do repositório. Você obtém poucos métodos implementados de grande valor prático. Para fazê-lo funcionar, você se depara com o absurdo da configuração do Java, no qual pode passar dias e semanas sem muita ajuda na documentação.
Em vez disso, siga a
MongoTemplate
rota e crie sua própria camada de acesso a dados, que o livra dos pesadelos de configuração enfrentados pelos programadores do Spring.MongoTemplate
é realmente o salvador para engenheiros que se sentem confortáveis arquitetando suas próprias classes e interações, pois há muita flexibilidade. A estrutura pode ser algo assim:MongoClientFactory
classe que será executada no nível do aplicativo e fornecerá umMongoClient
objeto. Você pode implementar isso como um Singleton ou usando um Enum Singleton (isso é thread-safe)fonte
FWIW, com relação às atualizações em um ambiente multi-thread:
MongoTemplate
fornece "atômica" out-of-the-box operaçõesupdateFirst
,updateMulti
,findAndModify
,upsert
... que lhe permitem modificar um documento em uma única operação. OUpdate
objeto usado por esses métodos também permite que você direcione apenas os campos relevantes .MongoRepository
só dá-lhe as operações básicas CRUDfind
,insert
,save
,delete
, que trabalham com POJOs contendo todos os campos . Isso força você a atualizar os documentos em várias etapas (1.find
o documento a ser atualizado, 2. modificar os campos relevantes do POJO retornado e, em seguida, 3.save
ele) ou definir suas próprias consultas de atualização manualmente usando@Query
.Em um ambiente multiencadeado, como, por exemplo, um back-end Java com vários terminais REST, as atualizações de método único são o caminho a percorrer, a fim de reduzir as chances de duas atualizações simultâneas sobrescreverem as alterações uma da outra.
Exemplo: dado um documento como este:
{ _id: "ID1", field1: "a string", field2: 10.0 }
e duas threads diferentes atualizando-o simultaneamente ...Com
MongoTemplate
ele ficaria mais ou menos assim:e o estado final para o documento é sempre,
{ _id: "ID1", field1: "another string", field2: 15.0 }
pois cada thread está acessando o banco de dados apenas uma vez e apenas o campo especificado é alterado.Considerando que o mesmo cenário de caso com
MongoRepository
seria assim:e o documento final sendo
{ _id: "ID1", field1: "another string", field2: 10.0 }
ou{ _id: "ID1", field1: "a string", field2: 15.0 }
dependendo de qualsave
operação atinge o banco de dados por último.(NOTA: Mesmo se usássemos a
@Version
anotação do Spring Data como sugerido nos comentários, não mudaria muito: uma dassave
operações lançaria umOptimisticLockingFailureException
, e o documento final ainda seria um dos anteriores, com apenas um campo atualizado em vez de ambos. )Portanto, eu diria que essa
MongoTemplate
é a melhor opção , a menos que você tenha um modelo POJO muito elaborado ou precise dos recursos de consultas personalizadasMongoRepository
por algum motivo.fonte
@Version
"evitaria" o segundo encadeamento sobrescrever os dados salvos pelo primeiro - "evitaria" no sentido de que descartaria a atualização e lançaria umOptimisticLockingFailureException
em seu lugar. Portanto, você terá que implementar um mecanismo de repetição se quiser que a atualização seja bem-sucedida. MongoTemplate permite que você evite todo o cenário.