|
Strona główna Zbieranina Serwisy Porady Projekty Humor sektora IT TODO Nowości Ostatnie zmiany Kontakt Find pages
Set your name in
UserPreferences Referenced by
JSPWiki v2.2.33
|
Hibernate/Struts - optymalizacja wykorzystania list słownikowychCzęsto w aplikacjach używa się różnych tabel słownikowych, których dane są używane najczęściej tylko do pokazania na listach wyboru. Dane te z reguły są stałe, bądź zmieniają się stosunkowo rzadko. Z kolei każdorazowe ładowanie ich z bazy przed wyświetleniem nie jest czymś szczególnie szczęśliwym (bo trzeba powtarzać kod, obciąża się zasoby, itd.). Aż się prosi żeby takie dane zapamiętać... Poniższy artykuł pokaże jak w prosty sposób używając Hibernate (oraz Struts) osiągnąć przechowywanie takich danych w cache. Table of ContentsWstęp. Co mamy, co chcemy osiągnąć i jak to zrobimy.Mamy aplikację webową (tutaj napisaną w Strutsach Pożądaną funkcjonalność zrealizujemy za pomocą Hibernate, a dokładniej za pomocą cechy pozwalającej na przechowywanie wyników zapytań w cache. Ma to tę zaletę, że kod aplikacji pozostanie bez zmian, późniejszą konfigurację (co i jak długo trzymać w cache) można przeprowadzać w oderwaniu od kodu aplikacji. Konfiguracja HibernateWłączamy cache'owanie zapytań poprzez dodanie parametrów do pliku hibernate.cfg.xml: <property name="cache.use_query_cache">true</property> <property name="cache.use_second_level_cache">true</property> <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property> Odpowiednie metody klas *DAOOczywiście posiadasz odpowiednie klasy *DAO opakowujące odwołania do bazy danych, prawda? Typowa postać metody DAO zwracającej zawartość tabeli słownikowej:
public static List<Bean> getBeans() {
try {
Session s = HibernateUtil.getSession();
return s.createQuery("from Bean order by name").list();
}
catch (HibernateException e) {
log.info("Error", e);
throw e;
}
}
Aby jednak Hibernate przechowywał wyniki zapytań w pamięci należy na obiekcie Query wywołać jeszcze metodę setCacheable(true), kompletna metoda będzie więc wyglądać następująco:
public static List<Bean> getBeans() {
try {
Session s = HibernateUtil.getSession();
return s.createQuery("from Bean order by name").setCacheable(true).list();
}
catch (HibernateException e) {
log.info("Error", e);
throw e;
}
}
Można sprawdzić w logach bazy danych - zapytanie do tabeli będzie wykonane tylko raz. Kolejne będą pobierać dane z cache. Konstrukcje na stronach JSPKodując formularze na stronach JSP używamy konstrukcji podobnych do: <html:form action="..." > ... <html:select property="beanId"> <html:optionsCollection name="dictionaryBean" property="beans" label="name" value="id"/> </html:select> ... Powyższy kod renderuje formularz HTMLowy z kontrolką typu select. Chcemy aby wyświetlała ona zawartośc tabeli zwracaną przez uprzednio przygotowaną metodę getBeans(). Nic prostrzego. Umieszczamy w applicationScope beana realizującego dostęp do naszej klasy DAO. Beana takiego można umieszczać na każdej stronie za pomocą konstrukcji <jsp:useBean/>, prościej będzie posłużyć się jednak implementacją interfejsu ServletContextListener i na starcie aplikacji umieścić naszego beana w odpowiednim zasięgu. Integracja stron JSP z klasą DAOTworzymy klasę stosującą się do konwencji Jave Bean, ona to będzie poprzez applicationScope pośrednikiem między tagami JSP a klasą DAO. Dla każdej z tablic słownikowych tworzymy odpowiednią metodę.
public class DictionaryBean {
public List<Bean> getBeans() {
return DictionaryService.getBeans();
}
}
Następnie umieszczamy instancję ww klasy w kontekście aplikacji:
public class ContextListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent event) {
event.getServletContext().setAttribute("dictionaryBean", new DictionaryBean());
}
public void contextDestroyed(ServletContextEvent event) {
}
}
Na koniec należy tylko jeszcze podłaczyć Listenera do samej aplikacji, robimy to poprzez dodanie elementu listener do pliku WEB-INF/web.xml określającego pełną nazwę klasy Listenera:
<listener> <listener-class>org.rydzewski.ContextListener</listener-class> </listener> Koniec.Jak to działa?
Dopieszczanie, czyli tuning.Jak coś pracuje dobrze, to może chodzić też lepiej ;-) Hibernate jako mechanizm cache używa (w podanej tutaj konfiguracji) biblioteki ehcache
<ehcache>
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="0"
timeToLiveSeconds="3600"
overflowToDisk="true"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
</ehcache>
|
||||||