5. MongoDB i Java
Anem a veure com accedir a MongoDB des dels nostres programes Java. Primerament, com vam veure a la unitat 2, estudiarem com accedir directament i desprès des de ORM.
5.1. Drivers
Com ja sabem, per connectar des de les nostres aplicacions a una base de dades necessitem un controlador o driver. MongoDB ofereix drivers oficials per a una multitud de plataformes, incloent C, C++, C#, NodeJS, Python, i per descomptat, Java, entre molts altres.
Focalitzant-nos en Java, MongoDB ens ofereix dos drivers:
- El driver Java per a aplicacions síncrones.
- El driver de Reactive Streams per al processament de Streams asíncrons.
Encara que actualment hi ha una tendència cap a la programació reactiva, treballarem amb el driver Java síncron per facilitar la comprensió i centrar-nos en l'accés real a les dades.
5.1.1. El driver Java
Utilitzant el MongoDB Driver per a Java podem connectar tant a una base de dades local o remota, com a un clúster de MongoDB Atlas. Aquest driver (MongoDB Java Driver) es pot trobar als repositoris Maven, i proporciona un gran nombre de classes i interfícies per facilitar el treball amb MongoDB des de Java.
En un projecte Gradle hauríem d'utilitzar:
| Bash | |
|---|---|
mentre que en un projecte Maven:
| XML | |
|---|---|
5.2. Connexió a una base de dades
Per connectar i comunicar-nos amb una base de dades necessitem un client. En el cas del driver de Java per a MongoDB, el client s'implementa a través de la classe MongoClient.
La classe MongoClient representa un conjunt de connexions a un servidor MongoDB. Aquestes connexions són segures per a fils, és a dir, diversos fils d'execució poden accedir-hi de manera segura.
La manera de crear instàncies de MongoClient és a través del mètode MongoClients.create(). A més, generalment, només necessitem una instància d'aquesta classe, fins i tot en aplicacions multi-fil. El mètode MongoClients.create pren com a argument una Connection String, amb el següent format simplificat (els paràmetres entre claudàtors són opcionals):
| Bash | |
|---|---|
Així, una manera d'obtenir, per exemple, una connexió al servidor local seria:
| Java | |
|---|---|
La classe MongoClient, entre altres, suporta els següents mètodes:
getDatabase(String name)→ Obté una referència a una base de dades el nom de la qual es passa com a argument.listDatabaseNames()→ Obté una llista de Strings (interfícieMongoIterable) amb els noms de les bases de dades del servidor.close()→ Tanca la connexió amb el servidor. Sempre s'ha de fer quan ja no es vagi a utilitzar.
5.2.1. MongoDatabase
El mètode getDatabase() de la classe MongoClient retorna una referència a un objecte que implementa la interfície MongoDatabase, que representa una connexió a una base de dades. Aquesta interfície defineix els següents mètodes:
getCollection(String name)→ Obté una referència a la col·lecció.listCollectionNames()→ Obté una llista de Strings (interfícieMongoIterable) amb els noms de les col·leccions de la base de dades.listCollections()→ Obté una llista de referències (MongoCollection) a les col·leccions de la base de dades.createCollection(String name)→ Crea una nova col·lecció amb el nom especificat a la base de dades.drop()→ Elimina la base de dades.
Aquí trobaràs un exemple de connexió i llistat de bases de dades i col·leccions d'un servidor donat:
5.3. Consultes
El mètode getCollection() de MongoDatabase() ens proporciona una col·lecció de Document (MongoCollection<Document>), sobre la qual podrem realitzar consultes utilitzant el mètode find(). Aquest mètode, que ja coneixem del shell de MongoDB, ens permetrà filtrar documents basant-nos en certs criteris.
Aquests criteris s'expressen com a filtres (query filters en la documentació), i poden contenir diversos operadors de consulta sobre alguns camps que determinaran quins documents de la col·lecció s'inclouen com a resultats.
La classe Filter ens proporciona mètodes de fàbrica per realitzar aquestes consultes, de manera similar a com treballàvem amb el shell de MongoDB. Aquesta classe ens ofereix:
- Consulta buida, amb
Filters.empty(). - Operadors de comparació: Per realitzar consultes basades en valors de la col·lecció:
Filters.eq(key, value),Filters.gt(key, value),Filters.gte(key, value),Filters.lt(key, value)oFilters.lte(key, value).
- Operadors lògics: Per realitzar operacions lògiques sobre el resultat d'altres consultes:
Filter.and(other_filters),Filter.or(other_filters), etc. - Operadors d'array: Permeten realitzar consultes basades en el valor o nombre d'elements d'un vector:
Filters.size(vector, size). - Altres operadors, com
Filter.exists()oFilter.regex(), per comprovar l'existència d'una clau o realitzar una cerca amb expressió regular.
A més dels filtres, també podrem incloure operacions d'agregació, a través del mètode aggregate() d'una instància de MongoCollection. Pots consultar la documentació sobre agregacions a la guia d'operacions d'agregació de MongoDB.
D'altra banda, l'API del driver de MongoDB també ens permet realitzar projeccions de camps utilitzant la classe Projections, que ofereix els mètodes Projections.fields(), Projections.include() o Projections.excludeID().
Exemple de cerca de pel·lícules d'un any donat, només 10 resultats:
Recorda
La classe Document té diversos mètodes per treballar com a documents JSON a la unitat 1. Podem obtenir cada camp donada una clau, obtenint el seu valor.
Un altre exemple amb filtres i projeccions: