LoginSignup
3
11

More than 3 years have passed since last update.

PostgreSQLをJavaで動かす

Last updated at Posted at 2019-07-23

JavaでPostgreSQLを動かしてみる。

環境

  • macOS Mojave
  • Eclipse 4.7.3
  • PostgreSQL 11.4
  • JDBC Driver 42.2.5(postgresql-42.2.5.jar)

JDBC Driverの導入

PostgreSQLのRDBにアクセスするためのJavaの標準APIとしてJDBCドライバが必要となる。

まずはそのダウンロードから。

https://jdbc.postgresql.org/download.html#current

ここでは postgresql-42.2.5.jar を使用する。

それを今回のプロジェクト下の任意の場所に配置する(lib/の中が分かりやすい?)

スクリーンショット 2019-07-23 16.28.17.png

しかしこのままではどこを参照しているのかが分からないのでパスを設定する必要がある。

macであれば

postgresql-42.2.5.jarをクリックしてプロジェクトタブ --> プロパティ --> Javaのビルドパス --> ライブラリ --> 外部JARの追加 --> postgresql-42.2.5.jarを探してopen --> 適用して閉じる

で参照ライブラリの中にpostgresql-42.2.5.jarが参照されていたらOK

スクリーンショット 2019-07-23 16.41.34.png

使用するDB

今回は全て以前使用したものを再利用していく。

ユーザーは以下の通り

terminal
customer=# \l
                                List of databases
   Name    |    Owner    | Encoding | Collate | Ctype |   Access privileges   
-----------+-------------+----------+---------+-------+-----------------------
 customer  | sf213471118 | UTF8     | C       | C     | 

テーブルはcustomerテーブルを使用する

terminal
customer=# \d
          List of relations
 Schema |   Name   | Type  |    Owner   
--------+----------+-------+-------------
 public | customer | table | sf213471118

customerテーブルの中身は以下の通り

terminal
customer=# SELECT * FROM customer;
       id        |   name   | gender | age 
-----------------+----------+--------+-----
 10001           | 田中太郎 | m       |  31
 10002           | 中村花子 | w       |  44
 10003           | 佐藤一郎 | m       |  20
 10004           | 内田彩   | w       |  18
 10005           | 高橋次郎 | m       |  56
 10006           | 中里悟   | m       |  34
(6 rows)

Javaの記述における大事な部分

記述していく上で忘れないようにしたいところを残しておく。

例外処理

.java
   public static void main(String[] args) throws Exception {
      try {
          System.out.println("DB access start");
          PostgreSQL_test.dbConnect();
      } catch (Exception e) {
          System.out.println("error main()");
          e.printStackTrace();
      } finally {
          System.out.println("DB access finished");
      }
   }

例外処理はtry-catch(-finally)で記述する。

この例だとException eとしているためエラーの場所しか特定できないが、catchの条件を変えて並列記述することでエラー内容を瞬時に把握することも可能。

例えば

.java
try {
    file_reader = new FileReader(customer);
    ~
  } catch (FileNotFoundException f) {          // ファイル探索エラー
    System.out.println("cannot find file");
    f.printStackTrace();
  } catch (IOException i) {                    //ファイル入出力エラー
    System.out.println("in/out error");
    i.printStackTrace();
  } finally {
    try {
      if(file_reader != null) {
        file_reader.close();
      }
    } catch (IOException i) {                  //ファイルclose中エラー
      System.out.println(i);
      i.printStackTrace();
    }
  }

というフローがあったとして、

try - catch - catchのほう

  • new FileReader(customer)をしたがそのファイル名が見つからないとき
  • customerファイルはあるが出力できなかったとき

の2つを考慮して分岐してある。

finally - try - catchのほう

  • close中のエラー

のみ検出している。

例外処理はFileNotFoundExceptionIOException以外にも沢山あるが、Exceptionとすれば全てのエラーを引っ掛けることができる(2つ上のプログラムの通り場所の特定くらいしか思いつかないが。。。)

DB接続に向けて

JDBCの初期化

DBに接続する前にJDBCドライバを初期化する必要がある。

PostgreSQLの場合は以下のように記述する

.java
Class.forName("org.postgresql.Driver").newInstance();

DB接続の確立/DB切断

またDBの接続を確立させるためにDriverManagerクラスが標準で持っているgetConnectionメソッドを使用する必要がある。

