tl;dr
PGSimpleDataSource
klass buntad med JDBC-drivrutinen från jdbc.postgresql.org implementerar DataSource
gränssnitt. Konfigurera dina databasanslutningsdetaljer i en PGSimpleDataSource
objekt och skicka runt som en DataSource
objekt.
PGSimpleDataSource ds = new PGSimpleDataSource() ;
ds.setServerName( "localhost" );
ds.setDatabaseName( "your_db_name_here" );
ds.setUser( "scott" );
ds.setPassword( "tiger" );
Använd det objektet för att göra en anslutning till databasen efter behov. Använd praktisk syntax för att prova med resurser.
try
(
Connection conn = ds.getConnection() ;
)
{ … }
JDBC-drivrutinens implementering
Din JDBC-drivrutin kan ge dig en implementering av DataSource
gränssnitt.
Ett objekt för denna implementering innehåller informationen som behövs för att skapa och konfigurera en anslutning till databasen, såsom:
- Namn och lösenord för databasanvändaren
- IP-adress och portnummer för databasserver
Upp till tre typer av implementering kan vara tillgängliga:
- Ofta är en sådan implementering ett tunt omslag runt
DriverManager
. Varje gång du ringerDataSource::getConnection
på objektet för en sådan implementering får du en ny databasanslutning. - Alternativt kan en implementering använda en anslutningspool under för att tillhandahålla redan existerande anslutningar. Dessa anslutningar delas ut och checkas in igen, som böcker i ett bibliotek, för att återvinnas för upprepad användning.
- En implementering kan stödja Java Transaction API, som stöder X/Open XA, för sofistikerade behov som att koordinera transaktionerna över flera resurser som databaser och meddelandeköer. Inte lika vanligt, så jag ignorerar den här typen här.
Drivrutin från jdbc.postgresql.org
Den kostnadsfria drivrutinen med öppen källkod från jdbc.postgresql.org tillhandahåller alla tre typerna av DataSource
genomförande. Men författarna rekommenderar inte att man faktiskt använder sin anslutningspooltyp i produktionen; om du vill poola, använd ett tredjeparts anslutningspoolningsbibliotek. Och vi ignorerar XA-typen.
Så låt oss titta på den enkla nya-anslutning-varje gång-implementeringen av DataSource
:org.postgresql.ds.PGSimpleDataSource
Konfigurera datakällobjektet
Instantiera ett tomt objekt och anropa sedan en serie sättermetoder för att konfigurera för ditt specifika databasscenario. Settermetoderna ärvs från org.postgresql.ds.common.BaseDataSource
.
Vi uppdaterar ännu inte till gränssnittet DataSource
, så att vi kan kalla de olika sättermetoderna. Se exempelkod och diskussion på sidan Datakällor och 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?
I allmänhet skulle jag använda dessa separata sättermetoder. Alternativt konstruerar du en sträng, en URL, med de olika informationsbitarna som ska ställas in på DataSource
i ett slag. Om du vill gå den vägen, ring setUrl
.
Det täcker grunderna. Men du kanske vill eller behöver några av de andra sättarna. De flesta av dessa ställer in Postgres-egenskapsvärden på servern. Egenskaperna har alla smarta standardinställningar, men du kanske vill åsidosätta för speciella situationer.
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.
Om du använder TLS (tidigare känt som SSL) för att kryptera databasanslutningen för att skydda mot avlyssning eller illvillig manipulation, använd flera sättare för det.
För alla Postgres-egenskaper utan en specifik sättermetod kan du anropa setProperty( PGProperty property, String value )
.
Du kan inspektera eller verifiera inställningarna på denna datakälla genom att anropa någon av de många getter-metoderna.
Efter att ha konfigurerat din PGSimpleDataSource
, kan du skicka vidare till resten av din kodbas som helt enkelt en DataSource
objekt. Detta isolerar din kodbas från chocken av att byta till en annan DataSource
implementering eller ändring till en annan JDBC-drivrutin.
DataSource dataSource = ds ; // Upcasting from concrete class to interface.
return dataSource ;
Använda datakällan
Använda en DataSource
är helt enkelt eftersom det bara tillhandahåller två metoder, ett par varianter av getConnection
för att få en Connection
objekt för ditt databasarbete.
Connection conn = dataSource.getConnection() ;
När du är klar med din Connection
, bästa praxis är att se till att stänga den. Använd antingen syntaxen försök med resurser för att automatiskt stänga anslutningen, eller stäng den uttryckligen.
conn.close() ;
Tänk på att en DataSource
är faktiskt inte en datakälla. En DataSource
är verkligen en källa för att generera/åtkomst till anslutningar till databasen. Enligt min mening är detta en felaktig benämning, eftersom jag ser det som ConnectionSource
. DataSource
pratar med din databas bara tillräckligt länge för att logga in med användarnamn och lösenord. Efter den inloggningen använder du Connection
objekt för att interagera med databasen.
Lagra din DataSource
När du väl har konfigurerat den vill du behålla DataSource
objekt runt, cachad. Du behöver inte konfigurera om flera gånger. Implementeringen bör skrivas för att vara trådsäker. Du kan ringa getConnection
när som helst från var som helst.
För en enkel liten Java-app kanske du vill lagra den som ett fält på en singleton eller i en statisk global variabel.
För en Servlet-baserad app som en Vaadin app, skulle du skapa en klass som implementerar ServletContextListener
gränssnitt. I den klassen skulle du skapa din DataSource
objekt när din webbapp startar. Därifrån skulle du lagra objektet i ServletContext
objekt genom att skicka till setAttribute
. Context
är den tekniska termen för 'webbapp'. Hämta genom att anropa getAttribute
och casta till DataSource
.
I ett företagsscenario är DataSource
kan lagras i en JNDI-kompatibel implementering. Vissa Servlet-behållare som Apache Tomcat kan tillhandahålla en JNDI-implementering. Vissa organisationer använder en server som en LDAP-server. Registrera och hämta din DataSource
objekt med JNDI täcks av många andra frågor och svar på Stack Overflow.