意外と触ってないと忘れるJavaでPostgreSQL JDBC Driverを使ってPostgreSQLに接続するJavaプログラムについてインフラな私が解説します。

今回はAzureでLinuxでRHELでやります。

1.環境

・ Azure VM
・ OS : RHEL8
・ロケールセット : 日本語
・ DB : Azure for PostgresSQL Database

2.環境準備

早速、Javaを実行できる環境の準備からいきます。
※ AzureのVM作成は省略します。

2-1.ルート権限に切り替え

まずは、ルート権限に切り替えます。
※ 趣味ならこれでもいいですが、仕事でやるときはセキュリティ要件とかポリシー廻りなどは
事前に確認しましょう。

$ sudo su

2-2.OpenJDKのインストール

今回は無料で使えるOpenJDKを使います。
個人開発とか検証ならこれで十分だと思います。

# yum -y install java-1.8.0-openjdk-devel

Red Hat Ansible Engine 2 for RHEL 8 x86_64 (RPMs) from RHUI                                        13 kB/s | 4.0 kB     00:00    
Red Hat Enterprise Linux 8 for x86_64 - BaseOS from RHUI (RPMs)                                    12 kB/s | 4.1 kB     00:00    
Red Hat CodeReady Linux Builder for RHEL 8 x86_64 (RPMs) from RHUI                                 15 kB/s | 4.5 kB     00:00    
Red Hat Enterprise Linux 8 for x86_64 - Supplementary (RPMs) from RHUI                             12 kB/s | 3.8 kB     00:00    
Red Hat Enterprise Linux 8 for x86_64 - AppStream from RHUI (RPMs)                                 15 kB/s | 4.5 kB     00:00    
パッケージ java-1.8.0-openjdk-devel-1:1.8.0.412.b08-2.el8.x86_64 は既にインストールされています。
依存関係が解決しました。
行うべきことはありません。
完了しました!

このコマンドは、yumパッケージマネージャーを使用してJavaのOpenJDK 1.8.0の開発ツール(ディベロッパーパッケージ)をインストールするためのものです。

-y” はyumコマンドのオプションです。
このオプションを指定することでインストール操作を確認せずに行うオプションです。

インストールが完了したら”java -version”コマンドを使ってJavaがインストールされたことを確認
します。

# java -version
openjdk version "1.8.0_412"
OpenJDK Runtime Environment (build 1.8.0_412-b08)
OpenJDK 64-Bit Server VM (build 25.412-b08, mixed mode)

試しに何か適当にベーシックなJavaプログラムを作ってコンパイルして実行してみます。
適当な名前でJavaのプロジェクトディレクトリを作成し”cd”コマンドで移動します。
※ コマンドの途中で”&&”で繋げると続けてコマンドを実行できます。

# mkdir program && cd program

“TestJava.java”ファイルをエディタで編集し保存して閉じます。
※ 私はVimを使いましたがnanoでもなんでもいいです。

# vi TestJava.java
public class TestJava {
  public static void main(String[] args) {
     // Hello,Worldを出力
     System.out.println("Hello,World");
   }
}

ファイルを作ることができたら、コンパイルのコマンドを打ちます。
(例) “javac “作成したファイル名”

# javac TestJava.java
# ls
TestJava.class  TestJava.java

classファイルが作成されたので続けて”java TestJava”を実行します。

# java TestJava
Hello,World

無事にJavaファイルをコンパイルしてclassファイルの実行までできました。
これでJavaを実行する環境としてはOKです。

次は、今回やってみるJavaをPostgreSQLに繋ぐためのDriverをインストールします。

2-3.Java、PostgreSQL JDBC Driverのインストール

次のコマンドを実行してJava PostgreSQL JDBC Driverをインストールします。

# yum -y install postgresql-jdbc

メタデータの期限切れの最終確認: 0:18:57 時間前の 2024年05月14日 13時29分36秒 に実施しました。
依存関係が解決しました。
===========================================================================================================
 パッケージ              Arch       バージョン             リポジトリー                              サイズ
===========================================================================================================
インストール:
 postgresql-jdbc         noarch     42.2.14-3.el8_9        rhel-8-for-x86_64-appstream-rhui-rpms     754 k
依存関係のインストール:
 ongres-scram            noarch     1.0.0~beta.2-5.el8     rhel-8-for-x86_64-appstream-rhui-rpms      46 k
 ongres-scram-client     noarch     1.0.0~beta.2-5.el8     rhel-8-for-x86_64-appstream-rhui-rpms      24 k

トランザクションの概要
===========================================================================================================
インストール  3 パッケージ