.java
connection = DriverManager.getConnection( <URL> , <USER>, <PASSWORD>);

URLに関してはjdbc:postgresql://<場所>:<ポート番号>/<DB名>で表記する。

今回は以下で設定した。

場所 ポート番号 DB名
localhost 5432 customer

切断に関しては、万が一のことも考えてfinallyで行うようにする。

.java
rs.close();    //rsはResultSetインターフェースの変数

SQL文の記述

SQLをDBに送るときには、まずConnectionインターフェースで定義されているcreateStatementメソッドを使用してステートメントを作成する必要がある(SQLを送るときに必ずセットで記述するもの)

.java
statement = con.createStatement();

上記が終わったらSQL文を問い合わせる記述をする

.java
resultset = stm.executeQuery(" <SQL文> ");

データの出力

ResultSetインターフェースのnext()メソッドで1行づつ処理を行うことができる。

.java
while (rs.next()) {
   System.out.println(rs.getInt("<column>"));
     System.out.println(rs.getString("<column>"));
}

今回のJava記述

PostgreSQL_test.java
package customer;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class PostgreSQL_test {

   public static void main(String[] args) throws Exception {
      try {
          System.out.println("DB access start");
          PostgreSQL_test.dbConnect();
      } catch (Exception e) {
          System.out.println("error main()");
          e.printStackTrace();
      } finally {
          System.out.println("DB access finished");
      }
   }

   private static void dbConnect() throws Exception {
      Connection con = null;
      Statement stm = null;
      ResultSet rs = null;
      int num = 1;

      String url        = "jdbc:postgresql://localhost:5432/customer";
      String user       = "sf213471118";
      String password   = "";          //今回パスワードは設定していない

      try {
         Class.forName("org.postgresql.Driver").newInstance();
         con = DriverManager.getConnection(url, user, password);
         stm = con.createStatement();
         rs = stm.executeQuery("SELECT * FROM customer");
         while (rs.next()) {
             System.out.println("[" + num + " 件目]");
             num++;
             System.out.println("id     : " + rs.getString("id"));
             System.out.println("name   : " + rs.getString("name"));
             System.out.println("gender : " + rs.getString("gender"));
             System.out.println("age    : " + rs.getInt("age"));
         }
      } catch(SQLException e) {
          System.out.println("error dbConnect()");
          e.printStackTrace();
        }finally {
            try {
                if ((rs != null)||(stm != null)||(con != null)) {
                    rs.close();
                }
            } catch (Exception e) {
                 e.printStackTrace();
            }
        }
      }
}

これを動かすと、以下が返ってくる。

JavaConsole
DB access start
[1 件目]
id     : 10001         
name   : 田中太郎
gender : m  
age    : 31
[2 件目]
id     : 10002          
name   : 中村花子
gender : w  
age    : 44
[3 件目]
id     : 10003          
name   : 佐藤一郎
gender : m  
age    : 20
[4 件目]
id     : 10004          
name   : 内田彩
gender : w  
age    : 18
[5 件目]
id     : 10005          
name   : 高橋次郎
gender : m  
age    : 56
[6 件目]
id     : 10006          
name   : 中里悟
gender : m  
age    : 34
DB access finished

本当であればrs.next()で現在の件数名を出力したかったのだが、よく分からなかったので姑息な手で出力してしまった。。。

どなたかやり方を教えていただけるととても嬉しいです

【追記】 2019/7/29

コメントを下さりありがとうございます。以下の通り修正しました。

①ループの部分の試行回数をrs.getRow()で受取り

PostgreSQL_test.java
    while (rs.next()) {
         System.out.println("[" + rs.getRow() + " 件目]");        /* 修正部分 */
         System.out.println("id     : " + rs.getString("id"));
         System.out.println("name   : " + rs.getString("name"));
         System.out.println("gender : " + rs.getString("gender"));
         System.out.println("age    : " + rs.getInt("age"));
    }

②close漏れを修正しました

PostgreSQL_test.java
     try {
         if ((rs != null)||(stm != null)||(con != null)) {
             rs.close();
             stm.close();      /* 修正部分 */
             con.close();      /* 修正部分 */
          }
      } catch (Exception e) {
                 e.printStackTrace();
        }

改めてありがとうございました。

3
11
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
11