tl;dr
Il PGSimpleDataSource
la classe in bundle con il driver JDBC da jdbc.postgresql.org implementa DataSource
interfaccia. Configura i dettagli della connessione al database in un PGSimpleDataSource
oggetto e passare come DataSource
oggetto.
PGSimpleDataSource ds = new PGSimpleDataSource() ;
ds.setServerName( "localhost" );
ds.setDatabaseName( "your_db_name_here" );
ds.setUser( "scott" );
ds.setPassword( "tiger" );
Utilizzare quell'oggetto per stabilire una connessione al database secondo necessità. Usa la comoda sintassi Prova con le risorse.
try
(
Connection conn = ds.getConnection() ;
)
{ … }
Implementazione del driver JDBC
Il tuo driver JDBC potrebbe fornirti un'implementazione del DataSource
interfaccia.
Un oggetto di questa implementazione contiene le informazioni necessarie per effettuare e configurare una connessione al database, come ad esempio:
- Nome e password dell'utente del database
- Indirizzo IP e numero di porta del server di database
Possono essere disponibili fino a tre tipi di implementazione forniti:
- Spesso una tale implementazione è un sottile involucro attorno al
DriverManager
. Ogni volta che chiamiDataSource::getConnection
sull'oggetto di tale implementazione, ottieni una nuova connessione al database. - In alternativa, un'implementazione potrebbe utilizzare un pool di connessioni sottostante per fornire connessioni già esistenti. Queste connessioni vengono distribuite e archiviate, come i libri in una biblioteca, per essere riciclate per un uso ripetuto.
- Un'implementazione può supportare Java Transaction API, supportando X/Open XA, per esigenze sofisticate come il coordinamento delle transazioni su più risorse come database e code di messaggi. Non è comunemente usato, quindi ignoro questo tipo qui.
Driver da jdbc.postgresql.org
Il driver gratuito open source di jdbc.postgresql.org fornisce tutti e tre i tipi di DataSource
implementazione. Ma gli autori sconsigliano di utilizzare effettivamente il loro tipo di pool di connessioni in produzione; se si desidera il pool, utilizzare una libreria di pool di connessioni di terze parti. E stiamo ignorando il tipo XA.
Diamo quindi un'occhiata alla semplice implementazione della nuova connessione ogni volta di DataSource
:org.postgresql.ds.PGSimpleDataSource
Configurazione dell'oggetto origine dati
Crea un'istanza di un oggetto vuoto, quindi chiama una serie di metodi setter da configurare per il tuo particolare scenario di database. I metodi setter sono ereditati da org.postgresql.ds.common.BaseDataSource
.
Non stiamo ancora eseguendo l'upcast all'interfaccia DataSource
, in modo da poter chiamare i vari metodi setter. Vedi codice di esempio e discussione nella pagina Fonti dati e 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?
Generalmente userei questi metodi di setter separati. In alternativa, costruisci una String, un URL, con le varie informazioni da impostare sul DataSource
in un colpo. Se vuoi seguire quella strada, chiama setUrl
.
Questo copre le basi. Ma potresti voler o aver bisogno di alcuni degli altri setter. La maggior parte di questi impostano i valori delle proprietà Postgres sul server. Le proprietà hanno tutte impostazioni predefinite intelligenti, ma potresti voler sovrascrivere per situazioni speciali.
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.
Se si utilizza TLS (precedentemente noto come SSL) per crittografare la connessione al database per proteggersi da intercettazioni o manipolazioni malevole, utilizzare diversi setter per questo.
Per qualsiasi proprietà Postgres senza un metodo setter specifico, puoi chiamare setProperty( PGProperty property, String value )
.
Puoi controllare o verificare le impostazioni su questa origine dati chiamando uno dei tanti metodi getter.
Dopo aver configurato il tuo PGSimpleDataSource
, puoi passare al resto della tua base di codice semplicemente come un DataSource
oggetto. Questo isola la tua base di codice dallo shock di passare a un altro DataSource
implementazione o passaggio a un altro driver JDBC.
DataSource dataSource = ds ; // Upcasting from concrete class to interface.
return dataSource ;
Utilizzo dell'origine dati
Utilizzando un DataSource
è assolutamente semplice in quanto fornisce solo due metodi, un paio di variazioni su getConnection
per ottenere una Connection
oggetto per il tuo lavoro nel database.
Connection conn = dataSource.getConnection() ;
Al termine della tua Connection
, la migliore pratica è assicurarsi di chiuderlo. Utilizza una sintassi Prova con le risorse per chiudere automaticamente la connessione o chiuderla in modo esplicito.
conn.close() ;
Tieni a mente che un DataSource
non è in realtà una fonte di dati. Un DataSource
è davvero una fonte per generare/accedere alle connessioni al database. A mio avviso, questo è un termine improprio, poiché lo considero ConnectionSource
. Il DataSource
comunica con il tuo database solo il tempo necessario per accedere con nome utente e password. Dopo aver effettuato l'accesso, utilizzerai la Connection
oggetto per interagire con il database.
Memorizzare il tuo DataSource
Una volta configurato, vuoi mantenere quel DataSource
oggetto in giro, memorizzato nella cache. Non è necessario riconfigurare ripetutamente. L'implementazione deve essere scritta per essere thread-safe. Puoi chiamare getConnection
in qualsiasi momento da qualsiasi luogo.
Per una semplice piccola app Java, potresti volerla archiviare come campo su un singleton o in una variabile globale statica.
Per un'app basata su servlet come un Vaadin app, creeresti una classe che implementa ServletContextListener
interfaccia. In quella classe stabilirai il tuo DataSource
oggetto all'avvio dell'app Web. Da lì memorizzeresti l'oggetto nel ServletContext
oggetto passando a setAttribute
. Context
è il termine tecnico per "app web". Recupera chiamando getAttribute
e trasmettere a DataSource
.
In uno scenario aziendale, il DataSource
possono essere archiviati in un'implementazione conforme a JNDI. Alcuni container servlet come Apache Tomcat possono fornire un'implementazione JNDI. Alcune organizzazioni utilizzano un server come un server LDAP. Registrazione e recupero del tuo DataSource
oggetto con JNDI è trattato in molte altre domande e risposte su Stack Overflow.