Cache
Heute werden wir über den Entitätsstaat und den Winterschlafcache in Hibernate sprechen.
1) Schauen wir uns zunächst den Status der Entität an:
Es gibt drei Haupttypen von Entitätszuständen: vorübergehend, persistent und abgelöst.
Sie verstehen es wahrscheinlich, indem Sie Englisch lesen.
Transient: Bezieht sich auf die Daten, die den Daten in der Datenbank noch nicht entsprechen.
Persistent: Bezieht sich auf die Daten, die den Daten in der Datenbank entsprechen, und Änderungen in der Datenbank werden in der Datenbank widerspiegelt.
Abstand: Bezieht sich auf die Daten, die den Daten in der Datenbank entsprechen. Da die Sitzung jedoch geschlossen ist, wirken sich die von ihnen vorgenommenen Änderungen nicht auf die Datenbankdatensätze aus.
Lassen Sie uns direkt codieren:
Transaktion TX = Session.BeginTransaction (); User user = new user (); user.setName ("Shun"); // Der Benutzer hier wurde nicht in der Datenbank gespeichert, und es gibt keinen entsprechenden Datensatz in der Datenbanktabelle. Es handelt sich um eine vorübergehende Statussitzung. Save (Benutzer); tx.commit (); // Nach dem Commit wird der Benutzer eine anhaltende staatliche Sitzung.CLOSE (); // Da die Sitzung geschlossen ist, wird der Benutzer zu diesem Zeitpunkt abgetrennt und alle seine Änderungen werden in der Datenbank nicht reflektiert. Session Session2 = SessionFactory.openSession (); Tx = Session2.BeginTransaction (); user.setName ("shun123"); Session2.SaveorUpdate (Benutzer); tx.commit (); // Wenn wir SaveorUpdate anrufen, wird der Benutzer wieder anhaltend und alle seine Änderungen werden in der Datenbank widerspiegelt. Session2.CLOSE (); Wir sehen den Code. Zunächst definieren wir einen Objektbenutzer. Bevor es gespeichert wird, ist es der transiente Zustand und es gibt keinen entsprechenden Datensatz in der Datenbank. Wenn wir die Änderung speichern und einreichen, wird der Benutzer persistierender Status und es gibt einen entsprechenden Datensatz in der Datenbank. Wenn wir die Sitzung schließen, wird der Benutzer abgetrennt, und seine Änderungen werden in der Datenbank nicht reflektiert, es sei denn, wir rufen die entsprechenden Aktualisierungs- und Additionsmethoden wie SaveorUpdate manuell auf. Und was sollen wir tun, wenn wir wollen, dass es von hartnäckig in den vorübergehenden Zustand wird? Löschen Sie es einfach direkt. Nach dem Löschen hat das Objekt keinen entsprechenden Datensatz in der Datenbank, was vorübergehend wird.
Der staatliche Übergang von Winterschlafe ist relativ einfach. Wenn es vorübergehend ist, gibt es keinen entsprechenden Datensatz für die Datenbank, während anhaltend und abgelöste entsprechende Datensätze haben. Der einzige Unterschied besteht jedoch darin, dass sich abgelöst ein Staat ist, der erst nach Abschluss der Sitzung existiert. Was ist der Unterschied zwischen Transient und Abstand? Es handelt sich nur um eine Frage, ob es einen entsprechenden Datenbanktabellensatz gibt.
2) Schauen wir uns nach dem Lesen des Status den Hibernate -Cache an
Es gibt zwei Arten von Caches für Hibernate: Cache 1 und Level 2 Cache.
Stufe 1-Cache: Der sogenannte Cache Level 1 ist der interne Cache.
Cache Level 2: Es enthält Cache auf Anwendungsebene, der als SessionFactory-Cache in Hibernate bezeichnet wird, und der andere ist verteilter Cache, der die sicherste Cache-Methode ist.
Schauen wir uns das Programm direkt an:
public static void main (string [] args) {configuration cfg = new configuration (). configure (); SessionFactory SessionFactory = cfg.buildSessionFactory (); Session Session = SessionFactory.openSession (); User user = (user) session.load (user.class, New Long (29)); System.out.println (user.getName ()); User user2 = (user) session.load (user.class, New Long (29)); System.out.println (user2.getName ()); Sitzung.CLOSE (); } Siehe die Ergebnisse:
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 =? Shun123123 Shun123123
In dem Beispiel haben wir Last zweimal verwendet, aber es gab nur eine SQL -Anweisung im Ergebnis, die darauf hinwies, dass sie nur einmal abfragt wurde.
Warum? Deshalb funktioniert der Hibernate -Cache. Nachdem die erste Abfrage abgeschlossen ist, erhalten Sie die gefundene Entität im Cache. Wenn Sie das nächste Mal überprüfen, dass der Cache überprüft wird, ob die entsprechende ID ein Entität gibt. Wenn dies der Fall ist, wird es direkt herausgenommen, andernfalls wird die Datenbankabfrage durchgeführt.
Ändern wir den Code an:
User user = (user) session.load (user.class, New Long (29)); System.out.println (user.getName ()); Session.evict (Benutzer); // Benutzer aus cache user2 = (Benutzer) Sitzung (user.class, New Long (29)); System.out.println (user2.getName ()); Sitzung.CLOSE ();
Siehe die Ergebnisse:
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 =? Shun123123 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_.us0_.user_id =? Shun123123
Nachdem wir den Benutzer aus dem Cache gelöscht haben, wird auch die zweite Abfrage direkt aus der Datenbank abgerufen.
Stufe 2 Cache -Gespräch
Schauen wir uns zuerst die Entity -Klasse an:
Benutzer der öffentlichen Klasse implementiert serialisierbare {public Long ID; privater Zeichenfolge Name; privates int Alter; } Die Zuordnungsdatei wird weggelassen, jeder sollte sie schreiben.
Schauen wir uns die Hibernate -Konfigurationsdatei an:
<Eigenschaft name = "hibernate.cache.provider_class"> org.hibernate.cache.ehcacheProvider </Property> <Eigenschaft name = "hibernate.cache.use_second_level_cache"> true </property> <Eigentum name = "hibernate.suse_query_query_cache"> true </probium
Wir sehen, dass wir in der Provider_class den EHCache angeben, sodass wir auch EHCache.xml in den Klassenpfad platzieren müssen:
<xml Version = "1.0" coding = "utf-8"?> <Ehcache> <diskStore path = "java.io.path"/> <defaultCache maxelementssinmemory
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 (); Query query = session.createquery ("vom Benutzerbenutzer wobei Name = 'shun123'"); Iterator iter = query.ITERATE (); while (iter.hasnext ()) {System.out.println ((Benutzer) iter.next ()). getName ()); } Session.close (); Session Session2 = SessionFactory.openSession (); Query query2 = session2.createquery ("vom Benutzerbenutzer wobei Name = 'shun123'"); Iterator iter2 = query2.Eterate (); while (iter2.hasnext ()) {System.out.println ((Benutzer) iter2.next ()). getName ()); } Session2.CLOSE (); } Nach dem Laufen können Sie sehen:
Hibernate: Wählen Sie user0_.user_id as col_0_0_ user user0_ wob Shun123 Hibernate: Wählen Sie user0_.user_id als col_0_0_ aus user user0_ wobei user0_.user_name = 'shun123' shun123
Wir können sehen, dass es nur einen Suchsatz ausführt und die ID nicht für die Suche nach der zweiten Abfrage abgerufen wird, was hauptsächlich auf den sekundären Cache zurückzuführen ist.
Lassen Sie uns zunächst den Code in der Testmethode analysieren. In der Testmethode öffnen wir zwei Sitzungen und erstellen zwei Abfragen separat für dieselbe Abfrage. Die beiden Sitzungen können jedoch den Cache, der Cache der zweiten Ebene, den Cache "SessionFactory Level" teilen. Solange unsere Sitzung von derselben Sitzung erstellt wird, können wir den sekundären Cache freigeben, um die Interaktion mit der Datenbank zu verringern.
Schauen wir uns die Bedeutung in der Konfigurationsdatei an:
<Eigenschaft name = "hibernate.cache.provider_class"> org.hibernate.cache.ehcacheProvider </Property> <Eigenschaft name = "hibernate.cache.use_second_level_cache"> true </property> <Eigentum name = "hibernate.suse_query_query_cache"> true </probium
Wenn wir den sekundären Cache verwenden müssen, müssen wir ihn zuerst konfigurieren:
<Eigenschaft name = "hibernate.cache.use_second_level_cache"> true </Eigenschaft>
Führen Sie den Cache der Account-Öffnung auf der zweiten Stufe durch und geben Sie dann vorbei:
<Eigenschaft name = "hibernate.cache.provider_class"> org.hibernate.cache.ehcacheProvider </property>
Geben Sie die Vorsorgeklasse für den sekundären Cache an. Im Allgemeinen verwenden wir EHCache. Die anderen Mine werden vorerst nicht verwendet und sind nicht sehr klar, daher werde ich vorerst nicht darüber sprechen.
Wie unser Beispiel müssen wir nur die oben genannten zwei konfigurieren, die vollständig normal ausgeführt werden und den sekundären Cache verwenden können.
Wofür ist der dritte Satz?
<Eigenschaft name = "hibernate.cache.use_query_cache"> true </property>
Diese Konfiguration zeigt an, dass wir beim Abfragen Cache verwenden müssen. Wenn wir dies verwenden müssen, müssen wir Query.SetCacheable (True) im Voraus aufrufen, um dies zu aktivieren.
Schauen wir uns den Code gemeinsam an (wir werden Cache vorerst nicht aktivieren):
public static void main (string [] args) {configuration cfg = new configuration (). configure (); SessionFactory SessionFactory = cfg.buildSessionFactory (); Session Session = SessionFactory.openSession (); Query query = session.createquery ("vom Benutzerbenutzer wobei Name = 'shun123'"); Listlist = query.list (); für (int i = 0; i <list.size (); i ++) {System.out.println (((Benutzer) liste.get (i)). getName ()); } Session.close (); Session Session2 = SessionFactory.openSession (); Query query2 = session2.createquery ("vom Benutzerbenutzer wobei Name = 'shun123'"); Listlist2 = query2.List (); für (int i = 0; i <list2.size (); i ++) {System.out.println (((Benutzer) list.get (i)). getName ()); } Session2.CLOSE (); } Die Ergebnisausgabe hier ist:
Hibernate: Wählen Sie user0_.user_id als user1_0_, user0_.user_name als user2_0_, user0_.age ASAME0_ AUSBENE UBSER0_ WHERE UMSER0_.USER_NAME = 'SHUN123' SHUN123 Hibernate: SELECT UBSER_NAME ASSER_ID ASBENE1_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0SOR_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0 -. Alter0_ von user user0_ wobei user0_.user_name = 'shun123' shun123
Wir sehen, dass der Cache nicht verwendet wird, da wir hier die Liste verwenden und nur die Liste der Cache schreibt und den Cache nicht liest. Hier werden also zwei Fragen geben.
Dann ändern wir es:
public static void main (string [] args) {configuration cfg = new configuration (). configure (); SessionFactory SessionFactory = cfg.buildSessionFactory (); Session Session = SessionFactory.openSession (); Query query = session.createquery ("vom Benutzerbenutzer wobei Name = 'shun123'"); <span style = "background-color: #ffffff;"> <span style = "color: #ff0000;"> query.setcacheable (true); </span> </span> listliste = query.list (); für (int i = 0; i <list.size (); i ++) {System.out.println (((Benutzer) liste.get (i)). getName ()); } Session.close (); Session Session2 = SessionFactory.openSession (); Query query2 = session2.createquery ("vom Benutzerbenutzer wobei Name = 'shun123'"); <span style = "color: #ff0000;"> query2.setCacheable (true); </span> listlist2 = query2.List (); für (int i = 0; i <list2.size (); i ++) {System.out.println (((Benutzer) list.get (i)). getName ()); } Session2.CLOSE (); } Ich habe zwei rote Code -Sätze gesehen. Dies sind die beiden Codes, die wir hinzugefügt haben, um den Abfragemittel -Cache zu aktivieren. Jetzt sehen wir das Ergebnis:
Hibernate: Wählen Sie user0_.user_id als user1_0_, user0_.user_name als user2_0_, user0_.age als Alter0_ aus user user0_
Es gibt nur noch eine Abfrage, warum? Nur bei diesen beiden roten Codes haben wir den Cache eingeschaltet, denken Sie daran, dass er zweimal verwendet werden muss. Stellen Sie beide Abfragen -Caches so ein, dass sie zwischengespeichert werden.
Kriterien sind auch ein ähnlicher Ansatz. Um zu vermeiden, dass einige Kinderschuhe vergessen, wie man Kriterien schreibt, werde ich einen Code eingeben:
public static void main (string [] args) {configuration cfg = new configuration (). configure (); SessionFactory SessionFactory = cfg.buildSessionFactory (); Session Session = SessionFactory.openSession (); Kriterienkriterien1 = Sitzung.Createcriteria (user.class); Kriterien1.SetCacheable (true); Kriterien1.Add (restriktions.eq ("Name", "Shun123")); Listlist = criteria1.list (); für (int i = 0; i <list.size (); i ++) {System.out.println (((Benutzer) liste.get (i)). getName ()); } Session.close (); Session Session2 = SessionFactory.openSession (); Kriterienkriterien2 = Session2.Createcriteria (user.class); Kriterien2.SetCacheable (true); Kriterien2.Add (restriktions.eq ("name", "shun123"); Listlist2 = criteria2.List (); für (int i = 0; i <list2.size (); i ++) {System.out.println (((Benutzer) list.get (i)). getName ()); } Session2.CLOSE (); } Lassen Sie uns die Ergebnisse sehen:
Hibernate: Wählen Sie diese_.user_id als user1_0_0_, this_.user_name als user2_0_0_, this_.age ASAGE0_0_ Vom Benutzer this_, wo this_.user_name =? Shun123 Shun123