Spring Boot – Data Repository Queries mit MongoDB
Einleitung
In diesem Tutorial beschreibe ich wie ihr mit dem Spring Data Projekt Datenbank Abfragen erstellen könnt ohne dabei eine Zeile Code in der Abfragesprache der Datenbank zu schreiben. Dieses Tutorial basiert auf dem Tutorial „Spring Boot – Data Repository mit MongoDB erstellen„. Wir werden das bestehende Tutorial so erweitern, dass wir eine Suchbegriff über einen Rest GET Aufruf erhalten und diesen weitergeben bis zur Mongodb. Anschließend wird das Ergebnis ausgegeben. Exemplarisch wird die Abfrage für eine Attribut implementiert. Die Implementierung für weitere Attribute ist so gesehen dank Spring Data identisch.
Voraussetzung
- Existierende Java 8 Installation
- Existierende Maven 3 Installation
- Existierende MongoDB Installation auf Port 2017
- Grundkenntnisse in REST
- Tutorial: Spring Boot – Data Repository Tutorial
Repository Interface erweitern
Als erstes erweitern wir das aus dem Tutorial „Spring Boot – Data Repository mit MongoDB erstellen“ bekannte Repository Interface. Hier möchten wir erreichen, dass wir über das Repository Interface Customer Objekte erhalten dessen Vornamen identisch sind mit dem Wert, der über die Rest Schnittstelle übergeben wird.
Folgendes Codebeispiel zeigt unsere CustomerRepository.java Interface
package de.ertantoker.tutorial; import org.springframework.data.mongodb.repository.MongoRepository; import java.util.List; public interface CustomerRepository extends MongoRepository<Customer, String> { List findCustomersByFirstname(String firstname); }
RestController erweitern
Nachdem wir nun das Repository Interface erweitert haben müssen wir die neue Methode um Controller aufrufen und das Ergebnis zurück geben.
Folgender Code zeigt den vollständigen RestController
package de.ertantoker.tutorial; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/customers") public class CustomerController { private CustomerRepository customerRepository; public CustomerController(CustomerRepository customerRepository) { this.customerRepository = customerRepository; } @GetMapping public ResponseEntity<List> getCustomers() { return new ResponseEntity<>(customerRepository.findAll(), HttpStatus.OK); } @PostMapping public ResponseEntity createCustomer(@RequestBody Customer customer) { Customer savedCustomer = customerRepository.save(customer); return new ResponseEntity<>(savedCustomer, HttpStatus.CREATED); } @GetMapping("/{id}") public ResponseEntity getCustomerById(@PathVariable String id) { return customerRepository.findById(id) .map(customer -> new ResponseEntity<>(customer, HttpStatus.OK)) .orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND)); } @GetMapping public ResponseEntity<List> getCustomerByFistname(@RequestParam String firstname) { return new ResponseEntity<>(customerRepository.findCustomersByFirstname(firstname), HttpStatus.OK); } }
Rest GET Methode testen
Aus meinen vorherigen Tutorial haben wir gesehen wie man Daten über die Rest Post Methode speichern kann. Ich würde euch daher empfehlen einige Datensätze abzuspeichern und dann über die neue GET Methode die Query über die MongoDB mit Spring Data zu testen. Ob ihr die Query richtig geschrieben habt wisst ihr wenn die Spring Boot Anwendung komplett startet. Spring Boot ist so implementiert, dass wenn man Queries erstellt die nicht funktionieren, dass dann die Spring Boot Anwendung nicht startet. Somit hättet ihr für euch schon einen ersten Test. Ob durch die Query jetzt auch richtigen Daten geliefert werden müsst ihr manuell über Postman testen. Natürlich konnte man das Ganze auch mit einem Spring Boot Integrationstest abdecken aber das würde jetzt den Rahmen des Tutorials sprengen. Wie man Spring Boot Integrationstests schreibt werde ich dann in einem anderen Tutorial von mir beschreiben.
Mit dem folgenden URL Aufruf könnt ihr schauen ob die neue GET Methode Ergebnisse liefert:
https://localhost:8080/customers?firstname=Testvalue
TestValue steht hier für den Wert den ihr als Vornamen suchen wollt. Die Methode würde aber nur Ergebnisse liefern, wenn ihr vorher über die POST Methode Daten gespeichert habt.
Spring Data – Repository Interface Beispiele
Bis jetzt haben wir im Tutorial eine Recht einfache Abfrage gesehen. Mit Spring Boot Data kann man aber noch viel kompliziertere Abfragen erstellen. Basierend auf der Customer.java Klase werden ich einige weitere Abfragen erstellen und diese auch kurz kommentieren.
List<Customer> findCustomersByFirstnameAndLastname(String firstname, String lastname) -> Finde alle Kunden die den Vornamen „firstname“ UND den Nachnamen „lastname“ haben.
List<Customer> findCutomersByLikeFirstname(String str) -> Finde alle Kunden dessen Vornamen mit dem Wert von str starten. Ist im SQL vergelichbar mit dem LIKE befehl.
List<Customer> findCustomersByFirstnameAndLastnameOrderByLastname(String firstname, String lastname) ->Finde alle Kunden die den Vornamen „firstname“ UND den Nachnamen „lastname“ haben und sortiere die Listenelemente nach dem Nachnamen.
Mit Spring Data ist es auch Queries zu erstellen, die auf Properties von Objekten zugreifen, die eingebettet sind.
Wir stellen uns vor, dass wir die Klasse Customer.java eine Property private Address address besitzt. Die Klasse Address hat wiederum folgende Properties als String: street, zipCode, city. Um jetzt alle Customer Objekte zu finden die in ihrer Adresse die Postleitzahl (zipCode ) 42579 haben müssten wir folgende Query schreiben.
List<Customer> findCustomersByAddressZipCode(String zipCode)
Diese Vorgehensweise kann man beliebig verschachteln. Natürlich kommt man irgendwann an den Punkt wo die Query nicht mehr lesbar ist. Da sollte man dann sich überlegen ob man eventuell andere Verfahren verwenden sollte.
Das Schema wie eine Query aufgebaut ist immer gleich. Folgender Ansatz hat sich bei meinen Projekten immer bewährt:
List<Type> findTypesByPropertyname(String str)
List<Type> findTypesByPropertyPropertyname(String str) -> Property steht für die Property die in der Klasse definiert ist. Propertyname steht für den Propertynamen der in der blauben Property definiert ist. Siehe hierzu das Beispiel oben mit der Adresse.
Natürlich kann man auch weitere Queries erstellen. Was Spring Data da an Umfang anzubieten hat könnt ihr euch gerne auf der Reference Dokumentation von Spring Data anschauen.
Das Ergebnis
In diesem Tutorial haben wir gesehen wie man mit Spring Data und den Repository Interfaces Datenbank Abfragen schreiben kann ohne eine Zeile in der Abfragesprache der jeweiligen Datenbank zu schreiben. Das Spring Data Projekt gibt es auch für klassische SQL Datenbank wie MySQL oder MariaDB. Wir haben in dem Tutorial nur einen kleinen Einblick in die Mächtigkeiten von Spring Data gesehen. Natürlich gibt es auch mit Spring Data Repositories Grenzen. Für die meisten „Default-Abfragen“ ist Spring Data vollkommen ausreichend. In meinen Projekten habe ich die Erfahrung gemacht, dass die Entwicklungszeit dank Spring Data unheimlich reduziert wurde. Wenn man das Ganze dann auch mit Spring Boot Integrationstests verbindet, kann man sicher sein, dass die Query auch funktioniert.
Ich hoffe euch hat mein Tutorial gefallen. Würde mich über Kritik, Anregungen und Vorschläge freuen. Solltet ihr eine spezielle Frage haben, dann schreibt einfach unten ein Kommentar.
[amazon_link asins=’3864905257,3864902908,3864901537′ template=’ProductCarousel‘ store=’fitnes06-21′ marketplace=’DE‘ link_id=’59b0499f-bb3b-11e8-a4b9-5ff41f9f8f96′]