Transkripte
1. Einführung: Hallo zusammen und willkommen
zum Spring Boot-Crashkurs. Die beste Online-Ressource, die Sie benötigen, um Spring Boot von
Grund auf zu lernen und ein
besserer Software-Ingenieur zu werden. Springboard-Framework wird von
vielen großen Technologieunternehmen verwendet , um ihre
Microservice-Architekturen und groß angelegten
Backend-Systeme zu erstellen, da es Ihnen hilft, eine
hochperformante Produktion aufzubauen bewerten Sie Anwendungen und sorgen Sie gleichzeitig dafür, dass Ihre
Codebasis skalierbar bleibt. Sie
unsere Fähigkeiten eingeübt haben können Sie auf
dem Arbeitsmarkt
wettbewerbsfähiger werden . Dies ist definitiv
eine erforderliche Technologie Sie auf Ihrem Weg zur
Senior-Backend-Software
beherrschen müssen.
Ingenieur. In diesem Kurs, unserem Kurs, werden
wir eine Rest-API mit
Spring Boot von
Grund auf neu erstellen , die mit
einer externen API über HTTP,
aber auch mit einer
lokalen MySQL-Datenbank
kommuniziert einer externen API über HTTP, aber auch mit einer
lokalen MySQL-Datenbank um einige zu speichern Benutzerdaten. Ziel dieses Kurses ist es, Ihnen zu zeigen, wie Spring
Boot in
einer End-to-End-Anwendung mit
einer ähnlichen Funktionalität wie
ein Microservice funktioniert einer End-to-End-Anwendung mit . Und hoffentlich
gibt dir das den kraftvollen Start deiner Reise, ein Frühling mit dem Meister
zu werden. Die einzigen Voraussetzungen für
diesen Kurs sind die Installation von
Intelligent Idea,
grundlegendes Java-Wissen und natürlich der starke Wunsch, neue Technologien
zu erlernen. Lassen Sie uns damit zur ersten Vorlesung
dieses Kurses
übergehen .
2. Warum SpringBoot?: Hallo zusammen, Willkommen zurück. Bevor wir uns also mit dem eigentlichen Code
befassen, nehmen
wir uns einen Moment Zeit
und verstehen warum wir das
Spring Boot-Framework lernen müssen. Genau hier sind wir
auf der offiziellen Website von Spring Width. Und wenn wir auf die Übersicht klicken, sehen
wir eine Reihe
von Vorteilen dieses Frameworks, die von der Branche
tatsächlich validiert wurden. Ich meine, sie werden
direkt hier auf der Website hinzugefügt. Aber die Beliebtheit
dieses Frameworks sagt
tatsächlich etwas darüber aus, ob
diese Vorteile tatsächlich
wahr sind oder nicht, oder? Also zuallererst über die Popularität, oder? Der Grund, warum es so beliebt ist, ist, dass
es sehr flexibel und es Ihnen ermöglicht, Apps mit
Produktionsrate sehr schnell zu erstellen. Wir werden
in diesem Kurs näher darauf eingehen, dass Frühling wirklich
einfach zu konfigurieren ist, sei es mithilfe von Anmerkungen
oder Konfigurationsdateien. Und es ist auch wichtig, die
Anwendungslandschaft zu
erwähnen, in der Spring Boot verwendet werden kann. Wir können es verwenden, um Microservices zu
erstellen ,
was dem heutigen neuen Trend ähnelt. So ziemlich jedes große Unternehmen hat diese
Microservice-Architektur in einem Teil seiner
Infrastruktur. Und Spring Boot bietet tatsächlich volle Unterstützung
für diesen Mosley. Wenn Sie die Spring Cloud und
die Cloud-Funktionen verwenden , die
Spring Cloud tatsächlich bietet, ähm, aber abgesehen davon können
Sie auch
reaktive Anwendungen
und ereignisgesteuerte Anwendungen erstellen . Es lässt sich also in so
ziemlich all die neuen Dinge integrieren
, die da draußen vor sich gehen. Mit anderen Worten, wenn Sie
wissen, wie Spring funktioniert, haben
Sie in dieser
Software-Engineering-Welt bis heute
einen Vorteil . Es gibt also eine Reihe von
Clips und Dokumentationen im
Internet, denen
Sie tatsächlich folgen können wenn Sie einen Überblick sehen möchten, oder Palm Springs funktioniert tatsächlich, viele Leute benutzen es
tatsächlich. Es gibt also jede Menge
Dokumentation im Internet. Und die Hauptaufgabe
dieses Kurses besteht darin,
Ihnen zu ermöglichen , Springboard
wirklich schnell zu benutzen. Wir werden uns also nicht mit all
den kleinen
Details von Springboard befassen . Wir fangen einfach sofort
an und beginnen mit
den Hauptfunktionen
von Springfield, oder? Ich gehe davon aus
, dass Sie
keine objektorientierte
Programmierung haben können und wie die Dinge in diesem Bereich funktionieren. Ich bin in Klassen, Interfaces, Methoden und solchen Dingen tätig. Also grundlegende Java-Kenntnisse. Und dann werden wir
mit den Funktionen des
Spring Boot Frameworks darauf
aufbauen .
3. Erstelle deine erste Spring-Boot: Also genug geredet. Lass uns etwas Code sehen, oder? Wenn Sie Ihre
erste Spring Boot-Anwendung erstellen möchten, haben
wir zwei Möglichkeiten. Die erste besteht darin, diese
Spring Initializer-Website zu verwenden, die Sie beim
Start Spring dot io zugreifen können. Und auf dieser Website können Sie eine vorkonfigurierte
Spring Boot-Anwendung
erstellen. Sie müssen sich nur umklicken, Ihr Projekt, Ihre Sprache,
Ihre Spring Boot-Version
auswählen und Ihren
Projektnamen, Artefaktgruppe
und solche Dinge,
einschließlich der Java-Version, vervollständigen und solche Dinge, . Und wenn Sie auf Generieren klicken, werden
Sie sehen,
dass der Browser ein Archiv
mit dem Projekt in einem intelligenten Ideenprojekt
herunterlädt , das
eine einfache Hello
World-Anwendung
enthält mit vorkonfiguriertem Sprungbrett. Dies ist natürlich der einfache Weg, aber wir werden
diesen Weg nicht einschlagen. Stattdessen beginnen
wir einem sauberen, intelligenten
Ideenprojekt und
fügen hinzu, was in Bezug
auf Spring-Abhängigkeiten erforderlich ist , um zu
sehen, wie es tatsächlich funktioniert. Also genau hier habe ich die intelligente Idee,
Community Edition. Ich werde
auf Neues Projekt klicken. Ich sage
Spring Boot Course. Ich werde Java als eine größere
Sprache als
Built-System wählen . Ich werde Java 17 verwenden. Und genau hier sage
ich Java Dot,
Spring, Spring Dot Course. Ich möchte auf Erstellen klicken
und wir
warten, bis Gradle aktualisiert wird, um alle
anfänglichen Abhängigkeiten herunterzuladen. Und das ist unser erstes Projekt. Jetzt gehen wir
zurück ins Internet und suchen nach Spring
Boot Starter Web. Maven, Central. Central ist natürlich
das Haupt-Repository für JVM-basierte Abhängigkeiten nach denen
wir suchen werden.
Diese Abhängigkeit heißt Spring Boot Starter Web. Diese ist
eine Art schlanke Abhängigkeit , die
so ziemlich alles beinhaltet, was wir benötigen, um eine sehr einfache
Spring Boot-Anwendung zu erstellen. Wir klicken
auf die neueste Version und wählen Gradle aus. Und wir werden das direkt in
unsere Gradle-Build-Datei
kopieren ,
den Abschnitt Abhängigkeiten. Ich füge es hier ein
und klicke dann auf „Mehr aktualisieren“. Und dann können wir sehen, dass es ordnungsgemäß heruntergeladen
wurde. Jetzt gehe ich zurück
zur Hauptklasse und genau hier auf Klassenebene und gehe zur Anwendung
Annotated with Spring
Boot über. Diese Rotation
kommt natürlich von dem Spring
Boot-Framework, das
den Einstiegspunkt für unsere
Spring Boot-Anwendung identifiziert . Und im Hauptteil
der Hauptklasse sagen
wir Spring
Application Dot Run. Und genau hier
werden wir
das Hauptobjekt der Punktklasse bereitstellen . Das ist also ein, das
ist der Bezeichner für die Hauptklasse, in der sich die Quelle mit
Annotation befindet. Dann
geben wir die Argumente an , die für die Hauptmethode angegeben
wurden. Was diese Zeile also tatsächlich
macht, ist zu beginnen, das eigentliche Framework ist im Grunde
eine blockierende Anweisung. Die Anwendung, der Prozess, der
JVM-Prozess wird also erst beendet, wenn die Anwendung
beendet wird oder bis sie beendet wird, der Prozess auf irgendeine
Weise beendet wird, oder? Jede Spring-Anwendung, ich meine, jeder Webserver
sollte eigentlich eine lange Laufzeit haben,
da er kontinuierlich
Verbindungen von HTTP-Clients
akzeptieren sollte . Wenn wir also auf Ausführen klicken, sehen
wir in
den Protokollen diese Ausgabe. Sie können sich also sowohl diesen schönen
Kunstspruch Frühling
als auch die Frühlingsversion ansehen . Und auf den Protokollen
können wir sehen, dass wir
hier die Protokolle vom
Tomcat-Webserver bekommen haben . Wir können den Port sehen, auf dem
die Anwendung ausgeführt wird, und wir können sehen, dass sie erfolgreich
gestartet wurde. Mit anderen Worten,
Tomcat ist im Grunde ein Webserver, der mit Spring Boot
geliefert wird. Sie können
es also auch unabhängig installieren, oder? Es wurde von der
Apache-Community entwickelt und ist im Grunde ein
klassischer Webserver, akzeptiert
nur Verbindungen, folgt dem HTTP-Protokoll
und all dem Zeug. der Hauptgrund, warum es in das Framework
eingebettet wurde Ich glaube, der Hauptgrund, warum es in das Framework
eingebettet wurde, ist, dass
es sehr leicht ist. Es verbraucht also nicht zu viel Speicher und zu
viel, zu viele Ressourcen. Und wahrscheinlich war dies der
Grund, warum es
als Teil des
Springboard-Frameworks ausgewählt wurde . Ich glaube, wir können es auch
ändern, wenn Sie möchten, mit Apache oder Caterer oder
anderen Webservern. So funktioniert es in einer
Standardversion, oder? Richtig, so funktioniert also unsere
erste Spring
Boot-Anwendung . Derzeit
macht die Anwendung nichts, sie akzeptiert nur
Verbindungen auf ADHS. Aber wenn wir in unseren
Browser gehen und localhost,
local, solicit, local host ADHD sagen local, solicit, local host ADHD und wir einfach darauf klicken. Wir können sehen, dass wir
nichts haben. dieser Fehler kommt tatsächlich Ich glaube, dieser Fehler kommt tatsächlich
von Spring Boot oder von Tomcat, weil es
einige Pfade finden muss , um die
Anfrage zuzuordnen, und in der Standardeinstellung hat
Patty
nichts, dem sie zuordnen kann. Derzeit läuft unsere Anwendung also
einfach und wir haben keine Aktion
angegeben, die bei einer bestimmten
Interaktion ausgeführt
werden soll, oder? Das ist also derzeit
der Staat, oder? Wir haben nur eine Anwendung
, die nichts tut. Wie teilen wir dieser
Verpflichtung mit, dass sie
eine bestimmte Aktion ausführen muss , wenn die Kunden auf eine bestimmte Weise
mit ihr interagieren? Aus diesem Grund erstellen
wir eine Klasse, die Controller genannt wird,
einen Rest-Controller. Und wir werden diese Klasse in
ein spezielles Paket namens
Controller
packen , oder? Habe gerade ein Paket erstellt
und dann rufe
ich diesen Benutzercontroller auf. Bei einer Spring
Boot-Anwendung ist
ein Controller also der
erste Einstiegspunkt für eine Anfrage in
der Anwendung. Wenn die Clients also
eine Anfrage stellen , die die
Anwendung aufrufen muss, wird
normalerweise zuerst
ein Controller aufgerufen. Basierend auf der Logik, die den Controller
definiert, wird
die Anforderung dann in anderen Komponenten weitergegeben, wie wir
in diesem Kurs weiter sehen werden. Um eine Vorstellung davon zu bekommen,
wie ein Controller funktioniert, erstellen
wir
hier eine Methode namens public void, eigentlich public string get user. Diese Methode ist eine sehr
einfache klassische Methode. Es gibt einfach so etwas zurück, wie Benutzer John Doe nur eine
Zeichenfolge zurückgibt. Und sehr wichtig, diese
Methode wird hier
mit get mapping annotiert ,
gefolgt von getUser. Wir können jede Art von
Zeichenfolge haben , die eigentlich mit
einem Schrägstrich beginnen
sollte , weil sie eine pfadähnliche Struktur
haben muss . Diese Anmerkung
erstellt also
tatsächlich einen Pfad oder eine Route
in unserer Anwendung. Also, wenn ein Client, entweder ein Browser
oder ein beliebiger HTTP-Client , diesen Pfad aufruft. Diese Methode wird
direkt in unserer
Anwendung aufgerufen , oder? So funktioniert es also
tatsächlich. Lassen Sie uns nun
unsere Anwendung erneut ausführen damit diese
Änderungen wirksam werden. Und wir werden in diesem Fall die
Eingabetaste drücken, oder? Also, wie Sie hier sehen können, haben
wir diese
Zeichenfolge wieder, oder? Wenn wir nun auf Inspect klicken,
um die eigentliche Anfrage zu sehen, wenn wir auf der
Registerkarte Netzwerk auf So klicken und auf Aktualisieren klicken, können
wir sehen, dass der
Browser diese
HTTP-Get-Anfrage tatsächlich auf dieser URL
gestartet hat, localhost 80, 80 getUser, der Standardbrowser, wenn Sie eine Seite aktualisieren, stellt
er diese Get-Anforderung. Tatsächlich macht es, tatsächlich stellt es zunächst
diese Get-Anfrage. Und dann kann es
etwas JavaScript wieder herunterladen, das dann
vom Browser ausgeführt wird
, der dann
andere Anfragen zulassen kann und so weiter. In der Praxis
ist das also noch komplexer. Aber in diesem sehr
einfachen Anwendungsfall hat
der Browser gerade eine Get-Anfrage
gestartet, der Browser gerade eine Get-Anfrage
gestartet bei der tatsächlich unsere API aufgerufen wurde, die dieses
String-Objekt zurückgibt. So erhalten Sie
Daten von unserer API zurück. Wenn wir nun einfach hier klicken,
wenn wir hier auf die Antwort klicken, können
wir unsere Zeichenketten-Payload sehen. Und wenn wir hier
wieder auf die Header klicken, können
wir sehen, dass wir in
den Antwort-Headern auch diese Informationen hier erhalten
haben. Diese Header wurden tatsächlich vom Framework
hinzugefügt. Also haben wir, wir haben
nichts mit diesen Daten gemacht,
um hier zu erscheinen. Das sind die Anforderungsheader. Und übrigens, das ist nur eine Art der
Informationseingabe mit Schlüsselwerten, oder? Und genau das hat der Browser
Chrome
auf Anfrage zu
unserer Anwendung hinzugefügt . Jetzt können wir diese Header natürlich
ändern, indem wir die Spring
Boot-Mechanismen verwenden. Es ist jedoch sehr
wichtig zu beachten dass ihre Struktur, der Name, der Schlüsselname der Header und die Werte tatsächlich durch das HTTP-Protokoll
reguliert werden . Also das HTTP-Protokoll,
und übrigens
HTTP, steht für Hypertext
Transfer Protocol. Hypertext
bezieht sich eigentlich auf HTML, aber es handelt sich eher um eine veraltete
Benennung, da Sie
Binärdaten
tatsächlich über HTTP übertragen können . HDP hat also eine Reihe von Regeln. Jedes Protokoll
hat grundsätzlich eine Reihe von Regeln, die
irgendeine Art von Aktion regeln. In diesem Fall regelt HTTP die Kommunikation zwischen
dem Client und dem Server. Sie können also im Grunde
alle möglichen Details
darüber sehen , wie Header weitergegeben werden
sollen. Deine Proxys funktionieren tatsächlich. Mit anderen Worten, wenn ein Client und der Server
dieselben Regeln einhalten, können
sie mithilfe
der Regeln des
HTTP-Protokolls, auch im Zwischenspeicher,
korrekt kommunizieren . Der Umfang dieses
Kurses besteht jedoch nicht darin,
tief in das HTTP-Protokoll einzusteigen tief in das HTTP-Protokoll einzusteigen da es sehr, sehr komplex ist. Und
in diesem speziellen Thema gibt es viele Details, vielleicht für einen anderen
Kurs in der Zukunft. Aber vorerst beschränken wir uns
auf diese sehr grundlegende Verwendung
dieses Protokolls. Kurz zusammengefasst Wenn Sie eine
GET-Anfrage an einen Webserver stellen, fordern
Sie im Grunde Daten von diesem an. Wenn du
eine Post-Anfrage
stellst, übermittelst du einige
Daten an diesen Server. In diesem Fall
definieren wir ein gutes Mapping, was bedeutet, dass wir die API,
den Webserver,
anweisen,
GET-Anfragen auf diesem Pfad zuzulassen. Wir haben auch Post Mapping, was bedeutet, dass wir
den Webserver anweisen,
Daten von externen Clients
auf einem anderen Pfad zu empfangen , z. B. von
Edges . Und das werden
wir als Nächstes tun. In der nächsten Vorlesung
werden wir diesen Benutzercontroller weiter entwickeln,
um
diese Interaktion
mit externen Clients noch genauer zu untersuchen .
4. Wie können wir POST-Anfragen verwenden?: Wir haben also gesehen, wie
wir im Grunde einige Daten von unserer API
zurückbekommen können . Lassen Sie uns nun diesen Eingabe- und
Ausgabe-Mechanismus von Spring Boot lernen und damit
spielen Ausgabe-Mechanismus von Spring Boot ist der Controller
und das Mapping-Setup. Eine wirklich nette
Sache beim Testen mit einem Browser ist, wenn Sie HTML
von Ihrer Anwendung zurückgegeben
haben, da der Browser den HTML-Code
tatsächlich rendert. Wenn wir etwas
wie HTML geschlossen sagen und dann Text sagen, natürlich nicht, das
ist nur zu Testzwecken, nur um herumzuspielen und Ihnen zu zeigen dass der Browser das HTML
rendert, nur irgendwelche Texte hier. Wenn wir das also erneut ausführen
und die Seite neu laden, können
wir sehen, dass der Text
im Grunde
vom Browser gerendert wird . Dementsprechend geben wir HTML zurück, aber es wird
automatisch vom Browser gerendert. Wenn Sie nun einen Webserver
haben, übertragen Sie normalerweise Daten in einem Format
wie JSON oder Proto Buff. Und Sie
benötigen diese Art
der Interaktion mit dem Browser nicht wirklich , aber es könnte nützlich sein, wenn Sie
einen solchen Anwendungsfall haben, indem einfach HTML zurückgeben. Jetzt verwenden
wir anstelle des Browsers einen
dedizierten HTTP-Client
, der Postmen genannt wird. Dies ist im Grunde
ein Tool dieser schönen Benutzeroberfläche, die
es uns ermöglicht, eine API mit verschiedenen
Arten von Anfragen,
Typen und verschiedenen
Arten von Payloads zu interagieren oder zu
testen ,
die auf sehr
einfache Weise konfigurieren. Wenn Sie also einen Webservice entwerfen, spielen Sie
normalerweise mit
dieser Art von Tool um zu sehen, wie es funktioniert, und
um verschiedene Dinge zu testen. Also genau dieselbe
Anfrage, die wir Browser aus
gestellt haben, können wir von Postman stellen,
indem wir localhost 80,
80 gefolgt von Git-Benutzer sagen . Und wenn Sie auf Senden klicken, können
Sie sehen, dass
der HTML-Code ausgeführt und zurückgegeben wird, oder? Sie können auch auf verschiedene Weise formatieren und
antworten. Nehmen
wir nun an, wir möchten
eine Zeichenfolge von unserer API zurückgeben . Diese Zeichenfolge sollte eigentlich die JSON-Repräsentation
für unser Benutzerobjekt sein. Definieren wir also zunächst ein
Modell in unserer Anwendung. Ich werde ein neues
Paket namens Model erstellen. Genau hier sage
ich Benutzermodell. Dies ist die Klasse für unseren Benutzer. Und darin
werden wir
private Zeichenfolge,
FirstName und LastName haben . Und nehmen wir an, wir müssen auch ganzen Zahlen eine
Mitgliedschaft von d
geben, oder? Was ist eine Art
Premium-Platin-Benutzer oder Dinge wie ein einzelner
Serverlevel in, in unserer Anwendung, nur
um Dinge zu testen. Also werden wir
zunächst einen Konstruktor hinzufügen . Wir werden auch
Getter und Setter für
alle Felder hinzufügen , oder? Intelligente Ideen helfen uns dabei,
das wirklich, sehr gut zu machen. Der einzige Controller, bei dem
wir ein Benutzermodell
zurückgeben werden, oder? Wir müssen diese Klasse importieren. Und genau hier, wenn
wir das zurückgeben, müssen
wir New User Model
von John Doe und 1234 sagen, okay? Natürlich spielen wir mit
Klassen in der realen Welt, wir spielen mit tatsächlichen
Objektmodellen. Aus diesem Grund
müssen wir auch damit experimentieren. Wenn ich also bei der Antwort
auf Senden klicke, erhalten
wir diesen JSON zurück. Wie Sie sehen können, hat
das Framework unser Objekt tatsächlich in ein angrenzendes,
im Grunde
unser Objekt,
ein Modell umgewandelt in ein angrenzendes,
im Grunde
unser Objekt, , das in ein
benachbartes Format serialisiert wurde, oder? Und das wurde
automatisch durch das
Spring Would Framework gemacht . Wenn wir nun
zum Controller zurückkehren, können
wir eine Situation haben,
in der wir verschiedene Benutzer
anhand einer ID
zurückgeben müssen , oder? Nehmen
wir also zum Beispiel an, wir haben hier eine Map, private Map von String
zu UserModel, oder? Nennen Sie diese Benutzerkarte new HashMap. Ordnung, und nehmen wir an, wir fügen hier
einen kleinen Controller hinzu, den öffentlichen Benutzercontroller. Und auf dieser Karte
haben wir zwei Benutzer. Nehmen wir an, nehmen wir an, auf
der Benutzerkarte, die
wir hinzufügen, setzen wir
zuerst den Benutzer John
, der dieses, dieses
Modell hat, genau hier. Und dann haben wir z.B. auch
den Benutzer Jane eingegeben und das ist Jane Doe mit
unterschiedlicher Mitgliedschaft von d. Also im Grunde haben wir diese
beiden Benutzer in dieser Map. Und wenn wir
den Benutzer von unserer API abrufen wollen, wollen
wir ihn
je nach Namen bekommen, oder? Und das bedeutet, dass der Name auf der Anfrage angegeben werden
muss. Also
sollte der Client
hier tatsächlich einen Namen hinzufügen , der eine Variable sein
kann. Und dieser sollte Nutzername
heißen, oder? So
spezifizierst du bei uns, auf einem Pfad, die Tatsache, dass du eine
Variable daraus extrahieren
möchtest. Also genau hier beim Benutzernamen müssen
wir ihn auch zu den Parametern
dieser Methode hinzufügen
, indem wir die Pfadvariablen-Annotation verwenden. Hier müssen wir
den Typ der Variablen
und denselben genauen Namen angeben , den
wir dem Pfad hinzugefügt haben, oder? Wenn Sie also eine Anfrage stellen, wenn Sie GetUser John
direkt vom Browser
oder vom Postman aus sagen , wird
der John-Wert für diese
Benutzernamenvariable weitergegeben. Und wir können es wie
jede andere Variable verwenden. In diesem Fall
können wir also sagen, user map dot get of username, oder? Lassen Sie uns das wiederholen. Und tatsächlich klicke ich
auch auf Debug und setze hier
einen Breakpoint, um zu sehen, dass diese Variable richtig
gefüllt wird. Also wurde die Anwendung gestartet. Ich gehe zurück
zu Postman und sage
getUser dot John und drücke Send und rice.
Wir können sagen, dass die
Username-Variable den gültigen John hat, und sie wird einfach
in die Map gehen und
den aktuellen zurückgeben Objekt, richtig? Also klicke ich auf
Weiter und zurück. Wir können sehen, dass wir dasselbe
bekommen. Wenn wir nun Chain verwenden, können
wir sehen, dass die
Variablen so sind, dass wir
richtig gespielt haben und F9 gedrückt haben, und wir können sehen, dass wir die anderen Objekte
bekommen. diese Weise stellt
ihr der
Anwendung im Grunde
einige Daten auf dem Pfad zur Verfügung , auf dem Anforderungspfad, sodass ihr verschiedene
Arten von Informationen auswählen
könnt. Dies kann eine Benutzer-ID sein,
es kann eine E-Mail sein, es kann alles Mögliche sein,
alles, was in Ihrer Bewerbung tatsächlich
Sinn macht. Lassen Sie uns nun die Gänge wechseln und
mit einer Pause
bei Anfragen spielen mit einer Pause
bei Anfragen . Auf diese Weise kann ein
Client einer Anwendung
Daten zur Verfügung stellen . Für die Spring Boot-Anwendung wollen
wir einen Benutzer erstellen, oder? Wir sagen „Benutzer erstellen“. Wenn wir einen Benutzer erstellen, möchten
wir nichts zurück
haben, aber Sie möchten
diesen, diesen Vertrag, aktualisieren. Zweitens sagen wir
hier, Post Mapping, oder? Weil wir einige Daten
für unsere Websites
bereitstellen wollen ,
sollten in diesen Daten die
Benutzerdetails stehen , oder? Der Vorname, der
Nachname usw. Also sagen wir Benutzer
hinzufügen, und das war's. Und genau hier zu den
Parametern müssen wir so etwas wie
Antwort, Anforderungstext
bereitstellen. Diese Anmerkung
teilt Spring Boot , dass es einige Daten
aus dem Anforderungstext
extrahieren und
in ein Objekt einfügen muss . Dieses Objekt sollte z. B. das Benutzermodell sein, oder? Das bedeutet also, dass wir auf der
Benutzerkarte „put und „user
dot get firstName“
gefolgt vom eigentlichen Objekt sagen können . Ja, ich muss hier
nichts zurückgeben, oder? Weil die Methode
keinen Rückgabetyp hat. Mit anderen Worten, ich extrahiere das
Benutzermodell aus der Anfrage und lege
es auf diesen User Mapper. Lass uns das machen. Und das erste Mal werde ich
versuchen, mit einem Debugger zu überprüfen ,
ob das Benutzerobjekt ordnungsgemäß gefüllt
ist. Ja, also die
Anwendung ist gestartet. Also werde ich
eine Post-Anfrage erstellen. Ich werde hier in Postman einen neuen
Tab erstellen. Und ich werde
hier den Beitrag auswählen, richtig. Ich sage Benutzer hinzufügen. Und genau hier am Hauptteil sage
ich deine Zeile, und ich wähle hier
JSON-Anwendungsjson aus. Ich muss nebenstehend angeben, was die tatsächlichen
Informationen für den Benutzer
enthält. Ich möchte nicht erstellen
, dass Jason
dem Schema dieses Objekts
oder des Benutzermodellobjekts folgt dem Schema dieses Objekts
oder des , oder? Sie sollten also
den Vornamen, Nachnamen und die
Mitglieds-ID angeben. Ich kann sie einfach
von der anderen Registerkarte abrufen. Und natürlich
werde ich
sie mit verschiedenen Werten füllen , z. B. Daniel, Craig. Und das sollte ein Wert
wie jede Ganzzahl sein, die wir wollen. Wenn wir auf Senden klicken, können
wir sehen, dass ein Fehler
namens interner Serverfehler angezeigt wird
oder dass etwas passiert ist. Mal sehen, was passiert ist. Wenn wir also direkt
hier in die Protokolle gehen, können
wir sehen, dass keine
Instanz des Benutzermodells erstellt werden kann , es gibt
keine Ersteller wie den
Standardkonstruktor. Das ist also ein Pfeil, den Sie
wahrscheinlich tatsächlich ziemlich
oft sehen können , wenn Sie mit Objekten spielen,
mit Serialisierung, Deserialisierung, solchen
Dingen
, der
uns tatsächlich sagt, wenn Sie stelle diesen Json zur Verfügung, oder? Und der Frühling mit dem
empfängt diesen Json, er versucht im Grunde, ein Benutzermodellobjekt zu
erstellen. Aber wenn er versucht,
dieses Benutzermodellobjekt zu erstellen, verwendet
es diesen
Konstruktor nicht, oder? Welches hat diese
drei Parameter. Stattdessen erwartet
es, einen Konstruktor
ohne Parameter zu haben , um einfach eine Instanz zu
erstellen. Und dann erwartet es,
die Setter-Methoden zu verwenden die Setter-Methoden zu all diese drei
Felder nacheinander
festzulegen. Das ist es, was das
Jackson-Zivilisationsframework tatsächlich erwartet, oder? Dies ist die Komponente
in Springboard, die sich mit Serialisierung
und Deserialisierung befasst. Mit anderen Worten, wir müssen hier
nur
einen Standardkonstruktor
ohne Parameter bereitstellen . Und es wird funktionieren, die
Anwendung erneut im Debug-Modus zu erstellen und erneut
auszuführen. Es hätte beginnen sollen. Okay? Gehen Sie nun zurück zu Postman
und klicken Sie auf Senden Dort heißt es, dass wir eine schlechte Anfrage
haben. Mal sehen, was der
Fehler ist, jetzt heißt es numerische
Wert des
JSON-Parse-Fehlers außerhalb des zulässigen Bereichs liegt, oder? Es sieht also so aus, als ob diese
Zahl, die wir
hier hinzufügen , außerhalb des
Integer-Bereichs liegt, also müssen wir hier nur eine
kleinere Zahl hinzufügen, oder? Wenn wir nun auf Senden klicken,
können wir sehen, dass es funktioniert. Wenn wir also auf
diesen Benutzerparameter klicken, können
wir sehen, dass er
mit den richtigen Werten gefüllt wird. Und wenn wir auf F9 klicken, um die Ausführung
fortzusetzen, sollte
der Wert in der Map
gespeichert werden. Wenn ich also den anderen Tab verwende,
um getUser for Daniel aufzurufen, können
wir sehen, dass wir die
richtige Antwort erhalten haben. So
fügen wir also tatsächlich Daten zu unserer API hinzu.
5. Standardantworten implementieren: Eine Sache, die ich auch über die
Funktionalität
dieser Controller erwähnen
wollte , ist , dass Sie normalerweise, wenn Sie mit Microservices
spielen, Lage sein müssen den richtigen Status für Ihre
Einführung für Ihr anfragen. In diesem Fall können wir sehen,
dass wir nur den Status 200
für alle Anfragen haben , die wir gestellt haben. Dies ist die Standardeinstellung, Status 100, okay? In HTTP bedeutet Protokoll, dass die Interaktion erfolgreich
abläuft und alles gut funktioniert hat. Jetzt können Sie auch nach
dem HTTP-Status suchen, der online ist, und das ist die vollständige Liste der Status, die in einem Protokoll erwähnt
werden, oder? Wenn Sie also z. B.
den Status 500-599 haben, sollte
das ein Serverfehler sein. Erfolgreiche Antworten sind 200-299. Und dieses Testament hat auch alle
möglichen Status. Wenn
Sie mit 201 antworten, bedeutet
dies, dass Sie
die Ressource erfolgreich erstellt haben. Alle Arten von
Interaktionsmodellen, die in Ihrer
Anwendung
passiert sind, oder? So gut gestaltet. Webserver, die Antworten und der Status Ihrer
Anwendung sollten
anhand dieses Statuscodes
die tatsächlichen
Ereignisse in Ihrer Anwendung widerspiegeln die tatsächlichen . Und im Frühjahr hätte ich
eine Möglichkeit, dies in
den Controllern zu tun , indem wir ein Objekt verwenden , das wir
bei jeder Methode zurückgeben müssen, das als Response-Entität bezeichnet wird. Und diese Antwortentität
ist ein generischer Typ. Wir können hier z. B. auch ein
HTTP-Status-Objekt hinzufügen und was das eigentlich
bedeutet, dass wir von dieser Methode
etwas wie return,
response, entity,
dot accepted, dot built zurückgeben können dass wir von dieser Methode
etwas wie return, response, entity,
dot accepted, Verantwortlichkeiten. Es folgt einem Builder-Muster. Und wenn wir hier akzeptiert sagen, bedeutet das, dass wir diesen
HTTP-Status akzeptiert hinzufügen, was 20.2 in der
Antwort ist, oder? Wir bauen dieses Objekt. Also im Grunde jetzt, wenn wir
die Anwendung ausführen und
einen neuen Benutzer erstellen. Also jetzt, wenn wir
wieder zu Postboten gehen und Benutzer hinzufügen sagen, und wir stellen hier einige Daten zur Verfügung. Wir klicken auf Senden. Wir können an
der Antwort sehen, dass wir auf Null
kommen, um sie zu akzeptieren, oder? Welches ist ein Statuscode
, den wir hier hinzufügen. Dies natürlich für
die beste Praxis Ihrer ,
Ihrer Bewerbung, oder? Jetzt kann dasselbe hier
und überall
in Ihrer Anwendung getan werden .
In jedem Controller sollten Sie diese Art von Interaktion
haben. Muss auch erwähnen, dass
der innere Controller auch andere
Arten von Methoden haben kann, oder? auch vom
HTTP-Protokoll verwaltet, z. B. wenn Sie nach HTTP-Methoden suchen, eigentlich nach dieser, können
Sie sehen, dass wir hier eine Reihe von
Methoden erhalten, oder? Bisher haben wir also die Methoden
GET und Post verwendet. Sie können aber auch
Head PUT, Delete,
Connect-Optionen, Trays, Patch haben , und das sind alles. ZB, wenn wir löschen
verwenden wollen, oder? Wenn wir einen Benutzer
löschen wollen, müssen
wir z. B. einfach hierher gehen, diese Methode
kopieren, sagen wir, Mapping löschen. Und genau hier müssen wir den Benutzer
identifizieren, z. B. müssen
wir Benutzer löschen sagen,
gefolgt von einem Benutzernamen, was wiederum ein
Pfadvariablenparameter ist, oder? Also können wir hier sagen, entfernen gefolgt vom Benutzernamen, was bedeutet, dass wir
den Benutzer einfach aus unserer Map entfernen. Und wenn wir die
Antwortentität zurückgeben, können
wir einfach
gelöscht oder Ernährung sagen falls es einen Status
ohne Inhalt gibt, kann er für
Löschvorgänge verwendet werden, oder? Wenn wir also
die Anwendung jetzt neu laden
und übrigens, wenn wir die Anwendung
neu starten, was die einzige Möglichkeit ist,
die Änderungen wirksam zu machen, die Map wieder leer, wird
die Map wieder leer,
sodass nur diese beiden Benutzer vom
Konstruktor hinzugefügt werden, oder? Wenn wir also einige Benutzer hinzufügen und dann die App beenden
und erneut starten, werden
die neuen Benutzer nicht in
der Map sein , wenn die obere neu gestartet
wird, oder? Weil es natürlich im Speicher
gespeichert ist. Also schauen wir mal, wir wollen der Benutzer Daniel zurück
ist, eigentlich jetzt, oder es
muss der Benutzer John sein, oder? Das ist also der Benutzer, und jetzt wollen wir löschen. Also wollen wir einen
neuen Tab erstellen und Löschen sagen. , ist dies die Methode zum
Löschen einer Anfrage genauer
zu sein, ist dies die Methode zum
Löschen einer Anfrage. Und ich sage Benutzer
löschen,
gefolgt von John, schreibe, lösche es. Es steht vorerst auf Null Inhalt, was bedeutet, dass der
löscht, was erfolgreich ist. Und dann klicke ich
erneut auf Senden , um den Benutzer John zu erhalten. Auch hier sehe ich, dass ich
nichts habe. Wir können das natürlich auch ein wenig
umgestalten, um etwas zu sagen, wenn die Benutzerzuordnung einen
Schlüsselbenutzernamen enthält, werde ich ihn direkt
zurückgeben. Andernfalls sage ich
, gib
eine Antwort-Entität zurück , die
nicht gefunden wurde, erstellt. Und hier muss
ich natürlich
eine Antwortentität des Benutzermodells zurückgeben . Und hier muss ich die
Antwortentität dieser Entität sagen. Und das sollte
eigentlich eine optionale,
optionale Alternative zu diesem sein. Mit anderen Worten, wenn ich den Benutzer in der Map
habe, gebe ich den tatsächlichen Benutzer zurück. Aber wenn ich es nicht tue, gebe
ich nicht gefunden zurück, was 404 ist, oder? Lassen Sie uns die
Verpflichtung noch einmal wiederholen, um zu sehen, dass diese Funktionalität
inaktiv ist, oder? Also werde ich
einen Benutzer John zurückholen. Ich kann sehen, dass ich es habe,
weil ich gerade die
Anwendung neu gestartet habe und die
Daten gefüllt wurden, geworfen. Der Konstruktor ist
tatsächlich auf der Karte. Jetzt möchte ich
einen Benutzer löschen, John, oder? Wenn ich den Benutzer John zurückbekomme, kann
ich sehen, dass ich 404
nicht gefunden habe und nicht 200. Okay. diese Weise
können wir natürlich den HTTP-Status
aktualisieren, um den richtigen Vorgang
widerzuspiegeln
, der in einer
anderen Anwendung stattgefunden hat. Ordnung, damit
haben wir gelernt, wie wir mit Controllern spielen
können, wie wir einige
Daten von SAP-Kunden, von Postman erhalten
können und
auch, wie wir die Daten ordnungsgemäß
zurückbekommen können. Lassen Sie uns nun die Gänge wechseln und
über Dienste im
Spring Boot-Framework sprechen .
6. Dienstleistungen im Spring-Boot erstellen: In Ordnung, willkommen
zurück. Bis jetzt arbeiten wir also mit
dem Rest-Controller. Wir haben gesehen, wie wir Informationen aus
unserer Spring Boot-Anwendung
als HTTP-Client hinzufügen und abrufen und auch
mit Postman spielen können, um Ihre Anfragen zu
starten. Jetzt werden wir mit
einer Strukturänderung gegenüber der
Anwendung fortfahren einer Strukturänderung gegenüber , da, wie
ich eingangs erwähnt habe, ein Rest-Controller der
Einstiegspunkt Ihrer Anwendung ist. So können Sie
festlegen, wie Sie
die Daten von Ihren
Kunden erhalten und wie Sie sie zurückgeben sollen. In der Regel
sollten diese Komponenten jedoch
die Interaktion innerhalb
Ihrer Anwendung in
anderen Strukturen weiterleiten die Interaktion innerhalb . Mit anderen Worten,
Sie sollten keine
Anwendungslogik hinzufügen oder von
Ihrem Risikocontroller aus keine Verbindung zu einer Datenbank herstellen. Sie sollten nur die
Daten in dem Modell abrufen, die Sie wollen, und dann eine
andere Komponente aufrufen, eine andere Klasse, in Ihre Logik ausgeführt
werden sollte, oder? Die erste Komponente dieser
Art, auf die wir uns jetzt einlassen werden,
wird Service genannt. Also werden wir hier
ein neues Paket namens Services erstellen . Es mag den Anschein haben, dass ich hier ein Paket für jede Klasse
erstelle, aber ich erstelle tatsächlich ein Paket für jede
Klassenkategorie. Denn wenn Sie Ihre Modelle hinzufügen
möchten, haben
Sie ein spezielles Paket für dieselben vier Controller, Dienste und andere Aspekte. In der Regel sollten Sie Ihren Code also auf
diese Weise
strukturieren , um ihn skalierbar zu
machen. Also werde ich
diesen Benutzerservice anrufen. Jetzt ist ein Dienst in Spring
Boot nur die Klasse, die mit der
Service-Annotation
annotiert ist. Und was diese Anmerkung
tatsächlich bewirkt, ist, dass Ihre Anwendung im
Dependency
Injection-Framework von Spring Boot gesehen werden kann , oder sie registriert Ihre
Klasse in diesem Setup. Mit anderen Worten, wenn wir auf diese
Oberfläche klicken, um zu sehen was dahinter steckt oder um die Implementierung zu
sehen. Wir können sehen, dass diese Notation im Grunde eine Schnittstelle ist
,
da Sie auf diese Weise
Anmerkungen in Java erstellen können. Und es hat auch diese
Komponentenannotation, die die Root-Annotation
in Spring Boot und
auch anderen ist . Nun, die einzige funktionale Rolle
dieser Anmerkung ist die
, die ich
zuvor erwähnt habe, oder? Registriert es
die Klasse im Dependency
Injection Framework. Und es hat auch eine
informative Rolle, oder? Es sagt Ihnen, dass von dieser Klasse
erwartet wird , dass sie eine
Art Rechenlogik ausführt, indem sie
entweder externe Dienste aufruft
oder einige Validierungen oder irgendeine Art von Logik , die etwas
mit dem Benutzer zu tun hat Verwaltung. Also werden wir
diesen Teil mit
dem User Map Storage in
diesen Benutzerdienst und
auch diese spezielle
Initialisierung verschieben dem User Map Storage in
diesen Benutzerdienst und . Wir werden es gleich hier in
den User Service
Controller legen . Und natürlich werden wir momentan
keinen Zugriff auf diese Map
im Controller haben. Wir müssen
einige Methoden erstellen , die denen entsprechen , die wir
im Rest-Controller haben. Um diese Trennung zu ermöglichen, sagen
wir public,
public, userModel, getUser. Und wir werden
hier den Benutzernamen haben, oder? Also werden wir noch
Username Dot sagen. Das ist also eine reguläre Klasse, nichts
Spezifisches mit dem
Rest-Controller zu tun hat, sodass wir keine Antwortentitäten
von Diensten zurückgeben
müssen . Dies ist eine Klasse,
die eine Verbindung zu der Art und Weise herstellt, wie wir Daten auf
dem HTTP-Client zurückerhalten. Er hat also einen moralischen Rahmen,
auf dem alles in Ordnung ist. Aber in einem Dienst oder
in einem generischen In, in jeder Komponentenklasse, können
wir jede Art von
einfachem Java-Code hinzufügen. Das ist also getUser. Gleiche gilt für AD-Benutzer. Wir brauchen
hier ein Benutzermodell. Und genau hier, wenn
du Put of user sagst, und hier können wir leer
oder so etwas sagen. Natürlich müssen wir hier user.name,
firstName und dann user
sagen . Und wir werden
nichts zurückgeben. Und wir haben auch Benutzer
löschen, oder? Also
sagen wir, lösche einen
Benutzer nach Benutzername, Vorname. Eigentlich sagen wir
den Benutzernamen entfernen. Die Hauptfrage wäre nun, wir verschieben diese Logik in diese
Benutzerservice-Klasse, oder? Wie arbeiten wir mit dieser
Klasse von unserem Controller aus? Weil wir
auf der Instanz
den Benutzerdienst in
unserem Controller haben müssen , oder? Um
genau die gleichen Dinge tun zu können, oder? Hinzufügen, Löschen oder Benutzer. Wir machen
das also zunächst,
ich meine, es gibt
tatsächlich zwei Möglichkeiten. Eine, die nicht empfohlen wird,
in einer, die empfohlen wird. Die erste
wäre also,
eine Instanz des
Benutzerdienstes zu erstellen , oder? Entweder auf oberster Ebene rechts,
als privates Feld oder auf
dem Konstruktor schreiben. Auf diese Weise
erstellen wir diese Instanz manuell, oder? Solange der
Controller also geht, hat
er eine Instanz. Dies ist eine Möglichkeit
, wie es funktionieren würde. Aber trotzdem, wenn wir brauchen, ob der Benutzerservice in
Zukunft
einen Konstruktor hat , sagen wir mal, richtig. Ein öffentlicher Benutzerservice, oder? Und genau hier
braucht es eine Art andere Klasse, die
nur die Benutzerverwaltung betrifft, also hat sie nichts mit Controllern
zu tun. Dann müssen wir diesen
Konstruktor genau hier aktualisieren, diesen Aufruf genau hier, richtig, um diese Abhängigkeit,
diesen Validierungsdienst,
z. B.
direkt hier
auf diesem Konstrukt, abrufen zu können Validierungsdienst,
z. B. , dieses Problem wird
immer größer, oder? Wenn mehr Parameter hinzugefügt werden , hätten wir keine Entkopplung mehr zwischen
Benutzerverarbeitungslogik und Eingabeausgabeklassen, oder? Wir mischen also die Bedenken wenn wir diese Art von
Ansatz hier verfolgen. Stattdessen wird empfohlen
, im Frühjahr
generisch mit Instanzen zu spielen , das Dependency
Injection Setup von Spring zu verwenden. Spring with hat also dieses sehr interessante
Muster, das auch in externen
Frameworks wie Juice zu
finden ist, z. B. Google Juice, was als Dependency Injection bezeichnet
wird. Und im Wesentlichen ist ein Dependency
Injection Framework nur eine Möglichkeit Instanzen in unserer Anwendung entkoppelt abzurufen, ohne das neue Schlüsselwort zu
verwenden. Denn jedes Mal, wenn Sie das neue Schlüsselwort
verwenden, stoßen
Sie auf dieses Problem,
bei dem Sie, wenn
Sie die Klasse benötigen, auch all
ihre Abhängigkeiten angeben müssen, oder? Und das ist problematisch, geht zu diesem Thema über die
Mischung von Problem und Dependency Injection
Framework, sodass Sie dieses Problem
auf sehr saubere Weise
angehen können. Mit anderen Worten, was wir
hier tun müssen, ist zu sagen, im Grunde
einen
variablen Benutzerdienst auf privater Ebene zu erstellen variablen Benutzerdienst und ihn hier zu diesem
Konstruktor hinzuzufügen. Und dann können wir sagen, dass dieser
Punktdienst gleich Dienst ist, oder wir können diesen umbenennen. Es weiß tatsächlich, dass wir hier über
verschiedene Variablen sprechen. Die Scope-Ebene eins und
die Klassenstufe eins. Aber was macht das, wenn der Benutzercontroller
instanziiert wird, oder? Also wenn der, wenn das Framework die Benutzercontroller-Klasse
instanziiert, bemerkt, dass dieser Benutzercontroller
ein Benutzerservice-Objekt benötigt und versucht,
eine Instanz der
Benutzerservice-Klasse zu erstellen . Und das passiert
hinter den Kulissen. Darüber brauchst du
dir keine Sorgen zu machen. Und es besagt, dass der
Benutzerdienst
keinen Konstruktorparameter hat
und einfach
die Instanz erstellt , wie Sie es
tun würden, das neue Schlüsselwort. Wenn der Benutzerdienst Parameter
im Konstruktor,
dem Framework,
hatte, werden wir stattdessen Parameter
im Konstruktor,
dem Framework,
hatte weitersuchen
und versuchen, auch für diese
Parameter
eine Instanz zu erstellen . Und so wird es
rekursiv gehen, oder? Bis es gelingt, alle Instanzen zu erstellen
, die gelöst werden müssen. Wenn es gelingt, eine Instanz zu
erstellen, es einfach bei
der Kompilierung fehl. Das ist sehr nützlich
, weil Sie das sofort sehen können. Schauen wir uns das mal in Aktion an. Also ich erhalte diesen
Benutzerservice direkt hier. Und natürlich kann ich jetzt den
Contains-Schlüssel oder Metal
verwenden , da er intern für
den Benutzerservice ist. Stattdessen sage ich einfach
Antwortentität des Benutzerdienstes,
eigentlich Service Dot
Get Users per Nutzername. Und in diesem Fall muss
ich sicherstellen, dass getUser Null oder
etwas Ähnliches zurückgibt. Wenn ich den
Schlüssel für Benutzer hinzufügen nicht habe, muss
ich nur den Service Dot Add User
des Benutzermodells suchen , das ich aus den Parametern
erhalten habe. Und das Gleiche habe ich für die Löschung
zu sagen. Löschen Sie also den Benutzer anhand des Benutzernamens. Also jetzt werden wir unsere Anwendung tatsächlich
ausführen, lassen Sie uns sicherstellen, dass
sie zuerst kompiliert wird, oder? Also werden wir uns das Debuggen
anhören, um
ein bisschen zu sehen , wie dieser Controller instanziiert
wird, oder? Wie Sie sehen können, hat der
Benutzerdienst eine Instanz. Das Framework hat
diese Benutzerservice-Instanz erstellt . Für uns ist dies das Dependency
Injection Framework , das diese
Instanz automatisch erstellt hat. Und es ist sehr praktisch, oder? Sie müssen dies nur
im Konstruktor angeben , und das war's. Sie müssen sich keine Gedanken
darüber machen , wie diese
Instanz erstellt wird. Lassen Sie uns es natürlich ausführen, um zu
sehen, dass es immer noch funktioniert Die Funktionalität sollte dieselbe
sein, oder? Also verstehe ich den Benutzer John. Ich sehe, dass es funktioniert. Ich füge einen Benutzer hinzu, Daniel Craig. Es ging auf Null, um es zu akzeptieren. Ich bitte für den Benutzer Daniel. Ich kriege es zurück. Ich lösche den Benutzer
John. Es hat geklappt. Und wenn ich dann noch einmal
nach John frage, sieht
es so aus, als
hätte ich den Benutzer John nicht. Mal sehen, was passiert. Wenn Sie 500 haben, ist normalerweise etwas schief gelaufen, entweder
eine Nullzeiger-Ausnahme oder etwas Ähnliches. Ja, eigentlich haben wir
diese NullPointerException. Im getUser können
wir also sehen, dass wir
optional ausschalten. Dieser wird tatsächlich ausgelöst, wenn
Sie hier einen Nullwert haben. Also müssen wir nullable absagen. Wenn Sie also
optional oder nullable sagen, wenn Sie hier Null angeben, wird
dies einfach
in ein optionales Feld von leer umgewandelt. Okay? Lass uns diesen Flow noch einmal versuchen, um zu sehen wie er diesmal funktioniert, oder? Also habe ich den Benutzer John, jetzt lösche ich ihn. Und genau hier,
wenn ich es wiederhole,
sehe ich 404 Not Found. Stimmt. So funktioniert es also. Also ja, so ist das
Dependency Injection Framework. Arbeitet hinter den Kulissen
in einem Sprungbrett. Jetzt möchte ich
Ihnen eine Best Practice zeigen , die Sie wirklich verinnerlichen
müssen, da dies absolut erforderlich ist,
wenn Sie mit Co-Design spielen und
Dienste erstellen und mit
Spring Boot spielen allgemein, was bedeutet, dass Sie
normalerweise auf Abstraktionen,
Ihre Klassen, angewiesen sind und nicht
auf konkrete Klassen. Und wenn wir uns das genau
ansehen, können
wir sehen, dass die
Benutzercontroller-Klasse von der Benutzerklasse
abhängt, von der Benutzerdienstklasse, die eine konkrete Klasse ist. Anstatt das zu haben, müssen
wir zuerst eine Schnittstelle mit dem
Namen Actually erstellen, wir müssen die
Benutzerservice-Klasse
in die
Benutzerservice-Implementierung I MPL umbenennen . Ich werde es einfach kurz
machen. Und genau hier
werde ich
eine Schnittstelle namens
User Service erstellen . Und dieser Benutzerservice sollte diese Methoden
enthalten. Benutzer bei Benutzer abrufen und Benutzer ungültig
löschen. Und dieser sollte ein Benutzermodell
sein, oder? Diese Schnittstelle
sollte natürlich durch die Implementierung des
Benutzerdienstes
implementiert werden . Wie Sie sehen, unterstreicht die
Idee von IntelliJ die Tatsache , dass wir
diese Schnittstelle jetzt implementiert haben. Und das ist die
Kernidee hinter dieser Strategie, dass
ich im Benutzercontroller die Schnittstelle, die Benutzerservice-Schnittstelle
und nicht
die Implementierung anfordere Benutzerservice-Schnittstelle
und nicht
die . Und Spring Boot
macht das Folgende. Wenn es versucht,
einen Benutzercontroller zu instanziieren, schaut
es auf den Konstruktor, es sieht, dass es eine Schnittstelle
benötigt, und es interpretiert
dies tatsächlich auf folgende Weise. Die
Benutzercontroller-Klasse ist also von
einer Klasse abhängig , die die
Benutzerservice-Schnittstelle implementiert. Also versucht es, nach
einer Klasse zu suchen ,
die die Benutzeroberfläche implementiert. In diesem Fall
haben wir eine einzige Klasse , die die
Benutzerservice-Schnittstelle implementiert. Und es wird
eine Instanz davon erstellen. Wenn Sie mehrere Klassen haben die dieselbe Schnittstelle
implementieren und Sie nach einer
Schnittstelle und einer Klasse fragen, müssen Sie expliziter angeben welche Klasse Sie
eigentlich wollen, oder? Und das tun Sie, indem Sie
die Qualifier-Annotation verwenden. der Qualifier-Annotation können Sie
nur eine Zeichenfolge und eine Zeichenfolge hinzufügen
, die Sie hier hinzufügen möchten. Diese Zeichenfolge sollte auch hinzugefügt werden wenn Sie eine
Instanz einer Klasse anfordern, aber auch, wenn Sie diese Klasse
erstellen, direkt in der Klassendefinition. Wenn Sie also zwei Klassen haben, implementieren Sie dieselbe Schnittstelle. Sie müssen
für beide ein Qualifikationsspiel hinzufügen
, damit die Quelle weiß
, welches sie , damit die Quelle weiß an welcher Stelle
anbieten sollte. Sie können auch mit zwei Klassen experimentieren und sehen, wie das in
Aktion funktioniert. So
sollten Sie also tatsächlich
einen Service in einer Produktionsqualität aufbauen , sagen
wir, in der Implementierung. Es hilft auch
beim Testen denn wenn Sie versuchen, den Benutzercontroller
zu testen, müssen
Sie eine neue
Benutzercontroller-Instanz erstellen. Aber wenn Sie eine erstellen möchten, anstatt alle Abhängigkeiten mit
all ihren Abhängigkeiten usw. erstellen mit
all ihren Abhängigkeiten zu müssen. Wir müssen hier nur eine
Schnittstelle markieren und angeben, dass die Dominions für
all diese Methoden waren, oder? Und du bist fertig. Sie müssen sich nicht mit
den Abhängigkeiten der Benutzerservice-Implementierung
von all diesen Dingen befassen. Sie müssen sich nur über dieses Interface
lustig machen. Und das ist es, oder? Probiere es auch mit einem
Unit-Test aus, um zu sehen, wie es funktioniert. Sie werden
einen großen Unterschied in der Art und Weise
, wie Sie Tests
implementieren, feststellen . In Ordnung, damit beginnen wir mit der nächsten
Vorlesung, in der wir einen externen Dienst
von unserer Spring
Boot-Anwendung aus aufrufen werden.
7. Konfigurationen in application.yaml hinzufügen: Willkommen zurück. In dieser Vorlesung
werden wir diese spezielle
Time-Service-Implementierung
ein wenig umgestalten .
Wie Sie hier sehen können, verwenden wir
den Uterus, um
eine Get-Anfrage an
diese Weltzeit-API zu stellen ,
um den aktuellen Zeit. Aber Sie wissen, dieser Endpunkt
könnte sich im Laufe der Zeit ändern. Möglicherweise müssen Sie eine
andere API verwenden oder Sie haben mehrere Endpunkte in
Ihrer Anwendung und möchten diese
von einem einzigen Ort aus verwalten. Anstatt also in allen Arten von Klassen nach
ihnen zu suchen, ist
es normalerweise besser,
einen Konfigurationsworkflow zu haben , in dem Sie all Ihre Konstanten
und Details Ihrer
Anwendung
speichern können all Ihre Konstanten
und Details Ihrer
Anwendung
speichern , das sollte
von einer einzigen Stelle in einer speziellen
Konfigurationsdatei aus verwaltet werden. Spring Boot verfügt über diesen
Konfigurationsmechanismus , der sehr einfach zu bedienen ist, und er lässt sich sehr gut in das Dependency
Injection-Framework integrieren. Also werden wir es jetzt
benutzen. Also gehen wir zunächst
in die Hauptklasse. Wir werden
diese Anmerkung hinzufügen, um die Konfigurationseigenschaften zu aktivieren. Dies ist erforderlich, da
wir
eine spezielle
Konfigurationsanmerkung verwenden eine spezielle
Konfigurationsanmerkung ,
die wirklich nützlich ist und für alle
Konfigurationsdateien erforderlich ist. Also werden wir ein
neues Paket namens config erstellen. Und genau hier nennen
wir
es Zeit, API, konfiguriere
diese Klasse. Wir werden
mit der
Configuration-Annotation kommentieren , die sie im Grunde im Dependency
Injection System von Spring Boot
verfügbar macht im Dependency
Injection System von Spring Boot
verfügbar , aber auch, aber auch das
Spring Framework mitteilt Diese Klasse sollte zum
Speichern von Konfigurationsdaten verwendet werden. Wir werden auch eine neue Anmerkung mit dem
Namen Konfigurationseigenschaften
hinzufügen . Und wir werden das in einer
Sekunde mit einem Parameter in
dieser Klasse
aktualisieren . Wir werden unsere Felder haben, die wir aus
der Konfigurationsdatei abrufen möchten. In diesem Fall wollen
wir den Endpunkt erhalten. Also im Grunde
wollen wir diesen in unserer
Konfigurationsdatei speichern und auch den Kontinent, weil wir vielleicht die innere
Konfiguration
des Kontinents ändern möchten . Wir sagen
private Zeichenfolge, Endpunkt und auch Kontinente. Und wir werden
Getter und Setter
für diese beiden Felder erstellen . Und wo werden wir die Konfigurationsdatei
speichern? Wir gehen
in das
Ressourcenverzeichnis und erstellen hier
eine neue Datei namens
application dot YAML Spring with nose to Logan an
diesem Ort, Ressourcen, direkt in den
Ressourcen
Verzeichnis. Und es wird nach dieser
Anwendungs-Yaml-Datei suchen. Wenn dies vorhanden ist, sucht es
darin nach Konfigurationen. In dieser
Konfigurationsdatei sage ich also API-Dot-API-Endpunkt. Und genau hier füge ich
den Endpunkt unserer Anwendung ein, der diese ist
, und warne Sie, dass Sie auch den Kontinent,
in diesem Fall Europa, hier einfügen . wir diese
Konfiguration hier haben,
können wir die
Daten an einem einzigen Ort speichern. Jetzt, in dieser Zeit,
konfiguriere ich vielleicht anhand der
Konfigurationseigenschaften. Wir werden ein Präfix
für unsere Konfiguration festlegen. Nun
ist ein Präfix für
unsere Konfiguration im Grunde das,
wie der Name schon sagt, das Präfix, unter dem sich
unsere Konfiguration für die Anwendung
in der Anwendungs-Yaml-Datei befinden
sollte . In diesem Fall sollte der Wert
für unser Präfix also API sein, da
wir unter diesem API-Schlüssel diese beiden
Felder haben, die wir in der
Time Config-Klasse speichern
möchten . Mit anderen Worten, das
ermöglicht uns alle Arten von hierarchischen
Konfigurationen, oder? Und je nach Präfix können
Sie auswählen, welchen Bereich
der Konfiguration Sie in Ihrer Klasse
speichern möchten, oder? Weil Sie vielleicht definitiv
keine große Klasse mit allen Konfigurationen
in
der Anwendung Yaml haben
möchten große Klasse mit allen Konfigurationen
in
der , oder? Ordnung, sobald wir
diese Klasse erstellt haben, werden
wir sie für
die Time-Service-Implementierung verwenden . Wir werden es im Grunde
injizieren, oder? Auf die gleiche Weise haben wir es mit
den anderen Diensten gemacht , die wir dem Konstruktor
hinzugefügt haben. Dependency Injection
Framework
kümmerte sich um ihre Initialisierung. Also sagen wir die
Constructor Time API Config, wo Sie
das in unserem Feld speichern möchten ,
und das war's. Jetzt werden wir
es benutzen, oder? Also sagen wir Time API,
Config Dot, GET Endpoint. Wir werden
dies mit get continent
und dann mit der Zeitzone verketten , die wir aus dem Parameter erhalten. In dieser Zeile werden wir es auch
etwas kürzer
machen . Okay, also der Endpunkt, wenn wir
ein bisschen auf die
Dokumentation schauen und in Schrägstrichen, und dann haben wir den Kontinent, das ist Europa, und
dann bekommen wir eine Zeitzone. Also brauchen wir hier auch einen
zusätzlichen Schrägstrich , da die Zeitzone eine direkte Zeichenfolge
ist. Also müssen wir ein zusätzliches
Sklavenschiff hinzufügen. Das sollte es sein. Lassen Sie uns hier einen Breakpoint setzen , um zu sehen, ob das tatsächlich funktioniert. Ordnung, jetzt werden
wir eine Anfrage stellen, um
einen Benutzer hinzuzufügen , und wir werden
uns
dieses Mal die API-Konfiguration ansehen . Und wir können sehen, dass
unsere Werte in dieser Klasse korrekt eingegeben wurden. Und wenn wir die Anfrage stellen, sollte
sie so funktionieren, wie
wir es erwarten, oder? Also kommen wir auf Null, um akzeptiert zu werden,
wenn wir es zurückbekommen, ja. Sollte so funktionieren, wie wir es erwarten. Ja, das ist
so ziemlich die Art und Weise, wie wir in Spring mit
Konfigurationsklassen spielen
können, aber wir können auch
einige
Standardkonfigurationen ändern , die von Springboard gelesen
werden, z. B. den Port auf welche unsere
Anwendung ausführt, in diesem Fall ADHS. Wenn wir
einen anderen Port verwenden möchten, können
wir leicht
Serverport 9019 sagen. Und wenn wir
die Anwendung realisiert haben, liest
Spring Boot diese Konfiguration und
ändert den Port
entsprechend, oder? Wie Sie sehen, wurde die
Änderung sofort
beim nächsten Durchlauf wirksam. Natürlich deckt die
Dokumentation alle verfügbaren Konfigurationen ab
, die wir hier hinzufügen können. Sie können
dasselbe auch mit der Datei mit den Anwendungseigenschaften tun. Wenn Sie also im
Internet suchen und auf
diese Konfigurationsdatei stoßen , ist es so
ziemlich dasselbe, außer dass sie eine kürzere Möglichkeit bietet die
Konfigurationsanwendung zu spezifizieren. Yaml funktioniert
so ziemlich auf die gleiche Weise. Lassen Sie uns damit zur nächsten Vorlesung
übergehen.
8. Externe Dienste per HTTP abrufen: Willkommen zurück. In der Regel interagieren
Sie in einem Webservice also entweder mit einer
Datenbank, um einige Daten
abzurufen , zu verarbeiten und dann an Ihre Kunden
zurückzuliefern. Oder Sie interagieren mit einem
anderen Dienst,
um einige Daten
abzurufen, oder fügen
diesem Dienst einige Daten hinzu, um
einen Geschäftsablauf auszuführen einen Geschäftsablauf , den Ihre Anwendung
ausführen
soll . in unserer Anwendung. Nehmen wir an, wenn wir einen Benutzer zu unserer Map
hinzufügen, möchten
wir auch
die Erstellungszeit in
UTC speichern , zu der dieser Benutzer für die
Erstellungszeit dieses Benutzers
erstellt wurde . Und anstatt
dies zu tun, indem
wir
die nativen Methoden aufrufen , die
wir in der
Java-API haben , möchten wir zusammen eine externe API verwenden um
Zeitverzerrungen oder ähnliches zu berücksichtigen. Wir machen das
nur, um des
Beispiels willen wie man einen
HTTP-Aufruf an eine externe API durchführt. werden wir tun. Die API, die
wir
aufrufen werden, heißt World Time API. Es ist sehr einfach
. Sie müssen nur eine Anfrage
an diese URL mit
der Zeitzone stellen und Sie erhalten manchmal
eine JSON-Payload-Breite
zurück , dann verwenden wir
diese. Lassen Sie uns also alle Bewerbungen
ein wenig darauf vorbereiten. Wir werden einen neuen
Dienst erstellen, den wir Zeitdienst nennen werden. Nicht unbedingt der beste Name, aber es ist der, den
wir verwenden werden. Also werden wir es mit
der Service-Annotation
kommentieren und
das auch auf
die
Time-Service-Implementierung ändern , oder? Und wir werden das
Time Service Interface verwenden. Welche Methoden
müssen wir also anwenden, damit wir die
tatsächliche Zeit
tatsächlich zurückgeben können , oder? Aktuelle Uhrzeit abrufen, wir können
sagen, aktuelle Uhrzeit abrufen. Und hier können wir
eine Zeitzone angeben, oder? Was so etwas
wie die Stadt
in Europa oder in anderen
Regionen der Welt sein kann , wir wollen die Zeit haben. Zurück zur
Implementierung können
wir die Methoden implementieren. Genau hier. Wir können, wir können tatsächlich den Kern
erstellen, aber jetzt nutzen wir diesen Service in unserer
Service-Implementierung. Auf dem Konstruktor können
wir also
vom Dependency
Injection Framework
eine Instanz von
Time Service Time,
Servicezeitumfragen anfordern vom Dependency
Injection Framework eine Instanz von
Time Service Time, , die wir auch
als privates Feld speichern können was übrigens auch endgültig
sein kann, oder? Das Gleiche gilt für diesen
, weil wir die Instanzen
einmalig
erstellen wollen , oder? Also haben wir den Serve, den Time Service hier und wir werden
ihn einfach für die Add User Methode verwenden. Was natürlich brauchen wir ein
Feld im Benutzermodell dem wir
den Erstellungstyp speichern wollen. Schöpfung. Benötige auch den Setter und
Getter für dieses Feld. Und wir werden es mithilfe
der intelligenten
Ideenfunktionalität
erstellen . Also haben wir einen Getter bekommen und wir wollten auch einen Setter
für dieses Feld, oder? Also werden wir
diese beiden Methoden nach der
Dekonstruktion nach unten verschieben . Jetzt haben wir also einen Platz
in unserem Modell, an dem wir diese
Schöpfungszeit einplanen wollen. Wir müssen
eigentlich nur
Time Service Dot auf dem
Benutzermodell sagen , oder? Wenn Sie Benutzerpunkt sagen,
legen Sie die Erstellungszeit fest. Und hier müssen wir sagen,
time service dot get current time von, sagen
wir Amsterdam. Das sollte eine Zeit sein. Nehmen wir an, es ist standardmäßig in
Europa. Amsterdam ist die
Stadt, die wir wollen. Nun
kann
diese, diese Zeitzone natürlich von einem externen Dienst,
Colocation Services, abgerufen werden ,
der den Standort
anhand der Client-IP erkennt . Sie können dies also noch
weiter ausbauen , um immer
komplexere Funktionen zu erhalten. Aber in diesem Fall lassen wir es einfach
so wie es ist. Die Hauptfrage hier wäre, wie bekommen wir die Zeit? Wie nennen wir das HTTP-API? Dafür verwenden wir also einen HTTP-Client, der Union Rest
heißt. In Java können wir
es schaffen, Kunden zu sein. Wir haben auch eine integrierte Version, aber diese ist die
einfachste Methode, die ich kenne, um eine HTTP-Anfrage von einer
Anwendung an eine externe API zu stellen. Also
importieren wir einfach die Abhängigkeitseinheit, wohingegen Java, wir
werden sie in die
aufgebaute
Gradle-Datei einfügen und auf Sync klicken. Schau nach, ob das richtig ist. 11311. Sieht toll aus. Es wurde festgestellt, dass es eine neuere Version
dieser Abhängigkeit gibt. Das ist der eine. Also in unserem Zeitdienst, wenn wir
die aktuelle Uhrzeit haben wollen, können
wir so etwas sagen. Union Rest Punkt,
gib uns hier eine URL. Und die URL ist die
, die wir hier haben. Aber natürlich muss es diese Zeitzone
enthalten. Dann können wir es als Jason sagen. Das bedeutet also,
die Anfrage zu stellen und
die Antwort zurückzubekommen. Jetzt gibt Jason eine
HTTP-Antwort von Jason Node zurück, was ein
primitiverer Datentyp ist. wollen wir nicht wirklich tun. Das wollen wir auch in ein Modell umwandeln. Schauen wir uns also an, ob wir dafür
andere Optionen
für diesen HTTP-Client haben. Also sagen wir als Objekt, oder? Wir haben das hier als Objekt. Wir haben auch die asynchrone Version. Wenn wir also als Objekt sagen, müssen
wir
hier eine Klasse bereitstellen, die
das Format der
Antwort hat , das wir von der API
erwarten, oder? Das ist also etwas, das wir ein- und ausarbeiten
müssen. In den Modellen können
wir also Zeit sagen. Oder die API-Antwort auf die Uhrzeit des Timers. Das kann ein Name für unsere Klasse sein und wir haben
zwei Möglichkeiten, oder? Bei der Definition dieser Klasse können
wir entweder ein Feld
für jedes Schlüsselwertpaar erstellen , das wir hier haben. Aber weil wir
nicht all diese Felder verwenden werden, verwenden wir
stattdessen nur dieses. Wir müssen
sie nicht unbedingt alle erstellen. Wir können einfach
nur diesen erstellen. Also UTC-Datum/Uhrzeit, wir sagen private
Zeichenfolge UTC-Datum/Uhrzeit, der Name sollte übereinstimmen. Wir können Konstruktoren hinzufügen, oder? Und auch Getter und
Setter für dieses Feld. Und wir werden den
Konstruktor hier auf dieser
Klassenebene etwas nach
oben verschieben ,
wir sagen json,
ignore, ignoriere, ignoriere
Eigenschaften, oder? Diese Anmerkung
ignoriert also alle Eigenschaften
, die wir hier nicht haben, als
Felder in unserer Klasse. In dieser Zeit
extrahieren wir einfach das, was wir brauchen,
aus dieser Nutzlast. Mit diesem Modell können
wir es also genau hier verwenden. Und Sie können sehen, wie Time
Service implementiert wird. Wir können die
Zeit-API-Antwort auf die Klasse sehen. Und wir können es gleich hier haben. Nimm den Körper, richtig. Wir sollten diesen
Text nicht vergessen, da als Objekt eine
HTTP-Antwort Ihres Typs
zurückgibt. Also müssen wir
get body verwenden, um das richtige
Antwortobjekt abzurufen. Sobald wir diese Antwort haben, können
wir sagen, dass der Antwortpunkt
Sie zu Datetime bringt, richtig, das Feld
aus unserer Klasse
extrahieren. In Ordnung, also schauen wir mal, was
wir bis jetzt gemacht haben, oder? Also verwenden wir diesen Dienst, um die beiden zusammen
aus dieser externen API zu extrahieren, und wir platzieren diese Zeit einem neuen Feld in unserer
UserModel-Klasse. Nun, natürlich
müssen wir sehen, ob das funktioniert. Lassen Sie uns diesen Breakpoint erreichen
und unsere Anwendung neu starten. Ich werde nur einen Breakpoint in
unserer
Time-Service-Implementierung
hinzufügen , um zu sehen, ob die Kohle korrekt
verarbeitet wurde. Also werde ich diesen Benutzer wieder
hinzufügen und ich kann diese
Antwort sehen, oder? Und das ist der eine. Ich kann hier also einige Daten sehen, was bedeutet, dass ich die Antwort von
dieser externen API
korrekt
erhalten habe. Wenn Sie mehr Dinge
debuggen möchten, können
Sie auch
diesen Quelltext entfernen und diese HTTP-Antwort der
Time-API-Antwort
verwenden, oder? Und dann sage Antwortpunkt, Text
abrufen, UTC, Datum, Uhrzeit abrufen. Denn in dieser HTTP-Antwort können
Sie mehr Dinge wie
den HTTP-Status sehen oder ob
es eine Datenpufferung gibt, können in diesem Objekt
alle möglichen Details
gesehen werden, oder? Also werde ich nochmal darauf eingehen. Und ich werde sehen, dass diese HTTP-Antwort
wieder richtig wird. Sie können also sehen, dass wir den Statuscode 200
erhalten. Sie können sehen, dass
wir keinen Fehler erhalten haben. Sie können die Header sehen, die von dieser API empfangen
wurden. Wir können sie alle hier sehen. Und wir können auch die Leiche sehen. Der Körper hat dieses, dieses Objekt mit unserem Datentyp,
richtig, drücken Sie F9, um die Ausführung
fortzusetzen. Und das ist es, oder? Wir sind auf Null gegangen, um es zu akzeptieren. Wenn wir nun den Benutzer zurückbekommen, sollten
wir auch diese
Erstellungszeit sehen, da dieser Get-Flow tatsächlich
das gesamte Objekt zurückgibt und
es in der HTTP-Antwort anzeigt. Das ist so ziemlich
alles, was Sie brauchen, um in Spring Boot
einen externen Dienst von Ihrer
Anwendung aus aufzurufen . Das ist eine sehr interessante
Art , sich mit
anderen Diensten zu verbinden. Und in der nächsten
Vorlesung werden
wir ein wenig an der
Service-Implementierung arbeiten diesmal ein wenig an der
Service-Implementierung arbeiten, um
sie ein bisschen
konfigurierbarer zu machen . Lassen Sie uns damit zur nächsten Vorlesung
übergehen.
9. MySQL mit Docker konfigurieren: Hallo zusammen und willkommen zurück. In dieser Vorlesung
werden wir sehen, wie
wir von einer Spring Boot-Anwendung aus eine Verbindung zu
einer Datenbank herstellen können . Denn wie ich
in der Services-Vorlesung erwähnt habe, kann
der Microservice
entweder eine Verbindung zu einem externen Dienst herstellen, um
einige Daten abzurufen oder einige Daten zu senden, oder er kann sich für genau
dasselbe tatsächlich mit
einer Datenbank verbinden Ding, richtig? Sie benötigen also irgendwie
eine Möglichkeit oder einen Ort, um Ihre Informationen zu speichern und sie aus
Ihrer Anwendung
zurückzurufen. Und natürlich
verfügt Bring Wood über eine Reihe von Mechanismen , die es uns ermöglichen, dies einfacher zu tun als, sagen
wir, Sie
tun es alleine. Und es ist auch
wichtig, dies
im Zusammenhang mit
mehreren Datenbankvarianten und
-modellen sowie
Datenmodellierungsschemata zu sehen im Zusammenhang mit
mehreren Datenbankvarianten und
-modellen sowie . Wir werden uns diese Übung also von
den Gebieten dieses komplexen, sagen
wir mal, Datenspeicherökosystems das wir derzeit in der
Branche haben. Was wir in dieser Vorlesung also im Grunde tun werden
, ist, diese Benutzerzuordnung durch meine Folgetabelle
zu
ersetzen, die tatsächlich ein
Schema haben wird, das dem in
diesem Benutzermodell sehr ähnlich die tatsächlich ein
Schema haben wird, das dem in
diesem Benutzermodell sehr ähnlich ist, oder? Also so ziemlich
dieselben Felder mit, sagen
wir mit einer ID
, die als
Kennung für einen Datensatz in
der Datenbank als Primärschlüssel dient Kennung für einen Datensatz in . Diese Vorlesung
wird also im Grunde aus zwei Teilen bestehen. Die erste wird die sein,
in der wir
eine Datenbank erstellen und sie so konfigurieren, dass
die eigentliche Tabelle erstellt wird. Der zweite Teil besteht
darin,
unsere Spring Boot-Anwendung tatsächlich zu modifizieren , um mit der Datenbank zu interagieren. Fangen wir also mit
dem ersten Schritt an, oder? Ich öffne mein
Terminal und
verwende Docker, um einen MySQL-Container auszuführen. Jetzt ist Docker natürlich keine Voraussetzung für diesen Kurs. Ich erwarte nicht, dass
du weißt, wie es ist. Aus diesem Grund werde
ich eine
sehr kleine Einführung in
diese spezielle Technologie geben diese spezielle Technologie und
alle Befehle, die ich
ausführe, Schritt für Schritt erklären . So kann es
für Sie tatsächlich einfacher sein, dem zu folgen. Zuallererst die
Docker-Container-Laufzeit. Sie können tatsächlich direkt
hier auf docs.docker.com gehen. Und Sie können tatsächlich viele Details
über Docker
als Technologie finden . Kurz gesagt, Docker
ist eine Technologie, mit der wir Container ausführen können. Und Container sind im Grunde eine
leichtgewichtige virtuelle Maschine die keinen Hypervisor benötigt
, wie VirtualBox oder
VMware oder Hyper-V. Sie können also grundsätzlich
einen Container mit Darker ausführen wenn Sie die Docker Engine
auf Ihrem Betriebssystem installieren und natürlich, wenn Sie einige Befehle
ausführen. Also wollen wir z. B.
MIC namens Container
auf diesem Computer ausführen , ich habe Docker hier bereits für Mac
installiert. Um also
einen MySQL-Container ausführen zu können, muss
ich sagen,
Docker run minus E, mein Quadratwurzel-Passwort und dann ein Port-Mapping und dann mein Sequel-Image
gefolgt von der Version. Schauen wir uns also an, was dieser
Befehl tatsächlich macht. Docker Run bedeutet, dass ich einen Container
mit Darker
ausführen möchte , oder? Dann heißt es minus e, ich möchte
diese
Umgebungsvariable erstellen und im Container
verfügbar machen. Umgebungsvariable ist
im Grunde nur ein Schlüssel-Wert-Datenpaar , auf das
in einer bestimmten Umgebung zugegriffen werden
kann, entweder in der aktuellen
Show oder in einem Container, normalerweise auf
Systemebene, oder? Aus diesem Grund wird es
im Grunde als Umgebungsvariable bezeichnet . In diesem Fall möchte ich also das Root-Passwort für
den Root-Benutzer
festlegen , da
wir das
Passwort für den Root-Benutzer benötigen, um sich in mein Sequel einloggen zu
können . Und in diesem Fall wird der Wert für das Passwort
einfach getestet. Und dann bedeutet minus p , dass ich
ein Port-Mapping erstellen möchte. Ein Port ist im Grunde
eine Kennung für eine Anwendung im Kontext
eines größeren Systems mit
mehreren Prozessen. Ein Betriebssystem
hat also eine Reihe von Ports, mit denen Sie über das Netzwerk eine
Verbindung herstellen können. Und jeder Port
identifiziert im Grunde eine Anwendung. Und die Anwendung kann Verbindungen
über diesen Port
empfangen und sie
verarbeiten und Antworten
zurückerhalten und so weiter, oder? In diesem Fall möchte ich also sagen, dass ich diesen Portvertrag
O6 von meinem lokalen Computer aus abbilden möchte. Von der Maschine, wenn ich diesen
Befehl
ausführe, der auch
als Host bekannt ist, bis
zum Port 3306 im Container. Jetzt, in dem Container
an diesem Hafen, läuft mein geheimer Prozess tatsächlich
ab. Aus diesem Grund. Ich habe dieses Porträt gewählt, das O6 direkt auf dem Container. Auf einer Achse kann
der Prozess über diesen Port
und den Host-Port also der Prozess über diesen Port etwas anderes
sein. Also ich kann hier einen
anderen Wert haben. Und in unserer Spring
Boot-Anwendung muss ich, wenn ich eine Verbindung
zu dieser MySQL-Datenbank herstellen möchte, diesen
Host-Port angeben, dass ich, dass ich hier richtig sitze. Der Einfachheit halber kann ich einfach sagen, dass ich denselben Port
verwenden möchte
, der
der Standardport für meine Schule ist, damit wir nicht auf andere Probleme
stoßen. Ich meine, Sie können einfach sehen,
ob der Port nicht stimmt weil er bei der
Verbindung mit der Datenbank einfach fehlschlägt. Sie können es also sofort auf das richtige
ändern. Das nächste Argument ist minus d, und minus d steht für
sie im Container. Wenn ich diesen Befehl ausführe, wartet
das Terminal nicht darauf dass
der Container beendet
oder beendet wird. Es wird einfach ein
Container im Hintergrund gestartet. Und das letzte Argument dieses
langen Befehls ist meine Fortsetzung, gefolgt von Calcium,
gefolgt von Latest. Meine Fortsetzung ist
im Grunde der Name
des Bildes, das wir ausführen wollen. Die Bilder für die Container finden Sie, wenn Sie
nach meinem zweiten Docker-Image suchen . Und Sie können diese
Website, Docker Hub, sehen, auf der Sie im Grunde
alle Bilder haben , die Sie
öffentlich bekommen können, oder? Also, The're Going Up ist im Grunde ein öffentliches Bildrepositorium. Und das ist
die offizielle Linie. Also, wenn Sie z.B.
diesen Befehl docker ausführen ,
ziehen Sie meine Fortsetzung. Es beginnt,
dieses Bild direkt
aus dem Remote-Repository auf Ihr
lokales System herunterzuladen dieses Bild direkt
aus dem Remote-Repository auf Ihr
lokales System . Ich habe dieses Bild schon. Laden Sie es herunter, damit ich es nicht erneut herunterladen
muss. Was aktuell hier
eigentlich bedeutet, ist die Image-Version, da
das Bild
mehrere Tags oder
Rechte oder Versionen haben kann . Ich
verwende derzeit die neueste Version, aber Sie können auch eine
ältere Version verwenden, wenn Sie 8031 oder eine
andere
möchten. Lassen Sie uns diesen Befehl ausführen. Wie Sie sehen können, haben wir diesen Fehler erhalten, der besagt, dass der
Port bereits zugewiesen ist, wahrscheinlich weil ich
diesen Container ausgeführt habe.
Nehmen wir an, docker ps teilt uns , welche Container
gerade laufen. Also z. B.
kann ich tatsächlich sagen, dass Docker
diesen Container tötet und
dieser Befehl zerstört
einfach den
laufenden Container
, der
zuvor von mir erstellt wurde. Also, wenn ich jetzt docker
ps starte
, heißt es , dass kein
Container läuft. Und wenn ich den Befehl ausführe , wird ein
Container erneut gestartet, was natürlich
ein anderer Container wäre. In diesem Fall erhalte ich diese sehr große ID
zurück, und das ist die ID des
Containers. Es
sollte im Grunde eine eindeutige ID sein, die
Docker für uns generiert. Nun, wenn ich die Corp leite, kann
ich sehen, dass der
Container läuft. Ich habe hier diese ID
, die identifiziert, der Container im Grunde eine
kürzere Version dieses Containers ist. Dann kann ich das Bild sehen, das vom Container verwendet
wird, gefolgt von dem ersten
Befehl, der ausgeführt
wird, wenn der
Container gestartet wird. Und das ist
im Bild selbst, also können wir
das und den Wald nicht kontrollieren. Weitere wichtige
Informationen zu diesem Container sind der
Status „erstellt“ usw. Auch das
Port-Mapping, das wir
zuvor gesehen haben ,
wird hier angezeigt. Also läuft dieser
Container. Melden wir uns nun in diesem
Container an, damit wir die MySQL-Datenbank
konfigurieren können . Um uns in diesem Container anzumelden, müssen
wir nur
Docker Exec minus IT sagen, gefolgt von der
Container-ID, gefolgt von Batch. Also, es bedeutet
interaktives Terminal. Ich möchte diesen Befehl ausführen. Exakt bedeutet, dass ich
diesen Befehl in einem interaktiven
Modus auf diesem Container ausführen möchte . Und der Befehl lautet
einfach Bash, dass ich Shell-Zugriff auf
diese Container erhalten
möchte. Wenn ich also diesen Befehl ausführe, kann
ich sehen, dass sich die
Shell tatsächlich geändert hat. Und es hat sich geändert, weil ich
jetzt im
Grunde Befehle im Container
ausführe, oder? Ich bin also nicht mehr auf dem
lokalen Host. Ich bin im Grunde auf dem Container-Dateisystem und auf dem
Containersystem, z. B. wenn ich den Befehl ls ausführe, kann
ich sehen, dass ich einen
anderen Satz von Dateien habe, richtig, als die
, die ich zuvor bekommen habe. Das, was
mich
hier in diesem Container interessiert,
ist natürlich der Zugriff auf das Labor. Dazu muss
ich mich auf meinem Bildschirm anmelden. Also muss ich
meine Fortsetzung minus U sagen, was für Benutzerroute steht, rechts umgebener Login mit einem Root-Benutzer minus
p und dann Enter, jetzt muss ich das
Passwort für den Root-Benutzer eingeben, was eigentlich
das ist, das ich über diese
Umgebungsvariable
bereitgestellt habe. Also ich kann hier testen sagen, ich habe einfach test
und dann Enter eingegeben. Und das kann ich mir vorstellen.
Und jetzt bin ich in meiner Sequel-Datenbank angemeldet. Also das Erste, was
ich hier tun muss, denn das ist eine
neue Datenbank. Ich muss sagen,
Datenbanktest erstellen. Ich möchte eine
neue Datenbank erstellen, die test und diesen Befehl
heißt , jetzt muss ich diese Datenbank verwenden. Also muss ich sagen, benutze Test. Und jetzt muss ich eine
Tabelle in dieser Datenbank erstellen. Ich habe also bereits eine Abfrage , die es mir ermöglicht, diese Datenbank zu
erstellen, welche ist diese, oder? Also integriere ich diese
Tabellenbenutzerentität, die diesen Primärschlüssel hat. Und ich habe das gemacht, es ist
automatisch inkrementiert. Und dann habe ich die
Felder, die bereits
Teil des Benutzermodells
in unserer Spring
Boot-Anwendung sind Teil des Benutzermodells , richtig, also
kopiere ich einfach diesen Befehl, füge ihn hier ein und dann die Abfrage wurde
erfolgreich ausgeführt. Ich möchte einige Daten
aus dieser neuen Tabelle erhalten. Natürlich werde
ich keine Ergebnisse bekommen, aber nur um zu sehen, ob die Tabelle korrekt erstellt
wurde, oder? Ich habe ein leeres Set. Jetzt
ist die Datenbank also im Grunde eingerichtet. Hier gibt es keine weiteren Dinge, die
dem Benutzer die
Spring Boot App ermöglichen , tatsächlich Daten zu dieser Datenbank
hinzuzufügen.
10. Konfiguriere unsere Spring-Boot für die Arbeit mit MySQL: Lassen Sie uns also zur
intelligenten Idee wechseln , um mit der Konfiguration
dieser Vormultiplikation zu beginnen. Ordnung, das erste,
was wir tun müssen ist natürlich
einige Abhängigkeiten zu importieren da wir in der Spring Boot
Starter-Webabhängigkeit keine
integrierte Unterstützung
für
den Datenzugriff haben in der Spring Boot
Starter-Webabhängigkeit keine
integrierte Unterstützung
für
den Datenzugriff . Also müssen wir die
folgenden zwei Abhängigkeiten hinzufügen. Im Moment werden wir schauen
, ob wir andere brauchen. Auf dem Weg dorthin. Wir werden im
Internet nach Spring Boot Data,
JPA, Maven Central suchen. JPA steht also für
Java Persistence API. Und Spring Boot hat eine
spezielle Abhängigkeit , die sich mit
beliebigen Abstraktionen befasst oder handelt es sich tatsächlich um
die gesamte API, die
es uns ermöglicht, mit Spring Boot auf
Daten zuzugreifen. Wir werden
diese Abhängigkeit kopieren, Spring Boot Starter Data JPA. Und dann suchen wir auch
nach MySQL Connector,
Java, Maven Central. Dies ist im Grunde eine
Abhängigkeit, die es uns ermöglicht, eine
Verbindung zu meiner SQL-Datenbank herzustellen. Sie benötigen grundsätzlich
einen Konnektor für jede Datenbank, zu der
Sie eine Verbindung herstellen möchten. Und sie sollten sich im
selben Repository befinden. Also immer noch an, auf meiner Zentrale. Aber dieser ist für
meine Fortsetzung und wir
müssen natürlich wichtig sein. Ich werde mit der Tastenkombination auf Gradle
Sync klicken. Und natürlich wollten wir
darauf warten, dass Gradle die Abhängigkeiten
aufnimmt, damit wir mit der Arbeit an dem Projekt
beginnen können . Okay, jetzt haben wir
die Abhängigkeiten von, wir müssen die
folgenden Änderungen vornehmen. Also werden wir
ein neues Paket erstellen , das
wir Daten nennen werden. Also dieses Datenpaket, ich werde
eine Klasse erstellen , die ich Benutzerentität nenne. Und diese Klasse
ist die, zu der wir gehen werden, die wir verwenden werden
, um Daten
an die Datenbank zu senden
und sie zurückzubekommen. Sie fragen sich vielleicht, warum wir dafür nicht die
UserModel-Klasse verwenden? Nun, weil diese Klasse
Teil des Domänenmodells ist , das wir für die Kommunikation
mit dem Rest-Controller verwenden. Oder habe das gesehen, dieses Schema
ist das, das
wir vom Benutzer
direkt mit Postman erhalten. Also müssen wir
diese beiden Modelle entkoppeln, oder? Weil wir
in einer echten Anwendung möglicherweise nicht
unbedingt
die exakt gleiche Struktur haben . Von der Front über die Kundenseite bis hin zu
den Datenbankfrauen haben
wir möglicherweise verschiedene
Modelle direkt auf dieser Etage. Aus diesem Grund
erstelle ich ein anderes, das diesem im Grunde sehr ähnlich
sein wird. Also werde ich es im Grunde kopieren und hier einfügen. Ich sage Benutzerentität. Dieser ist ein
bisschen anders, weil er eine
serialisierbare Schnittstelle implementieren muss, oder? Im echten Leben. Der Grund, warum es serializable
implementieren muss, ist , dass diese Klasse an die Datenbank
übergeben wird, oder? Es muss mit
den Spalten in der
Tabelle übereinstimmen , die wir erstellt haben. Wie Sie wahrscheinlich hier
gesehen haben, haben
wir Vorname, Nachname, Mitglieds-ID und Erstellungszeit. Diese Felder sind also eigentlich
diese, aber natürlich mit dem Unterstrich
zwischen den Wörtern
geschrieben, oder? Sie müssen also im Grunde denen
übereinstimmen, die
wir in der Tabelle haben. Und wir müssen diese Klasse auch mit
einer sehr wichtigen
Anmerkung
versehen , die Entität genannt
wird, oder? Diese Klasse, die
für Java verfügbar ist, Persistence API, sagt uns
im Grunde, dass diese Klasse mit einer Tabelle in unserer,
in unserer Datenbank abgeglichen werden muss mit einer Tabelle in unserer,
in unserer Datenbank abgeglichen werden , oder? Wir können Felder auch mit
allen Arten von Anmerkungen versehen, die sich auf die Entitätsklasse
beziehen. Wir können diese Klasse also
noch weiter anpassen , wenn wir ein
komplexeres Szenario haben. In diesem Kurs werden wir jedoch
nicht auf
zu viele Details
zur Konfiguration dieser Klasse eingehen. Wir werden es für den Moment
einfach halten, um zu sehen,
wie die Dinge durchgängig miteinander verbunden sind. Und Sie können auch
weitere Aspekte in diesem Bereich erkunden ,
wenn Sie interessiert sind. Also haben wir die Entitätsklasse. Der zweite Aspekt, den
wir erstellen müssen, ist das Benutzer-Repository. Jetzt ist das Benutzer-Repository
im Grunde eine Schnittstelle, die das Credit-Repository der
Benutzerentität
erweitert ,
gefolgt von einer Zeichenfolge. Warum haben wir hier also eine Schnittstelle
namens User Repository,
die
mit einem Repository annotiert ist, in dem
das
Crud-Repository tatsächlich erweitert wird. Diese Schnittstelle, die
Teil von Spring Boot ist, ist im Grunde die
Hauptabstraktion für einen Datenzugriff
, der Erstellungs-,
Lese-, Aktualisierungs- und
Löschvorgänge ermöglicht . Und wir müssen
hier auch die Objekte angeben, auf denen wir
diese Operationen
mit dem Datenbankkurs ausführen wollen . Und auch der Primärschlüssel
, den wir verwenden wollen, wenn wir die Operationen
auf diesen Entitäten ausführen, oder? Wie Sie auf dieser
Oberfläche sehen können, haben wir speichern,
speichern alle, die nach der existierenden by ID bestraft werden. Also die Operationen, die
wir direkt ausführen können. Jetzt, da wir dieses
Benutzer-Repository hier haben, können
wir es tatsächlich direkt in
unserer Benutzerservice-Implementierung
verwenden . Wir können es also direkt hier einfügen, Benutzer-Repository, wir können es
als Feld speichern und wir
können es auch verwenden. Zum Beispiel können
wir in getUser sagen, dass das
Benutzer-Repository nach ID gefunden wird. Jetzt müssen wir einen Ausweis angeben. Also haben wir hier diesen Fund by
Firstname Metal hinzugefügt
, der es
uns im Grunde ermöglicht, eine Abfrage in
unserer Datenbank zu stellen , indem wir
den Vornamen und das Recht verwenden und eine Benutzerentität zurückerhalten. Jetzt haben wir zuerst dieses kleine
Problem, dass wir die
Benutzerentität in ein Benutzermodell
konvertieren müssen . Und dafür
erstellen wir einen Mapper, der eine Klasse
schreibt, die
speziell dafür konzipiert ist,
von einer Benutzerentität in ein
Benutzermodell und zurück zu konvertieren . Aber bevor wir zu diesem Teil übergehen, werden
wir auch
das Benutzer-Repository verwenden , um einige Daten hinzuzufügen. Um Daten zur Datenbank hinzuzufügen, müssen
wir also die Speichermethode verwenden. Und bei der Speichermethode müssen
wir
natürlich eine Benutzerentität angeben , oder? Wir werden es sofort
bereitstellen sobald wir die
Mapper erstellt haben. Lassen Sie uns aber auch eine Methode zum
Löschen der Benutzer implementieren. Wir werden also sagen, dass das
Benutzer-Repository
nach Benutzername gelöscht wird, oder? Also brauchen wir hier eine weitere
Anfrage. Dazu müssen wir auch eine neue Methode erstellen und
nach Vornamen
löschen. Also sagen wir hier, nach Vornamen
löschen und den Benutzernamen
hinzufügen. Außerdem müssen wir diese Benutzerzuordnung
entfernen. Eigentlich
brauchen wir es nicht mehr. Und lassen Sie uns auch
die Mapper-Klasse erstellen , die ich zuvor erwähnt habe. Also werden wir ein
neues Paket namens Mappers erstellen. Ein Mapper ist also
im Grunde nur eine Klasse, sagen
wir User Entity
Mapper, mit der wir
von einem
Typ in einen anderen konvertieren können . Lassen Sie uns also zuerst
eine Schnittstelle
namens Entity Mapper erstellen . Und diese Schnittstelle muss, sagen
wir, Parameter
generieren und
sie hat zwei Methoden. NFET-Mapper können wir also
grundsätzlich von diesem
Typ zu diesem Typ
konvertieren. Also kehren wir zurück, du sagst Map, und dann nehmen
wir die Entität
als t, als Parameter. Und wir bieten auch die umgekehrte Operation
an, bei der wir konvertieren, wobei wir ein t
von einem erhalten, den Sie schreiben. Nehmen wir an, das ist die Abstraktion, die
wir verwenden werden. Und der User Entity Mapper
wird den Entity Mapper
der Benutzerentität und des Benutzermodells implementieren . Okay? Wenn wir also
diese Methoden implementieren, können
wir sehen, dass uns
die erste Methode ein Benutzermodell
von einer Benutzerentität liefert. Die umgekehrte Map liefert uns eine Benutzerentität aus einem Benutzermodell. Also werden wir
diese Klasse auch zu einer Komponente machen , oder? Weil wir es als Werkzeug benutzen. In diesem Fall
können wir einfach Benutzermodell des Benutzers
zurückgeben, tatsächlich Entitätspunkt FirstName, LastName, Mitglieds-ID und
Erstellungszeit, natürlich, mit einem neuen und
natürlich ist dies ein in diesem Fall etwas
überflüssig, aber in einem realen Szenario werden Sie, Sie werden
diese Modelle driften lassen. Sie müssen also hier einige
Änderungen hinzufügen, oder? Klasse wird keinen
bestimmten Parameter haben, die andere wird ihn haben. Sie müssen also hier
einige Konvertierungen
vornehmen , um manchmal eine gewisse Desinfektion vorzunehmen. Ich mache das eher wie
eine Übung, um zu
wissen , dass dies in einem realen Szenario
passieren kann und wird. Mit diesem User
Entity Mapper
fügen wir ihn
nun in die
Benutzerservice-Implementierung ein. Aber natürlich werden
wir die Schnittstelle verwenden,
richtig, um die Dinge zu entkoppeln. Also Entity Mapper, wo Sie den Entity Mapper verwenden
müssen
, der dieser ist, sagen
wir Benutzer,
sagen wir Entity Mapper,
um sicherzugehen, dass wir ihn als Feld haben. Und genau hier, wo wir den Vornamen
finden, oder? Wenn wir also die
Benutzerentität zurückbekommen, sagen
wir
Map, weil wir die Entität
haben und das Benutzermodell zurückbekommen
wollen. Okay? Das ist es also, was wir wollen. Wenn wir nun eine
speichern wollen, verwenden Sie eine Entität, was Sie sagen möchten, Entity
Mapper Dot Reverse Map. Und wir werden den Benutzer
weitergeben, oder? Wir übergeben das Benutzermodell, die umgekehrte Map
ruft eine Benutzerentität ,
die für dieselbe Operation verwendet wird. Das ist also im Grunde
die Art und Weise, wie wir es machen würden. Natürlich haben wir keine Fehlerbehandlung,
wir
haben kein
Ausnahmemanagement in diesem Code. Es ist im Grunde so einfach wie möglich, damit Sie die Grundidee
bekommen können. Wir können sie auch final machen. Und das Letzte
, was wir
in dieser Anwendung tatsächlich brauchen , um
eine Verbindung zur Datenbank herzustellen, ist, hier in
der Anwendung eine
Yaml-Konfiguration
für die Datenbank hinzuzufügen der Anwendung eine
Yaml-Konfiguration , oder? Also dafür, also im Grunde genommen
der Endpunkt der Port und diese Konfiguration
ist die folgende, oder? Also habe ich diese
Konfiguration einfach aus einer Datei eingefügt. Die zuvor wiederhergestellte Konfiguration
ist im Grunde eine Spring-Datenquellenkonfiguration,
bei der wir die URL übergeben, richtig, die
den Endpunkt als Port enthält. Dies ist der
Host-Port, sehr wichtig. Also der erste in diesem
Befehl genau hier, oder? Also dieser, der erste,
der Host-Port, gefolgt vom Datenbanknamen genau hier haben wir den
Benutzernamen und das Passwort bekommen. Mit diesen Details können
wir uns also mit der Datenbank verbinden. Natürlich gibt es auch andere Anwendungen
in produktionstauglichen
Anwendungen Sie müssen alle Arten
von Verbindungspool-Setups
und viele andere Details angeben . Aber um das Beispiel beizubehalten, ist
dies die
Mindestkonfiguration, die wir hier
angeben müssen , um
eine Verbindung zur Datenbank herstellen zu können. Lassen Sie uns diese Anwendung also im
Debug-Modus ausführen , um zu sehen, ob sie funktioniert. Höchstwahrscheinlich nicht
, weil es beim ersten Versuch nie funktioniert. Also wie du hier sehen kannst. Wir haben keinen Unterricht. Sie haben Java x, x, xml gefunden. Sehr seltsame Ausnahme, oder? Wenn wir
eine Klasse nicht gefunden haben, ist normalerweise eine Abhängigkeit wahrscheinlich aufgehoben. Und in diesem Fall
sprechen wir im Grunde von dieser Abhängigkeit, J XB minus API. nicht wirklich sicher,
was das Problem ist. Ich habe festgestellt, dass das im Internet
ein häufiges Problem ist. Also werden wir es hier hinzufügen, um
zu sehen, wie es funktioniert, oder? Jetzt heißt es also, dass wir
keine Kennung für die Entität
angegeben haben . Das bedeutet also, dass
wir
eine Kennung für
diese Benutzerentität hinzufügen müssen . Identifier ist im Grunde ein
Feld, das mit der ID annotiert ist. In unserem Fall müssen
wir diese
ID-Anmerkung
natürlich zum Primärschlüssel hinzufügen . In unserem Fall möchten wir nicht
unbedingt, sagen
wir, eine Integer-ID hinzufügen , genau
hier ist dies möglicherweise nicht nützlich. Nehmen wir an, wir können es
unter FirstName ausprobieren und sehen
und sehen, wie es funktioniert, oder? Wie Sie sehen können, wurden die
Anwendungen gestartet. Versuchen wir nun, einen
Benutzer in unserer Anwendung hinzuzufügen. Also gehen wir gleich
hier auf das sichere Metall
der Add User Methode in Rio, um Postman zu verwenden, um
einen Benutzer hinzuzufügen, oder? Mal sehen, was da steht. Wir haben F9 gedrückt, keine Ausnahme, wir kommen auch wieder auf Null. Es bedeutet also, dass keine Ausnahme von der Anwendung besteht, oder? Wir können also auf
Aus Benutzerentität auswählen klicken. Wir können sehen, dass der Benutzer
in der Datenbank ist, was natürlich wirklich großartig ist. Ich meine, wir haben es geschafft,
Daten zu unserer Datenbank hinzuzufügen. Lassen Sie uns auch einen anderen Benutzer hinzufügen. Es scheint also so zu
funktionieren, wie wir es erwarten. Lassen Sie uns nun versuchen, einige Daten
zurückzubekommen. Also dieser hier, es
sieht aus, als ob er funktioniert. Wenn ich nach Daniel
suche, scheint es ziemlich gut zu funktionieren, was wirklich toll ist. Ich meine, ja, lass uns
auch einen Benutzer löschen. Ja, bei dieser Operation
sehen wir also so aus, als hätten wir ein Problem, es
sieht so aus, als ob wir einen Fehler haben. Was es also sagt,
es heißt, dass kein Entitätsmanager
, dessen tatsächliche Transaktion für den aktuellen
Thread
verfügbar ist, nicht zuverlässig verarbeiten kann, um Kohle zu
entfernen, oder? Dieser Fehler sagt
uns also, dass wir
diese Transaktionsanmerkung
zur Löschmethode nicht haben . Und dies ist ein sehr
wichtiger Punkt, auf den ich mich
stützen wollte , da der
Löschvorgang normalerweise sehr empfindlich ist. Ich meine, Sie können
es tatsächlich von mehreren Threads aus ausführen, von mehreren,
sagen wir, Ausführungsabläufen weil Sie möglicherweise auf
Parallelitätsprobleme stoßen. Sie können also
tatsächlich
Inkonsistenzprobleme haben , Rennbedingungen. Um diese in Spring Boot zu lösen, müssen
Sie diese
transaktionale Annotation verwenden, die uns im Grunde sagt, dass alle Operationen dieser
Methode, die sich natürlich auf
das Benutzer-Repository beziehen , ausgeführt
werden einer Transaktion, die
im Grunde eine atomare
Operation in der Datenbank ist , die entweder
erfolgreich sein oder fehlschlagen kann, aber nicht teilweise
ausgeführt werden kann, oder? Aus diesem Grund benötigen
wir diese
Transaktionsanmerkung in
unserer Methode, damit wir
den Löschvorgang ordnungsgemäß
ausführen und schreiben können . Fügen wir also auch einen neuen Benutzer hinzu,
damit wir sehen können, dass es funktioniert. Ich habe den Markets-Benutzer gelöscht
, um zu sehen, ob das funktioniert. Wenn ich lösche, sagen wir mal
den Daniel-Benutzer, oder? Sieht aus, als hätten wir 204 bekommen, okay, und der Benutzer
wurde aus unserer Datenbank gelöscht. So funktioniert es also. Ich lasse Sie
dieses Problem mit
den Benutzerentitäten beheben . Also probiere es einfach aus, schau, ob
du es verwenden kannst , findest du in der
Dokumentation und Anmerkung, mit denen
wir eine ID generieren können. Mit anderen Worten, Sie können es ausprobieren, dieses ID-Feld hier der Tabelle abzurufen, um es als
reine Feldbenutzer-Entität hinzuzufügen und zu
sehen, ob es funktioniert. Prüfen Sie, ob wir
es automatisch
aus unserer Spring Boot-Anwendung
und nicht aus der Tabelle generieren können . Das ist also im Grunde
eine Möglichkeit herumzuspielen und Dinge zu behandeln. Schau, ob es funktioniert, schau,
ob es nicht funktioniert. Siehst du, untersuche warum.
So kannst du, du kannst im Grunde
all diese Dinge lernen. Dies ist also im Grunde
eine sehr einfache Möglichkeit auf eine Datenbank zuzugreifen, wie eine End-to-End-Lösung, ohne dass zu
viele komplexe Aspekte darin enthalten sind. Wie ich
eingangs erwähnt habe, kann es sein,
dass aufgrund dieser riesigen Landschaft von Datenbanken dieser riesigen Landschaft von Datenbanken
und Varianten kann alle möglichen Probleme
mit Abhängigkeiten, Versionen, mit , die nicht vorhanden sind,
wie wir es zuvor gesehen haben. Erwarten Sie also
, dass dieser Ablauf nicht einwandfrei ist, möchten Sie nicht
leicht zu erreichen sein. Damit beginnen wir mit der
nächsten Vorlesung.