tl;dr
PGSimpleDataSource
klasa dołączona do sterownika JDBC z jdbc.postgresql.org implementuje DataSource
berło. Skonfiguruj szczegóły połączenia z bazą danych w PGSimpleDataSource
obiekt i przekazać jako DataSource
obiekt.
PGSimpleDataSource ds = new PGSimpleDataSource() ;
ds.setServerName( "localhost" );
ds.setDatabaseName( "your_db_name_here" );
ds.setUser( "scott" );
ds.setPassword( "tiger" );
Użyj tego obiektu, aby w razie potrzeby nawiązać połączenie z bazą danych. Użyj wygodnej składni try-with-resources.
try
(
Connection conn = ds.getConnection() ;
)
{ … }
Implementacja sterownika JDBC
Twój sterownik JDBC może zapewnić implementację DataSource
interfejs.
Obiekt tej implementacji zawiera informacje potrzebne do nawiązania i skonfigurowania połączenia z bazą danych, takie jak:
- Nazwa i hasło użytkownika bazy danych
- Adres IP i numer portu serwera bazy danych
Dostępne mogą być maksymalnie trzy rodzaje implementacji:
- Często taka implementacja jest cienkim opakowaniem wokół
DriverManager
. Za każdym razem, gdy dzwonisz doDataSource::getConnection
na obiekcie takiej implementacji otrzymujesz nowe połączenie z bazą danych. - Alternatywnie implementacja może wykorzystywać pulę połączeń poniżej do dostarczania już istniejących połączeń. Połączenia te są rozdawane i ponownie weryfikowane, jak książki w bibliotece, do ponownego wykorzystania w celu ponownego użycia.
- Implementacja może obsługiwać Java Transaction API, obsługującą X/Open XA, dla wyrafinowanych potrzeb, takich jak koordynacja transakcji w wielu zasobach, takich jak bazy danych i kolejki komunikatów. Nie tak powszechnie używane, więc ignoruję tutaj ten typ.
Sterownik z jdbc.postgresql.org
Darmowy sterownik open-source z jdbc.postgresql.org zapewnia wszystkie trzy typy DataSource
realizacja. Ale autorzy nie zalecają faktycznego używania ich typu puli połączeń w produkcji; jeśli chcesz puli, użyj biblioteki puli połączeń innej firmy. I ignorujemy typ XA.
Przyjrzyjmy się więc prostej implementacji DataSource
typu fresh-connect-each-time :org.postgresql.ds.PGSimpleDataSource
Konfigurowanie obiektu źródła danych
Utwórz wystąpienie pustego obiektu, a następnie wywołaj serię metod ustawiających w celu skonfigurowania dla konkretnego scenariusza bazy danych. Metody ustawiające są dziedziczone z org.postgresql.ds.common.BaseDataSource
.
Nie przesyłamy jeszcze do interfejsu DataSource
, dzięki czemu możemy wywoływać różne metody ustawiające. Zobacz przykładowy kod i dyskusję na stronie Źródła danych i JNDI.
PGSimpleDataSource ds = new PGSimpleDataSource() ; // Empty instance.
ds.setServerName( "localhost" ); // The value `localhost` means the Postgres cluster running locally on the same machine.
ds.setDatabaseName( "testdb" ); // A connection to Postgres must be made to a specific database rather than to the server as a whole. You likely have an initial database created named `public`.
ds.setUser( "testuser" ); // Or use the super-user 'postgres' for user name if you installed Postgres with defaults and have not yet created user(s) for your application.
ds.setPassword( "password" ); // You would not really use 'password' as a password, would you?
Generalnie używałbym tych oddzielnych metod ustawiających. Alternatywnie możesz skonstruować ciąg, adres URL, z różnymi fragmentami informacji, które mają być ustawione w DataSource
jednym pociągnięciem. Jeśli chcesz iść tą drogą, zadzwoń do setUrl
.
To obejmuje podstawy. Ale możesz chcieć lub potrzebować innych seterów. Większość z nich ustawia wartości właściwości Postgres na serwerze. Wszystkie właściwości mają inteligentne ustawienia domyślne, ale możesz chcieć je zastąpić w szczególnych sytuacjach.
ds.setPortNumber( 6787 ) ; // If not using the default '5432'.
ds.setApplicationName( "whatever" ) ; // Identify the application making this connection to the database. Also a clever way to back-door some information to the Postgres server, as you can encode small values into this string for later parsing.
ds.setConnectTimeout( … ) ; // The timeout value used for socket connect operations, in whole seconds. If connecting to the server takes longer than this value, the connection is broken.
ds.setSocketTimeout( … ) ; // The timeout value used for socket read operations. If reading from the server takes longer than this value, the connection is closed. This can be used as both a brute force global query timeout and a method of detecting network problems.
ds.setReadOnly( boolean ) ; // Puts this connection in read-only mode.
Jeśli używasz TLS (wcześniej znanego jako SSL) do szyfrowania połączenia z bazą danych w celu ochrony przed podsłuchiwaniem lub złośliwą manipulacją, użyj do tego kilku programów ustawiających.
W przypadku dowolnej właściwości Postgres bez określonej metody ustawiającej możesz wywołać setProperty( PGProperty property, String value )
.
Możesz sprawdzić lub zweryfikować ustawienia tego źródła danych, wywołując dowolną z wielu metod pobierania.
Po skonfigurowaniu PGSimpleDataSource
, możesz przekazać resztę swojego kodu jako po prostu DataSource
obiekt. To izoluje Twoją bazę kodu przed szokiem związanym z przejściem na inny DataSource
implementacja lub zmiana na inny sterownik JDBC.
DataSource dataSource = ds ; // Upcasting from concrete class to interface.
return dataSource ;
Korzystanie ze źródła danych
Korzystanie z DataSource
jest całkowicie proste, ponieważ zapewnia tylko dwie metody, parę wariacji getConnection
aby uzyskać Connection
obiekt do pracy z bazą danych.
Connection conn = dataSource.getConnection() ;
Po zakończeniu z Connection
, najlepiej jest go zamknąć. Użyj składni try-with-resources, aby automatycznie zamknąć połączenie, albo zamknij je jawnie.
conn.close() ;
Pamiętaj, że DataSource
nie jest w rzeczywistości źródłem danych. DataSource
jest naprawdę źródłem do generowania/dostępu do połączeń z bazą danych. Moim zdaniem jest to błędna nazwa, ponieważ myślę o niej jako o ConnectionSource
. DataSource
komunikuje się z bazą danych tylko na tyle długo, aby zalogować się przy użyciu nazwy użytkownika i hasła. Po tym logowaniu używasz Connection
obiekt do interakcji z bazą danych.
Przechowywanie DataSource
Po skonfigurowaniu chcesz zachować to DataSource
obiekt wokół, buforowany. Nie ma potrzeby wielokrotnego konfigurowania. Implementacja powinna być napisana tak, aby była bezpieczna dla wątków. Możesz zadzwonić do getConnection
zawsze i wszędzie.
W przypadku prostej małej aplikacji Java możesz chcieć przechowywać ją jako pole w pojedynczym lub w statycznej zmiennej globalnej.
W przypadku aplikacji opartej na serwletach, takiej jak Vaadin aplikacji, utworzyłbyś klasę implementującą ServletContextListener
berło. W tej klasie utworzyłbyś swoje DataSource
obiekt podczas uruchamiania aplikacji internetowej. Stamtąd możesz przechowywać obiekt w ServletContext
obiektu, przekazując do setAttribute
. Context
to termin techniczny oznaczający „aplikację internetową”. Pobierz, wywołując getAttribute
i przesyłanie do DataSource
.
W scenariuszu korporacyjnym DataSource
mogą być przechowywane w implementacji zgodnej z JNDI. Niektóre kontenery serwletów, takie jak Apache Tomcat, mogą udostępniać implementację JNDI. Niektóre organizacje używają serwera, takiego jak serwer LDAP. Rejestracja i pobieranie DataSource
obiekt z JNDI jest omówiony w wielu innych pytaniach i odpowiedziach na temat przepełnienia stosu.