Dlaczego potrzebujesz pamięci podręcznej zapytań
Przepiszmy nasz przykład z pozyskiwaniem pracowników w HQL:
Employee director1 = session.createQuery("from Employee where id = 4").uniqueResult();
Employee director2 = session.createQuery("from Employee where id = 4").uniqueResult();
assertTrue(director1 != director2);
Wyniki takich zapytań nie są przechowywane ani w pamięci podręcznej pierwszego, ani drugiego poziomu.
Właśnie w tym miejscu można użyć pamięci podręcznej zapytań . Jest również domyślnie wyłączone. Aby go włączyć, dodaj następujący wiersz do pliku konfiguracyjnego:
<property name="hibernate.cache.use_query_cache" value="true"/>
Ale to tylko połowa rozwiązania. Włączyliśmy pamięć podręczną zapytań, ale musimy również określić, które wyniki zapytań chcemy buforować. To musi być napisane w zapytaniu:
Query query = session.createQuery("from Employee where id = 4");
query.setCacheable(true);
Employee director1 = query.uniqueResult();
Pamięć podręczna zapytań jest podobna do pamięci podręcznej drugiego poziomu. Ale w przeciwieństwie do tego, tutaj kluczem do danych w pamięci podręcznej nie jest identyfikator obiektu, ale zestaw parametrów zapytania. A same dane to identyfikatory obiektów, które pasują do kryteriów zapytania. Dlatego racjonalne jest używanie tej pamięci podręcznej z pamięcią podręczną drugiego poziomu.
Czyszczenie pamięci podręcznej
Jednym z ważnych zadań podczas pracy z pamięcią podręczną jest upewnienie się, że obiekty w pamięci podręcznej zmieniają się i usuwają je z pamięci podręcznej (lub aktualizują). Hibernate robi to bardzo dobrze. Czasami wydaje się nawet, że kieruje się zasadą „wyczyść pamięć podręczną w każdej niezrozumiałej sytuacji”.
Załóżmy, że chcesz zaktualizować dane użytkownika za pośrednictwem HQL:
Query query = session.createQuery("update Employee set name=’Alex’ where id = 4")
query. executeUpdate();
Hibernate nie może dokładnie wiedzieć, co się zmieniło w bazie danych, ale wie, że zmieniasz obiekt pracownika. Dlatego po wykonaniu tego zapytania Hibernate usunie wszystkie obiekty typu Employee ze swojej pamięci podręcznej.
Ale NativeQuery działa jeszcze bardziej interesująco:
Query nativeQuery = session.createNativeQuery("update employee set name=’Alex’ where id = 4")
nativeQuery.executeUpdate();
Wykonano natywne zapytanie SQL do bazy danych. Oznacza to, że coś się zmieniło w bazie danych - żądanie zostało wywołane w metodzie executeUpdate() . Dlatego w tym przypadku Hibernate zagra bezpiecznie i usunie wszystkie obiekty wszystkich typów ze swojej pamięci podręcznej .
Jak ci się to podoba? Wywołujesz nieszkodliwe żądanie, a Hibernate w odpowiedzi usuwa wszystkie dane z pamięci podręcznej! Jest to z pewnością lepsze niż gdyby trzymał przedmioty różniące się od podstawy, ale to wszystko!
Dlatego twórcy Hibernate szybko wymyślili, jak pomóc Hibernate w tym przypadku. Możesz powiedzieć, który typ jednostki ma zostać usunięty z pamięci podręcznej:
Query nativeQuery = session.createNativeQuery("update employee set name=’Alex’ where id = 4");
nativeQuery.unwrap(org.hibernate.SQLQuery.class).addSynchronizedEntityClass(Employee.class);
nativeQuery.executeUpdate();
Uwaga . Natywne zapytania wybierające nie opróżniają pamięci podręcznej , a jedynie wstawiają, aktualizują, usuwają, wywołują wywołania procedur itp.
Ręczne czyszczenie pamięci podręcznej
Z pewnych powodów możesz chcieć samodzielnie usunąć obiekt z pamięci podręcznej. Można to zrobić na różne sposoby.
Uwaga . Obiekty w pamięci podręcznej są przechowywane w grupach zwanych regionami . Domyślnie nazwa regionu jest taka sama jak nazwa klasy. Dlatego jeśli masz obiekty typu com.codegym.Employee , to wszystkie będą przechowywane w grupie (regionie) o nazwie „ com.codegym.employee ”.
Jeśli chcesz uzyskać dostęp do pamięci podręcznej i coś z nią zrobić, możesz to zrobić za pomocą obiektu SessionFactory i metody getCache() :
session.getSessionFactory().getCache().evictQueryRegion("com.codegym.employee”);
Jeśli chcesz usunąć dane ze wszystkich grup (regionów), musisz uruchomić następujące zapytanie:
session.getSessionFactory().getCache().evictAllRegions();
Aby usunąć jeden obiekt z pamięci podręcznej, należy podać jego nazwę (typ) oraz id. Możesz to zrobić na dwa sposoby:
session.getSessionFactory().getCache().evictEntityData("Employee”, 4);
session.getSessionFactory().getCache().evictEntityData(com.codegym.Employee.class, 4);
Możesz także sprawdzić, czy dany obiekt znajduje się w pamięci podręcznej:
session.getSessionFactory().getCache().containsEntity("Employee”, 4);
session.getSessionFactory().getCache().containsEntity(com.codegym.Employee.class, 4);
GO TO FULL VERSION