ダウンロードサイズの合計: 825 k
インストール後のサイズ: 858 k
パッケージのダウンロード:
(1/3): ongres-scram-client-1.0.0~beta.2-5.el8.noarch.rpm                    64 kB/s |  24 kB     00:00    
(2/3): ongres-scram-1.0.0~beta.2-5.el8.noarch.rpm                          116 kB/s |  46 kB     00:00    
(3/3): postgresql-jdbc-42.2.14-3.el8_9.noarch.rpm                          1.2 MB/s | 754 kB     00:00    
-----------------------------------------------------------------------------------------------------------
合計                                                                       1.3 MB/s | 825 kB     00:00     
トランザクションの確認を実行中
トランザクションの確認に成功しました。
トランザクションのテストを実行中
トランザクションのテストに成功しました。
トランザクションを実行中
  準備             :                                                                                   1/1 
  インストール中   : ongres-scram-1.0.0~beta.2-5.el8.noarch                                            1/3 
  インストール中   : ongres-scram-client-1.0.0~beta.2-5.el8.noarch                                     2/3 
  インストール中   : postgresql-jdbc-42.2.14-3.el8_9.noarch                                            3/3 
  検証             : ongres-scram-client-1.0.0~beta.2-5.el8.noarch                                     1/3 
  検証             : ongres-scram-1.0.0~beta.2-5.el8.noarch                                            2/3 
  検証             : postgresql-jdbc-42.2.14-3.el8_9.noarch                                            3/3 
インストール済みの製品が更新されています。

インストール済み:
  ongres-scram-1.0.0~beta.2-5.el8.noarch           ongres-scram-client-1.0.0~beta.2-5.el8.noarch          
  postgresql-jdbc-42.2.14-3.el8_9.noarch          

完了しました!

このコマンドは、yumパッケージマネージャーを使用してPostgreSQL JDBCドライバをインストールするためのものです。

-y” はyumコマンドのオプションです。
このオプションを指定することでインストール操作を確認せずに行うオプションです。
※ 初めてインストールするパッケージやモジュールなどは”-y”は付けずに実行しましょう。

2-4.PostgreSQLに接続するJavaプログラムの作成

JDBC Driverをインストールできたので次はPostgreSQLに接続するためのテスト用プログラムを
作ります。※ 予めAzure for PostgresSQL Databaseを作成し”test”テーブルを作成しています。

import java.sql.*;

public class TestJDBC {
    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rset = null;

        String url = "jdbc:postgresql://ホスト:ポート/データベース名";
        String user = "ユーザー名";
        String password = "パスワード";

        try {
            // データベースへの接続
            conn = DriverManager.getConnection(url, user, password);
            stmt = conn.createStatement();

            // テーブル一覧を取得するSQLクエリを作成
            String sql = "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'";
            // SQLクエリを実行して結果を取得
            rset = stmt.executeQuery(sql);

            // 取得したテーブル一覧を表示
            System.out.println("Existing tables in the database:");
            while (rset.next()) {
                String tableName = rset.getString(1);
                System.out.println(tableName);
            }
        } catch (SQLException e) {
            // 例外が発生した場合はエラーを出力
            e.printStackTrace();
        } finally {
            // クローズ処理
            try {
                if (rset != null) rset.close();
                if (stmt != null) stmt.close();
                if (conn != null) conn.close();
            } catch (SQLException e) {
                // クローズ処理で例外が発生した場合はエラーを出力
                e.printStackTrace();
            }
        }
    }
}

これで”コンパイルして接続できました!”だと勉強にならないので以下に説明を書きますw

「各コードブロックに関連する処理の説明」

  1. JDBCドライバのロード: import java.sql.*;でJavaのSQLパッケージをインポートし、PostgreSQLへの接続に必要なクラスを使用できるようにします。
  2. 変数の初期化: Connection, Statement, ResultSetの3つの変数を宣言しています。これらは、それぞれデータベース接続、SQLステートメントの実行、結果セットの取得に使用されます。
  3. データベースへの接続: DriverManager.getConnection(url, user, password);で、指定されたURL、ユーザー名、パスワードを使用してPostgreSQLデータベースに接続します。
  4. ステートメントの作成: conn.createStatement();で、データベース上でSQLステートメントを実行するためのStatementオブジェクトを作成します。
  5. SQLクエリの実行: stmt.executeQuery(sql);で、指定されたSQLクエリを実行し、結果をResultSetオブジェクトに格納します。
  6. 結果の取得と表示: rset.next()rset.getString(1)を使用して、結果セットからテーブル名を1つずつ取得し、それをコンソールに出力します。
  7. 例外処理: try-catch-finallyブロックを使用して、SQLExceptionが発生した場合や、リソースの解放処理が正しく行われるようにします。

