2011-01-26 19 views
5

Używam aplikacji WWW Java na serwerze Tomcat i chciałbym wiedzieć, co jest "najlepszą praktyką" pod względem dostępu do połączenia z bazą danych z JNDI Tomcat?Właściwy sposób wywoływania źródła danych JNDI w Tomcat

Obecnie jest to w zasadzie to, co robię za każdym razem, kiedy potrzeba, aby uzyskać dostęp do bazy danych:

Context envContext = null; 
DataSource dataSource = null; 
try { 
    envContext = (Context)ctx.lookup("java:/comp/env"); 
    dataSource = (DataSource)envContext.lookup("jdbc/datasource"); 
    return dataSource.getConnection(); 
} catch (Exception e){ 
    e.printStackTrace(); 
    return null; 
}finally { 
    if(envContext != null){ 
     try{ 
      envContext.close(); 
     } catch (NamingException e){ 
      e.printStackTrace(); 
     } 
    } 
} 

Jednakże, jest to właściwy sposób wyszukać połączenie z JNDI za każdym razem, gdy chcesz uzyskać dostęp do bazy danych ? Czy powinienem zamiast tego odwoływać się do kontekstu lub źródła danych?

Odpowiedz

3

JNDI wyszukiwań są zasadniczo mapie wyszukiwań więc ich koszt jest minimalny. Ale lepiej jest, aby DataSource raz i "cache", że. Więc jeśli cokolwiek - napisanie metody zwracania DataSource jest idealne, aby nie wiązać zbyt wiele kodu do elementów wewnętrznych J2EE i ułatwić testowanie kodu.

+0

Dokładnie taki rodzaj odpowiedzi, którego szukałem, dziękuję. Kolejne pytanie, czy za każdym razem, gdy robię dostęp do danych, jest dużo narzutów w tworzeniu nowego kontekstu? – Avanst

+0

Relatywnie mówiąc - nie wierzę w to. Ale jeśli zepsułeś to i stworzyłeś Kontekst za każdym razem, a jedynie buforowałeś źródło danych - podejrzewam, że zobaczysz różnicę. Ale praktycznie rzecz biorąc - liczba razy, kiedy otrzymujesz DataSource (lub Kontekst) jest minimalna w porównaniu do pozostałych działań w przetwarzaniu żądania. –

+3

Wyszukiwanie JNDI nie jest kosztowne, wyszukiwania 'InitialContext' są ** BARDZO DROŻNE ** w każdym kontenerze aplikacji i powinny być wykonywane tylko raz przy uruchomieniu aplikacji. Większość ludzi nie zna różnicy. –

1

Twój kod wyszukiwania wygląda dobrze
W twoim kontekście problemowym buforowanie źródła danych wydaje się w porządku, o ile nie buforujesz rzeczywistego obiektu połączenia.

Nie stosowałem tego podejścia od jakiegoś czasu. Te dni, co najmniej, używam sprężynę wstrzyknąć źródło danych/zainicjować JdbcTemplate

+0

Tak, normalnie użyłbym jakiegoś narzędzia innej firmy, takiego jak hibernacja, ale do tego nie wolno mi używać niczego poza prostą java. – Avanst

2

można zrobić coś takiego też: -

... 

Context initContext = new InitialContext(); 
DataSource dataSource = (DataSource) initContext.lookup("java:comp/env/jdbc/datasource"); 

... 
4

new InitialContext() jest drogie w każdym kontenerze aplikacji, powinien być static final i stworzył w static {} bloku, skutecznie czyni go Singleton. Powinieneś tylko raz utworzyć to odwołanie i użyć go ponownie w dowolnym miejscu.

DataSource również powinien być static. Powinieneś mieć metodę public static Connection getConnection(); do pobierania obiektów Connection, kod nigdy nie powinien mieć do czynienia bezpośrednio z DataSource. Działa to szczególnie dobrze z implementacjami PooledDataSource.

+0

Dlaczego jest drogi? Nie musi wiele robić, a konkretnie nie musi wykonywać żadnych sieciowych operacji wejścia/wyjścia? Podejrzewam, że to miejski mit. – EJP

+0

@EJP Nie jest to miejski mit, miałem umowę, w której jeden z "wiodących" programistów (osoba VB) pisał Servlety i tworzył "nowe InitialContext()" na każde żądanie. Każda prośba trwała prawie minutę. Ośmielał się, jak powolna jest Jawa, bla, bla, bla. Sprawdziłem jego kod i przeniosłem tę linię do "prywatnego statycznego finału" i boomu. Żądanie było w zakresie "setek milisekund". To była bardzo wczesna wersja WebLogic, więc teraz może nie być tak źle z powodu Prawa Moore'a. Ale był to powtarzalny problem, gdy napisałem tę odpowiedź w marcu 2011 roku. –

+0

Nie odpowiedziałeś na moje pytanie. * Dlaczego * jest to kosztowne? i, aby zacytować cię z innego miejsca, [YEINU: Twoje wrażenia nie są uniwersalne] (https: //blog.mozilla.org/nnethercote/2014/01/02/yeinu-your-experience-is-not-universal /). Czy faktycznie przetestowałeś "każdy kontener aplikacji"? Bez tego twoja odpowiedź jest bezpodstawna. A w jaki sposób "nowa wartość InitialContext()" jest kosztowna "z powyższym komentarzem, że wyszukiwania" InitialContext "* są ** BARDZO DROŻNE **? Uzupełnić swój umysł. – EJP

Powiązane problemy