web-dev-qa-db-ja.com

プログラムでPostgresJDBCの `DataSource`オブジェクトを生成します

JDBCチュートリアル は、DataSourceクラスを使用するのではなく、 DriverManager オブジェクトを使用してデータベース接続を取得することをお勧めします。 データソースオブジェクトとの接続 ページを引用するには:

DataSourceオブジェクト…データソースへの接続を取得するための推奨される手段。

[〜#〜] jdbc [〜#〜] Postgresへの接続用にそのようなオブジェクトを取得するにはどうすればよいですか? JDBCドライバーを配置しています。

今のところ、 thisthis のようにJNDIをいじりたくありません。

Javaアプリ内でプログラムでDataSourceをインスタンス化できますか?それとも、そのDataSourceインターフェースを自分で実装する必要がありますか?

7
Basil Bourque

JDBCドライバーの実装

JDBCドライバー は、 DataSource インターフェースの実装を提供する場合があります。

この実装のオブジェクトには、データベースへの接続を確立および構成するために必要な情報が含まれています。

  • データベースユーザーの名前とパスワード
  • データベースサーバーのIPアドレスとポート番号

提供される最大3種類の実装が利用可能です。

  • 多くの場合、このような実装は DriverManager の薄いラッパーです。このような実装のオブジェクトで _DataSource::getConnection_ を呼び出すたびに、新しいデータベース接続が取得されます。
  • あるいは、実装では、下に 接続プール を使用して、既存の接続を提供することもできます。これらの接続は、図書館の本のように配布されてチェックインされ、繰り返し使用するためにリサイクルされます。
  • 実装は、データベースやメッセージキューなどの複数のリソース間でトランザクションを調整するなどの高度なニーズに対応するために、 Java Transaction API をサポートし、 X/Open XA をサポートする場合があります。あまり一般的に使用されていないので、ここではこのタイプを無視します。

Jdbc.postgresql.orgのドライバー

jdbc.postgresql.org のオープンソースの無料ドライバーは、3種類すべてのDataSource実装を提供します。しかし、作者は実際に 接続プールタイプ を本番環境で使用することを推奨していません。プールが必要な場合は、サードパーティの接続プールライブラリを使用してください。そして、私たちは無視しています XAタイプ

それでは、DataSourceの単純なfresh-connection-each-time実装を見てみましょう: _org.postgresql.ds.PGSimpleDataSource_

データソースオブジェクトの構成

空のオブジェクトをインスタンス化してから、一連の セッターメソッド を呼び出して、特定のデータベースシナリオ用に構成します。セッターメソッドは _org.postgresql.ds.common.BaseDataSource_ から継承されます。

まだインターフェースDataSourceにアップキャストしていないので、 さまざまなセッターメソッド を呼び出すことができます。 データソースと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?
_

通常、私はこれらの個別のセッターメソッドを使用します。または、DataSourceに設定するさまざまな情報を1回のストロークで使用して文字列(URL)を作成します。そのルートに行きたい場合は、 setUrl に電話してください。

それは基本をカバーしています。しかし、他のセッターが必要な場合もあります。これらのほとんどは、サーバーに Postgresプロパティ 値を設定しています。すべてのプロパティにはスマートなデフォルトがありますが、特別な状況ではオーバーライドすることをお勧めします。

_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.
_

[〜#〜] tls [〜#〜] (以前はSSLと呼ばれていました)を使用してデータベース接続を暗号化し、盗聴や悪意のある操作から保護する場合は、いくつかのセッターを使用します。

特定のsetterメソッドのないPostgresプロパティの場合は、 setProperty( PGProperty property, String value ) を呼び出すことができます。

多くのgetterメソッドのいずれかを呼び出すことにより、このデータソースの設定を検査または検証できます。

PGSimpleDataSourceを構成した後、コードベースの残りの部分に単純に DataSource オブジェクトとして渡すことができます。これにより、コードベースが別のDataSource実装に変更したり、 別のJDBCドライバー に変更したりするショックから保護されます。

_DataSource dataSource = ds ;  // Upcasting from concrete class to interface.
return dataSource ; 
_

データソースの使用

DataSourceの使用は、2つのメソッド、つまり getConnection のバリエーションのペアを提供して Connectionを取得するため、非常に簡単です。 データベース作業のオブジェクト。

_Connection conn = dataSource.getConnection() ; 
_

Connectionを終了したら、必ず閉じることをお勧めします。 try-with-resources構文 を使用して接続を自動的に閉じるか、明示的に接続を閉じます。

_conn.close() ;
_

DataSourceは実際にはデータソースではないことを覚えておいてください。 DataSourceは、実際にはデータベースへの接続を生成/アクセスするためのソースです。私の考えでは、これはConnectionSourceと考えるので、誤った呼び方です。 DataSourceは、ユーザー名とパスワードを使用してサインインするのに十分な時間だけデータベースと通信します。サインイン後、Connectionオブジェクトを使用してデータベースを操作します。

DataSourceの保存

構成したら、そのDataSourceオブジェクトをキャッシュに残しておきます。繰り返し再構成する必要はありません。 実装はスレッドセーフになるように作成する必要があります 。いつでもどこからでもgetConnectionに電話できます。

単純な小さなJavaアプリの場合、シングルトンまたは静的グローバル変数のフィールドとして保存することをお勧めします。

Vaadin アプリなどの サーブレット ベースのアプリの場合、実装するクラスを作成しますServletContextListenerインターフェース。そのクラスでは、Webアプリの起動時にDataSourceオブジェクトを確立します。そこから、 ServletContext に渡すことにより、オブジェクトを setAttribute オブジェクトに格納します。 Contextは、「Webアプリ」の専門用語です。 getAttributeを呼び出し、DataSourceにキャストして取得します。

エンタープライズシナリオでは、DataSource[〜#〜] jndi [〜#〜] 準拠の実装に格納される場合があります。 Apache Tomcat などの一部の サーブレットコンテナ は、JNDI実装を提供する場合があります。一部の組織では、 LDAPサーバー などのサーバーを使用しています。 DataSourceオブジェクトをJNDIに登録および取得する方法については、StackOverflowに関する他の多くの質問と回答で説明しています。

13
Basil Bourque