このコードの処理の流れは次のようになります。

  1. Connection, Statement, ResultSetの3つの変数を初期化します。これらは、データベース接続、SQLステートメントの実行、結果セットの処理に使用されます。
  2. PostgreSQLデータベースに接続するためのURL、ユーザー名、パスワードを指定してDriverManager.getConnection(url, user, password)を使用して接続します。
  3. conn.createStatement()を使用して、データベース上でSQLステートメントを実行するためのStatementオブジェクトを作成します。
  4. SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'というSQLクエリを実行して、”public”スキーマ内のテーブルの一覧を取得します。
  5. 取得したテーブル一覧をループで処理し、それぞれのテーブル名を取得してコンソールに出力します。
  6. 例外処理として、try-catchブロックを使用して、SQLの実行中に例外が発生した場合にエラーをキャッチして出力します。
  7. finallyブロックを使用して、ResultSet, Statement, Connectionなどのリソースをクローズします。

以上がコードブロックごとの説明と、コード処理の流れのざっとした説明です。
もう少し細かくみましょう。

2-4-1.たかがimport、されどimport


最初にimportの文でJavaのSQLパッケージをインポートしています。
今回は”import java.sql*;”と省略して以下のように書きました。

import java.sql.*;


え、こんなに短いならこれでいいじゃん‼️ と思うかもしれませんが

もちろん、メリットデメリットがあります。

こちらの書き方はまず以下のメリットがあります。

 ①見た目通り簡潔に書くことができる。
 ②他のクラスも一括してインポートされるため、クラス名だけでなくメソッド名なども短く書ける。

デメリットとしては

 ①必要のないクラスもインポートされるため、メモリ使用量が増える可能性がある。
 ②コードの可読性が低下する可能性がある。

一方で以下のように細かく書くこともできます。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

めちゃくちゃ多いですよね😅
本来はこうやって書いたほうが以下のメリットがあります。

メリット
 ①使用しているクラスが明確になるため、コードの可読性が向上する。
②必要なクラスのみがインポートされるため、メモリ使用量が削減される。

当然デメリットもあって言わずもなが、”インポートするクラスが多い場合は冗長になる”可能性があります。

import文を一つとってもここまで考えでコーディングできるかどうか大切なことだと思います。

2-4-2.変数が null で初期化されているのはなあぜなあぜ?

コピペした人も書いてる人も不思議に思ったかもしれません。なぜ、変数に”null”が入ってるのか?

Connection conn = null;
Statement stmt = null;
ResultSet rset = null;

これらの変数が最初に “null" で初期化されているのは、それぞれが後でリソース(Connection、Statement、ResultSet)を参照するためのポインタとして使用されるためです。

Javaでは、変数を明示的に初期化しないとコンパイルエラーが発生するため、これらの変数を null で初期化しています。実際のリソースが確保されると、それらの変数は適切なオブジェクトに参照が更新されます。ただし、エラーが発生した場合などに備えて、 finally ブロックでこれらのリソースをクローズする前に変数が null であることを確認することが重要です。

2-5.コンパイルしてPostgreSQLに接続してみる(笑)

ここまで長かった・・・。すいません。
早速コンパイルして接続を試したいと思います!

# ls
TestJDBC.java  TestJava.class  TestJava.java

# javac TestJDBC.java
# ls
TestJDBC.class  TestJDBC.java  TestJava.class  TestJava.java

実行します。


今回はPostgres JDBCのクラスファイルを指定した状態で実行したいため以下のコマンドで実行します。
ここがポイントだと思います。

 # java -cp .:/usr/share/java/postgresql-jdbc.jar TestJDBC

このコマンドは、Javaアプリケーションを実行するための基本的なコマンドに”-cp”オプションを付けて
PostgreSQL JDBC Driverのjarのパスを指定しJavaを実行しています。

-cpはclasspathの略で、ここでは2つのディレクトリまたはJARファイルをパスに含めることを指示しています。

つまり、このコマンドは現在のディレクトリとPostgreSQLのJDBCドライバをクラスパスに追加してTestJDBCクラスを実行しています。

実行結果

# java -cp .:/usr/share/java/postgresql-jdbc.jar TestJDBC
Existing tables in the database:
test_table
test2_table

無事にAzure Linux RHELにJava実行環境を構築しJavaプログラムからPostgreSQLに繋いでSQLクエリを投げ結果を出力することができました。

3.終わりに


Javaを触っていない方だと意外と細かいところでわからないことが多々あるかと思います。
僕自身があんまりJavaを触ってないのですが、今回は勉強のために記録しました。

誰かの役に立てれば幸いです。
ここまでお読みいただき、ありがとうございました!


投稿者 izumi kikumura

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です