Interceptor
Ich glaube, dass Kinderschuhe mit Struts2 definitiv mit Struts2 vertraut sind. Struts2 kann den Interceptor so anpassen, dass eine Reihe von damit verbundenen Arbeiten ausgeführt werden. Und der Interceptor, über den wir hier sprechen, hat auch ähnliche Funktionen.
Ohne Unsinn zu sagen, nur codieren:
Das Folgende ist die MyInterceptor -Klasse, die die Interceptor -Schnittstelle implementiert:
public String onParestatement (String arg0) {return arg0; } public boolean onsave (Object arg0, serialisierbar arg1, Object [] arg2, string [] arg3, type [] arg4) löscht Callbackexception {if (arg0 -Instanz des Benutzer) {system.out.println ("Benutzer zu speichern } return false; } Ich werde keine anderen Methoden lesen. Befolgen Sie einfach die Standardimplementierung. Wir müssen diese beiden Methoden nur ändern. Wir müssen den Rückgabewert in Onreparestatement ändern, um die aktuelle SQL -Anweisung zurückzugeben. Die Parameter sind die ausgeführte SQL -Anweisung. Wir können die Anweisung ausdrucken, indem wir sie direkt zurückgeben.
In Onsave können Sie erkennen, dass es beim Speichern aufgerufen wird. Wir können eine Reihe von Vorbereitungsarbeiten durchführen.
Ich glaube, jeder kann es verstehen, indem er sich die Parameternamen ansieht.
Serialisierbar bezieht sich auf den Parameter der Sequenznummer, der sich auf die Attribute bezieht, die der Datenbank -ID zuordnen.
Objekt [] Dies ist eine Reihe von Zuständen, die vorerst nicht viel verwendet wurden. Ich werde es später studieren. Die API erklärt jedoch, dass die Onsave -Methode unabhängig davon, wie der Wert in diesem Array geändert wird, true zurückgeben muss.
String [] bezieht sich auf den Namen des Attributs und Typ [] ist der Typ des entsprechenden Attributs.
1) Dieser Interceptor kann einige entsprechende Vorgänge vor und nach dem Speichern der Datenbank ausführen. Wenn Sie beispielsweise die Daten ändern und Präfix oder Suffix hinzufügen möchten, können Sie sie verwenden, um sie zu implementieren. Schauen wir uns es unten an.
public boolean onsave (Object arg0, serialisierbarer arg1, Object [] arg2, String [] arg3, type [] arg4) löscht Callbackexception {if (arg0 instanceof user) {system.out.println ("Benutzer zu speichern } // Wir fügen 123 als Präfix des Namens hier hinzu user = (user) arg0; user.setName ("123"+user.getName ()); false zurückgeben; }Schauen wir uns die Testmethode an:
public static void main (string [] args) {configuration cfg = new configuration (). configure (); SessionFactory SessionFactory = cfg.buildSessionFactory (); Interceptor interceptor = new myinTeptor (); Session Session = SessionFactory.openSession (Interceptor); User user = new user (); user.setName ("Shun"); Transaktion TX = Session.BeginTransaction (); Session.save (Benutzer); tx.commit (); Sitzung.CLOSE (); } Es ist sehr einfach, wir haben es einfach gerettet. Hier gibt es keine Zuordnungsdateien und Entitätsklassen. Probieren Sie es einfach aus.
Führen Sie es aus und wir können sehen:
Benutzer zu speichern wo user_id =?Es wird den Namen und das Alter am Ende aktualisieren, vor allem, weil wir Änderungen in der Onsave -Methode vorgenommen haben.
public boolean onload (Object arg0, serialisierbar arg1, Object [] arg2, String [] arg3, type [] arg4) löscht Callbackexception {if (arg0 InstanceOf Benutzer) {System.out.Out.println ("Benutzer zu geladen =>"+(arg2 [0]+":"+arg2 [1]); } User user = (user) arg0; // beurteilen, welches Attribut Name für (int i = 0; i <arg3.Length; i ++) {if (arg3 [i] .equals ("name")) {user.setName ((String) arg2 [i]). Ersetzen ("123", ""); arg2 [i] = ((String) arg2 [i]). Ersetzen ("123", ""); }} return false; } Der Wert des modifizierten Attributs beim Laden wird in die Onload -Methode geschrieben.
Das Arg0 hier ist unser Benutzerobjekt. Es hat noch keinen Wert. Diese Methode wird nach der Lastmethode aufgerufen, daher ist es für uns nutzlos, den Benutzer zu diesem Zeitpunkt zu bedienen, und der Benutzer. Hauptsächlich in:
arg2 [i] = ((String) arg2 [i]). Ersetzen ("123", "");
Dieser Code ändert den Wert des zurückgegebenen Attributs, sodass der Wert im Benutzerobjekt, den wir im Programm erhalten, ebenfalls ändert. Führen wir die Testmethode aus, um zu sehen:
public static void main (string [] args) {configuration cfg = new configuration (). configure (); SessionFactory SessionFactory = cfg.buildSessionFactory (); Interceptor interceptor = new myinTeptor (); Session Session = SessionFactory.openSession (Interceptor); User user = (user) session.load (user.class, New Long (39)); System.out.println ("Benutzername:"+user.getName ()); Sitzung.CLOSE (); }Wenn wir uns die Ergebnisse ansehen, haben wir:
Hibernate: Wählen Sie user0_.user_id als user1_0_0_, user0_.user_name als user2_0_0_, user0_.age als Alter0_0_ von user user0_ Where user0_.user_id =? Benutzer zu geladen => 123shun: 0 Benutzername: Shun
Wir haben die ursprüngliche 123 entfernt und nach der tatsächlichen Belastung eine relevante Verarbeitung durchgeführt. Dies ist jedoch keine echte Verarbeitung vor der tatsächlichen Belastung, und es ist etwas misstrauisch gegenüber den Spekulationen. Aber es ist auch eine Überlegung. Interceptor kann in der relevanten Verarbeitung von Protokollen am meisten verwendet werden. Zum Beispiel müssen wir uns für jede Operation entsprechend melden, sodass Interceptor eine gute Wahl ist.
Sammlung
Erinnern Sie sich an das Set, das wir in den vorherigen Beispielen in Eins-zu-Many verwendet haben. Haben Sie noch den Eindruck? Wenn Sie dies nicht tun, überprüfen Sie die Informationen und überprüfen Sie sie. Heute werden wir diese Sammlungen in der Nähe lernen.
Lassen Sie uns einfach auf den Punkt kommen.
1) Lassen Sie uns zunächst ein Set lernen. Jeder weiß, dass es auch ein Set im Java -Util -Paket gibt. Was ist der Unterschied und die Verbindung zwischen Set und Set in Hibernate? Wir öffnen die Hibernate -API, finden Set und Sie können sie sehen.
Was wir sehen, ist die Elternklasse einer solchen Winterschlafsammlung. Es ist eine abstrakte Klasse mit einer Reihe von konkreten Implementierungsklassen. Wenn wir weiterhin die folgende Methode sehen, stellen wir fest, dass diese Klasse die Kapselung der Java-Sammlung implementiert, sodass wir verstehen, dass der sogenannte Hibernate-Set tatsächlich nur den Java-Set zusammenfasst.
Ist diese Eigenschaft, die keine doppelten Elemente im Set auch im Winterschlaf zulässt? Die Antwort lautet natürlich ja.
Wir sehen uns diese hier nicht an. In der Vergangenheit, als wir Mapping lernten, haben wir direkt die Eigenschaften mit den zugehörigen Klassen verbunden, aber heute sind wir nicht so. Wir verwenden eine andere Methode. Verbinden Sie einfach eine Zeichenfolge, um festzustellen, ob ein Problem besteht.
Bevor wir uns diese Frage ansehen, schauen wir uns den String -Vergleich in Java an.
Was wir sehen, ist die Elternklasse einer solchen Winterschlafsammlung. Es ist eine abstrakte Klasse mit einer Reihe von konkreten Implementierungsklassen. Wenn wir weiterhin die folgende Methode sehen, stellen wir fest, dass diese Klasse die Kapselung der Java-Sammlung implementiert, sodass wir verstehen, dass der sogenannte Hibernate-Set tatsächlich nur den Java-Set zusammenfasst.
Ist diese Eigenschaft, die keine doppelten Elemente im Set auch im Winterschlaf zulässt? Die Antwort lautet natürlich ja.
Wir sehen uns diese hier nicht an. In der Vergangenheit, als wir Mapping lernten, haben wir direkt die Eigenschaften mit den zugehörigen Klassen verbunden, aber heute sind wir nicht so. Wir verwenden eine andere Methode. Verbinden Sie einfach eine Zeichenfolge, um festzustellen, ob ein Problem besteht.
Bevor wir uns diese Frage ansehen, schauen wir uns den String -Vergleich in Java an.
public static void main (String [] args) {String s1 = "shun1"; String S2 = "Shun1"; System.out.println ("S1 == S2:"+(S1 == S2)); } Ich glaube, viele Kinderschuhe wissen, dass die Antwort wahr ist.
Schauen wir uns vor einem Beispiel unsere Mapping -Datei an. Wir schreiben die Zuordnungsklassen nicht:
Dies ist die Zuordnungsdatei für Tuser:
<class name="TUser" table="t_user" dynamic-insert="true" dynamic-update="true" dynamic-update="true"> <id name="id" column="id"> <generator /> </id> <property name="name" type="java.lang.String" column="name"/> <property name="age" type="java.lang.Integer" column = "Alter"/> <set name = "adresses" cascade = "all" table = "t_address"> <key column = "user_id"/> <!-<Eins-zu-Many/>-> <Element Column = "Adresse" Typ "String"/> </set> </class>
Als nächstes kommt die Adresszuordnungsdatei:
<class name = "adress" table = "t_address" dynamic-iNsert = "false" dynamic-update = "false"> <id name = "id" column = "id" type = "java.lang.interger"> <generator /> < /id> <Eigenschaft name = "adress" columne nicht-null = "true"> </viele zu eins> </class>
Die Kinderschuhe haben es klar gesehen. Ich kommentierte eins-zu-Viele im Set in Tuser und verwendet Element. Egal, was das Problem ist, schauen wir uns zuerst die Datenbank an:
Dies ist die T_Address -Tabelle:
Hier ist die T_USER -Tabelle:
Wir können sehen, dass der Benutzer mit ID 4 drei Adressen entspricht. Schauen wir uns als nächstes die Testmethode an:
public static void main (string [] args) {configuration cfg = new configuration (). configure (); SessionFactory SessionFactory = cfg.buildSessionFactory (); Session Session = SessionFactory.openSession (); Tuser user = (tuser) session.load (tuser.class, New Integer (4)); Set set = user.getAddresses (); Sitzung.CLOSE (); System.out.println ("Adressgröße:"+set.size ()); } Eine sehr einfache Abfrageklasse, die gerade dieses Ergebnis herausgenommen hat, wir sahen ein seltsames Phänomen:
Adressgröße: 1
Dies ist das Ergebnis!
Sie werden auf jeden Fall sagen, es muss falsch sein, es ist ein Fehler in Hibernate. Ich muss hier glücklich sein. Ich kann endlich einen Fehler einreichen. Als ich den Job wechselte, konnte ich laut sagen, dass ich einen Fehler für den Winterschlaf eingereicht habe. Haha, aber leider ist das kein Fehler.
Ich habe gerade gesagt, dass der Vergleich der Schnur, die wir vor uns hatten, den Weg hierher ebnete. Wie kann ich sie also ebnen?
Wir verwenden festgelegt in der Konfigurationsdatei und assoziieren sie über Zeichenfolgezeichen. Wenn es dann in der Datenbank herausgenommen und in den Satz eingebaut wird, wird zunächst bestimmt, ob die Werte des zugehörigen Zeichens gleich sind. Da unsere Werte gleich sind (wir werden uns nicht in den Zeitvergleich befassen) müssen wir nur wissen, dass wir, wenn wir Strings zum Vergleich verwenden, in die Streicherfalle in Java wieder fallen. Wenn Sie herausfinden, dass es nur einen gibt, ist das Löschen beim Löschen leistungsfähiger, es löscht die gleichen Datensätze.
Dann schauen wir uns den gelöschten Blick an:
Tuser user = (tuser) session.load (tuser.class, New Integer (4)); Transaktion TX = Session.BeginTransaction (); Objekt obj = user.getAddresses (). Iterator (). Next (); user.getAddresses (). REME (OBJ); tx.commit (); Sitzung.CLOSE ();
Die Ausgabe von Hibernate hier lautet:
Hibernate: Löschen Sie aus T_ADdress Where user_id =?
Ich glaube, jeder weiß, wann er alle Adressen unter dem Benutzer löschen soll. Es gibt keine andere Wahl, als all dies zu löschen.
Sie müssen also in der realen Entwicklung darauf achten.
2) Wir haben über Set oben gesprochen, es scheint, dass es nicht sehr angenehm zu verwenden ist. Es gibt eine solche Falle, aber es gibt keine Möglichkeit. SET ist das, das wir am meisten verwenden, und im Allgemeinen wird niemand direkt Strings assoziieren. Aber viele Menschen sind immer noch unglücklich, so dass der Hibernate nach Bedarf eine zusätzliche Tasche hat (vielleicht nicht nach Bedarf, vielleicht sind einige Leute in ihnen unzufrieden, haha).
Schauen wir uns zuerst die grundlegende Nutzung an:
Zunächst müssen wir das SET -Tag in der vorherigen Tuser -Mapping -Datei an ändern, um:
<bag name = "adresses" lazy = "true" table = "t_address"> <key column = "user_id" /> <element type = "string" column = "adress" /> < /bag>
Und die entsprechende Entitätsklasse muss den Adresstyp an Listentyp ändern.
Hier fügen wir drei Adressen hinzu:
Wir führen den Testcode aus:
public static void main (string [] args) {configuration cfg = new configuration (). configure (); SessionFactory SessionFactory = cfg.buildSessionFactory (); Session Session = SessionFactory.openSession (); Tuser user = (tuser) session.load (tuser.class, New Integer (4)); System.out.println ("Adressgröße:"+user.getAddresses (). Size ()); Sitzung.CLOSE (); }
Hier sehen wir:
Adressgröße: 3
Dieses Mal können wir alles sehen, unabhängig davon, ob es Wiederholungen gibt oder nicht.
Aber wir haben uns nur ein Löschproblem angesehen. Die Tasche wurde hier nicht gelöst und wir müssen Idbag verwenden. Wir sehen die Konfigurationsdatei und benötigen die folgenden Änderungen:
idbag name = "adresses" table = "t_address" lazy = "true"> <collection-id type = "int" column = "id"> <generator /> < /collection-id> <key column = "user_id" /> <element type = "String" column = "adress" /> < /idbag>
Wir sehen, dass es nur noch eine Sammlung als Tasche gibt, um die zu löschende Datensatznummer anzuzeigen.
Wenn wir den gelöschten Code erneut ausführen:
Tuser user = (tuser) session.load (tuser.class, New Integer (4)); Transaktion TX = Session.BeginTransaction (); Objekt obj = user.getAddresses (). Iterator (). Next (); user.getAddresses (). REME (OBJ); tx.commit ();
Wir sehen, dass die Ausgabeerklärung lautet:
Hibernate: Löschen Sie aus T_Address Where id =?
Diesmal wird es nicht über user_id gelöscht, sondern basierend auf der ID von T_ADDRESS, was bedeutet, dass wir den Datensatz wirklich löschen, das wir löschen müssen.
Wir sehen die Datenbank und der Datensatz ist jetzt:
Wir haben den ersten Datensatz gelöscht, es ist richtig.
3) Nachdem wir uns die beiden oben genannten Methoden angesehen haben, werfen wir einen Blick auf die Karte. Der größte Unterschied zwischen ihm und den beiden oben genannten zwei besteht darin, dass es den Schlüsselwerten entsprechen kann. Schauen Sie sich den Code direkt an, intuitive Sichtweise:
Zunächst müssen wir die Konfigurationsdatei ändern:
<map name = "adresses" table = "t_address" Lazy = "true"> <key column = "user_id" /> <index type = "string" consponse = "type" /> <element type = "string" column = "adress" /> < /map>
Der größte Unterschied zwischen IT und den beiden vorherigen ist, dass es einen Index gibt, der dem Kartenschlüssel in Java entspricht, und wir verwenden dies, um die entsprechenden Datensätze abzurufen. Denken Sie daran, dass Sie nach der Änderung hier die entsprechende Entitätsklasse ändern müssen, und Sie müssen den Typ des Attributs von Adressen in die Karte ändern.
Schauen Sie sich die Datenbankdaten an:
Hier sehen wir, dass es zwei Büros und ein Zuhause gibt. Welches Büro sollte also genutzt werden?
Mach dir keine Sorgen, wir werden es wissen, nachdem wir den Testcode ausgeführt haben:
Tuser user = (tuser) session.load (tuser.class, New Integer (4)); System.out.println (user.getAddresses (). Get ("home")); System.out.println (user.getAddresses (). Get ("Office"));Shanwei Shanghai
Ja, wie das Ergebnis zeigt, bekommen wir den einen hinter sich, der dem Prinzip der Karte entspricht. Die gespeicherten Werte überschreiben die vorherigen Werte (falls sie denselben Schlüssel sind).
Die Karte ist relativ einfach, was mit den ersten beiden vergleichbar ist.
4) Schauen wir uns die letzte an. Die Liste unterscheidet sich von den vorherigen und kann sortiert werden.
Schauen wir uns an, wie es implementiert wird:
Ändern wir zunächst die Zuordnungsdatei:
<list name = "adresses" table = "t_address" lazy = "true"> <key conal
Es ähnelt der Konfiguration von MAP, aber die Attribute des Index sind unterschiedlich. Der Index in der Karte wird als Schlüssel verwendet, um den Wert zu erhalten, während der Index der Liste als Sortierung verwendet wird.
Schauen wir uns die Datenbank an:
Wir setzen drei Werte in der Reihenfolge von 0, 1 und 2.
Führen Sie den Code aus, um die Werte von 0 und 2 zu ändern:
Tuser user = (tuser) session.load (tuser.class, New Integer (4)); Transaktion TX = Session.BeginTransaction (); Objekt obj1 = user.getAddresses (). Get (0); Objekt obj2 = user.getAddresses (). Get (2); user.getAddresses (). set (0, obj2); user.getAddresses (). set (2, obj1); tx.commit ();
Wir sehen die Ergebnisse:
Wir sehen, dass 0 und 2 ersetzt wurden, und natürlich ändert dies nur den Wert von IDX. Dies hat jedoch im Grunde die Sortierfunktion implementiert.