tl;dr
Die PGSimpleDataSource
-Klasse, die mit dem JDBC-Treiber von jdbc.postgresql.org gebündelt ist, implementiert DataSource
Schnittstelle. Konfigurieren Sie Ihre Datenbankverbindungsdetails in einer PGSimpleDataSource
-Objekt und als DataSource
herumreichen Objekt.
PGSimpleDataSource ds = new PGSimpleDataSource() ;
ds.setServerName( "localhost" );
ds.setDatabaseName( "your_db_name_here" );
ds.setUser( "scott" );
ds.setPassword( "tiger" );
Verwenden Sie dieses Objekt, um bei Bedarf eine Verbindung zur Datenbank herzustellen. Verwenden Sie die praktische Try-with-Ressourcen-Syntax.
try
(
Connection conn = ds.getConnection() ;
)
{ … }
Implementierung des JDBC-Treibers
Ihr JDBC-Treiber kann Ihnen eine Implementierung der DataSource
bereitstellen Schnittstelle.
Ein Objekt dieser Implementierung enthält die Informationen, die benötigt werden, um eine Verbindung zur Datenbank herzustellen und zu konfigurieren, wie zum Beispiel:
- Name und Passwort des Datenbankbenutzers
- IP-Adresse und Portnummer des Datenbankservers
Es können bis zu drei Arten von bereitgestellter Implementierung verfügbar sein:
- Oft ist eine solche Implementierung ein dünner Wrapper um den
DriverManager
. Jedes Mal, wenn SieDataSource::getConnection
aufrufen Aufgrund einer solchen Implementierung erhalten Sie eine neue Datenbankverbindung. - Alternativ kann eine Implementierung einen Verbindungspool darunter verwenden, um bereits vorhandene Verbindungen bereitzustellen. Diese Verbindungen werden ausgehändigt und wieder eingecheckt, wie Bücher in einer Bibliothek, um für den wiederholten Gebrauch recycelt zu werden.
- Eine Implementierung kann die Java-Transaktions-API unterstützen, die X/Open XA unterstützt, für anspruchsvolle Anforderungen wie die Koordination der Transaktionen über mehrere Ressourcen wie Datenbanken und Nachrichtenwarteschlangen hinweg. Nicht so häufig verwendet, daher ignoriere ich diesen Typ hier.
Treiber von jdbc.postgresql.org
Der kostenlose Open-Source-Treiber von jdbc.postgresql.org bietet alle drei Arten von DataSource
Implementierung. Die Autoren empfehlen jedoch nicht, ihren Verbindungspooltyp tatsächlich in der Produktion zu verwenden. Wenn Sie Pooling wünschen, verwenden Sie eine Verbindungspooling-Bibliothek eines Drittanbieters. Und wir ignorieren den Typ XA.
Schauen wir uns also die einfache Implementierung von DataSource
an, bei der jede Verbindung neu hergestellt wird :org.postgresql.ds.PGSimpleDataSource
Konfigurieren des Datenquellenobjekts
Instanziieren Sie ein leeres Objekt und rufen Sie dann eine Reihe von Setter-Methoden auf, um es für Ihr spezielles Datenbankszenario zu konfigurieren. Die Setter-Methoden werden von org.postgresql.ds.common.BaseDataSource
geerbt .
Wir führen noch kein Upcasting zur Schnittstelle DataSource
durch , damit wir die verschiedenen Setter-Methoden aufrufen können. Siehe Beispielcode und Diskussion auf der Seite Datenquellen und 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?
Im Allgemeinen würde ich diese separaten Setter-Methoden verwenden. Alternativ konstruieren Sie einen String, eine URL, mit den verschiedenen Informationen, die auf der DataSource
festgelegt werden sollen in einem Schlag. Wenn Sie diesen Weg gehen möchten, rufen Sie setUrl
auf .
Damit sind die Grundlagen abgedeckt. Aber vielleicht möchten oder brauchen Sie einige der anderen Setter. Die meisten davon setzen Postgres-Eigenschaftswerte auf dem Server. Die Eigenschaften haben alle intelligente Standardwerte, aber Sie können sie in besonderen Situationen überschreiben.
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.
Wenn Sie TLS (früher bekannt als SSL) verwenden, um die Datenbankverbindung zu verschlüsseln, um sie vor Abhören oder böswilliger Manipulation zu schützen, verwenden Sie dafür mehrere Setter.
Für jede Postgres-Eigenschaft ohne eine bestimmte Setter-Methode können Sie setProperty( PGProperty property, String value )
aufrufen .
Sie können die Einstellungen dieser Datenquelle überprüfen oder überprüfen, indem Sie eine der vielen Getter-Methoden aufrufen.
Nach der Konfiguration Ihrer PGSimpleDataSource
, können Sie einfach als DataSource
an den Rest Ihrer Codebasis übergeben Objekt. Dies schützt Ihre Codebasis vor dem Schock des Wechsels zu einer anderen DataSource
Implementierung oder Wechsel zu einem anderen JDBC-Treiber.
DataSource dataSource = ds ; // Upcasting from concrete class to interface.
return dataSource ;
Verwendung der Datenquelle
Verwenden einer DataSource
ist absolut einfach, da es nur zwei Methoden bereitstellt, ein Paar Variationen von getConnection
um eine Connection
herzustellen Objekt für Ihre Datenbankarbeit.
Connection conn = dataSource.getConnection() ;
Wenn Sie mit Ihrer Connection
fertig sind , ist es am besten, es zu schließen. Verwenden Sie entweder eine try-with-resources-Syntax, um die Verbindung automatisch zu schließen, oder schließen Sie sie explizit.
conn.close() ;
Denken Sie daran, dass eine DataSource
ist nicht wirklich eine Datenquelle. Eine DataSource
ist wirklich eine Quelle zum Generieren/Zugreifen auf Verbindungen zur Datenbank. Meiner Meinung nach ist dies eine falsche Bezeichnung, da ich es als ConnectionSource
betrachte . Die DataSource
spricht nur lange genug mit Ihrer Datenbank, um sich mit Benutzername und Passwort anzumelden. Nach dieser Anmeldung verwenden Sie die Connection
Objekt, um mit der Datenbank zu interagieren.
Speichern Ihrer DataSource
Nach der Konfiguration möchten Sie diese DataSource
beibehalten Objekt herum, zwischengespeichert. Keine Notwendigkeit, wiederholt neu zu konfigurieren. Die Implementierung sollte Thread-sicher geschrieben werden. Sie können getConnection
aufrufen jederzeit und überall.
Für eine einfache kleine Java-App möchten Sie sie vielleicht als Feld in einem Singleton oder in einer statischen globalen Variablen speichern.
Für eine Servlet-basierte Anwendung wie Vaadin app erstellen Sie eine Klasse, die ServletContextListener
implementiert Schnittstelle. In dieser Klasse würden Sie Ihre DataSource
einrichten -Objekt, wenn Ihre Web-App gestartet wird. Von dort würden Sie das Objekt im ServletContext
speichern Objekt durch Übergabe an setAttribute
. Context
ist der Fachbegriff für „Web-App“. Abrufen durch Aufrufen von getAttribute
und Casting in DataSource
.
In einem Unternehmensszenario ist die DataSource
kann in einer JNDI-kompatiblen Implementierung gespeichert werden. Einige Servlet-Container wie Apache Tomcat bieten möglicherweise eine JNDI-Implementierung. Einige Organisationen verwenden einen Server wie einen LDAP-Server. Registrieren und Abrufen Ihrer DataSource
Objekt mit JNDI wird in vielen anderen Fragen und Antworten zu Stack Overflow behandelt.